OSDN Git Service

Thu Apr 20 17:41:28 2000 Mo DeJong <mdejong@cygnus.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 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 "defaults.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 ((int, 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 static void parse_ctor_invocation_error PARAMS ((void));
97 static tree parse_jdk1_1_error PARAMS ((const char *));
98 static void complete_class_report_errors PARAMS ((jdep *));
99 static int process_imports PARAMS ((void));
100 static void read_import_dir PARAMS ((tree));
101 static int find_in_imports_on_demand PARAMS ((tree));
102 static int find_in_imports PARAMS ((tree));
103 static int check_pkg_class_access PARAMS ((tree, tree));
104 static tree resolve_package PARAMS ((tree, tree *));
105 static tree lookup_package_type PARAMS ((const char *, int));
106 static tree lookup_package_type_and_set_next PARAMS ((const char *, int, tree *));
107 static tree resolve_class PARAMS ((tree, tree, tree, tree));
108 static void declare_local_variables PARAMS ((int, tree, tree));
109 static void source_start_java_method PARAMS ((tree));
110 static void source_end_java_method PARAMS ((void));
111 static void expand_start_java_method PARAMS ((tree));
112 static tree find_name_in_single_imports PARAMS ((tree));
113 static void check_abstract_method_header PARAMS ((tree));
114 static tree lookup_java_interface_method2 PARAMS ((tree, tree));
115 static tree resolve_expression_name PARAMS ((tree, tree *));
116 static tree maybe_create_class_interface_decl PARAMS ((tree, tree, tree, tree));
117 static int check_class_interface_creation PARAMS ((int, int, tree, 
118                                                   tree, tree, tree));
119 static tree patch_method_invocation PARAMS ((tree, tree, tree, 
120                                             int *, tree *));
121 static int breakdown_qualified PARAMS ((tree *, tree *, tree));
122 static tree resolve_and_layout PARAMS ((tree, tree));
123 static tree resolve_no_layout PARAMS ((tree, tree));
124 static int invocation_mode PARAMS ((tree, int));
125 static tree find_applicable_accessible_methods_list PARAMS ((int, tree, 
126                                                             tree, tree));
127 static void search_applicable_methods_list PARAMS ((int, tree, tree, tree, 
128                                                    tree *, tree *));
129 static tree find_most_specific_methods_list PARAMS ((tree));
130 static int argument_types_convertible PARAMS ((tree, tree));
131 static tree patch_invoke PARAMS ((tree, tree, tree));
132 static int maybe_use_access_method PARAMS ((int, tree *, tree *));
133 static tree lookup_method_invoke PARAMS ((int, tree, tree, tree, tree));
134 static tree register_incomplete_type PARAMS ((int, tree, tree, tree));
135 static tree obtain_incomplete_type PARAMS ((tree));
136 static tree java_complete_lhs PARAMS ((tree));
137 static tree java_complete_tree PARAMS ((tree));
138 static tree maybe_generate_pre_expand_clinit PARAMS ((tree));
139 static void java_complete_expand_method PARAMS ((tree));
140 static int  unresolved_type_p PARAMS ((tree, tree *));
141 static void create_jdep_list PARAMS ((struct parser_ctxt *));
142 static tree build_expr_block PARAMS ((tree, tree));
143 static tree enter_block PARAMS ((void));
144 static tree enter_a_block PARAMS ((tree));
145 static tree exit_block PARAMS ((void));
146 static tree lookup_name_in_blocks PARAMS ((tree));
147 static void maybe_absorb_scoping_blocks PARAMS ((void));
148 static tree build_method_invocation PARAMS ((tree, tree));
149 static tree build_new_invocation PARAMS ((tree, tree));
150 static tree build_assignment PARAMS ((int, int, tree, tree));
151 static tree build_binop PARAMS ((enum tree_code, int, tree, tree));
152 static int check_final_assignment PARAMS ((tree ,tree));
153 static tree patch_assignment PARAMS ((tree, tree, tree ));
154 static tree patch_binop PARAMS ((tree, tree, tree));
155 static tree build_unaryop PARAMS ((int, int, tree));
156 static tree build_incdec PARAMS ((int, int, tree, int));
157 static tree patch_unaryop PARAMS ((tree, tree));
158 static tree build_cast PARAMS ((int, tree, tree));
159 static tree build_null_of_type PARAMS ((tree));
160 static tree patch_cast PARAMS ((tree, tree));
161 static int valid_ref_assignconv_cast_p PARAMS ((tree, tree, int));
162 static int valid_builtin_assignconv_identity_widening_p PARAMS ((tree, tree));
163 static int valid_cast_to_p PARAMS ((tree, tree));
164 static int valid_method_invocation_conversion_p PARAMS ((tree, tree));
165 static tree try_builtin_assignconv PARAMS ((tree, tree, tree));
166 static tree try_reference_assignconv PARAMS ((tree, tree));
167 static tree build_unresolved_array_type PARAMS ((tree));
168 static tree build_array_from_name PARAMS ((tree, tree, tree, tree *));
169 static tree build_array_ref PARAMS ((int, tree, tree));
170 static tree patch_array_ref PARAMS ((tree));
171 static tree make_qualified_name PARAMS ((tree, tree, int));
172 static tree merge_qualified_name PARAMS ((tree, tree));
173 static tree make_qualified_primary PARAMS ((tree, tree, int));
174 static int resolve_qualified_expression_name PARAMS ((tree, tree *, 
175                                                      tree *, tree *));
176 static void qualify_ambiguous_name PARAMS ((tree));
177 static tree resolve_field_access PARAMS ((tree, tree *, tree *));
178 static tree build_newarray_node PARAMS ((tree, tree, int));
179 static tree patch_newarray PARAMS ((tree));
180 static tree resolve_type_during_patch PARAMS ((tree));
181 static tree build_this PARAMS ((int));
182 static tree build_wfl_wrap PARAMS ((tree));
183 static tree build_return PARAMS ((int, tree));
184 static tree patch_return PARAMS ((tree));
185 static tree maybe_access_field PARAMS ((tree, tree, tree));
186 static int complete_function_arguments PARAMS ((tree));
187 static int check_for_static_method_reference PARAMS ((tree, tree, tree, 
188                                                       tree, tree));
189 static int not_accessible_p PARAMS ((tree, tree, int));
190 static void check_deprecation PARAMS ((tree, tree));
191 static int class_in_current_package PARAMS ((tree));
192 static tree build_if_else_statement PARAMS ((int, tree, tree, tree));
193 static tree patch_if_else_statement PARAMS ((tree));
194 static tree add_stmt_to_compound PARAMS ((tree, tree, tree));
195 static tree add_stmt_to_block PARAMS ((tree, tree, tree));
196 static tree patch_exit_expr PARAMS ((tree));
197 static tree build_labeled_block PARAMS ((int, tree));
198 static tree finish_labeled_statement PARAMS ((tree, tree));
199 static tree build_bc_statement PARAMS ((int, int, tree));
200 static tree patch_bc_statement PARAMS ((tree));
201 static tree patch_loop_statement PARAMS ((tree));
202 static tree build_new_loop PARAMS ((tree));
203 static tree build_loop_body PARAMS ((int, tree, int));
204 static tree finish_loop_body PARAMS ((int, tree, tree, int));
205 static tree build_debugable_stmt PARAMS ((int, tree));
206 static tree finish_for_loop PARAMS ((int, tree, tree, tree));
207 static tree patch_switch_statement PARAMS ((tree));
208 static tree string_constant_concatenation PARAMS ((tree, tree));
209 static tree build_string_concatenation PARAMS ((tree, tree));
210 static tree patch_string_cst PARAMS ((tree));
211 static tree patch_string PARAMS ((tree));
212 static tree build_try_statement PARAMS ((int, tree, tree));
213 static tree build_try_finally_statement PARAMS ((int, tree, tree));
214 static tree patch_try_statement PARAMS ((tree));
215 static tree patch_synchronized_statement PARAMS ((tree, tree));
216 static tree patch_throw_statement PARAMS ((tree, tree));
217 static void check_thrown_exceptions PARAMS ((int, tree));
218 static int check_thrown_exceptions_do PARAMS ((tree));
219 static void purge_unchecked_exceptions PARAMS ((tree));
220 static void check_throws_clauses PARAMS ((tree, tree, tree));
221 static void finish_method_declaration PARAMS ((tree));
222 static tree build_super_invocation PARAMS ((tree));
223 static int verify_constructor_circularity PARAMS ((tree, tree));
224 static char *constructor_circularity_msg PARAMS ((tree, tree));
225 static tree build_this_super_qualified_invocation PARAMS ((int, tree, tree,
226                                                           int, int));
227 static const char *get_printable_method_name PARAMS ((tree));
228 static tree patch_conditional_expr PARAMS ((tree, tree, tree));
229 static tree generate_finit PARAMS ((tree));
230 static void add_instance_initializer PARAMS ((tree));
231 static void fix_constructors PARAMS ((tree));
232 static tree build_alias_initializer_parameter_list PARAMS ((int, tree,
233                                                             tree, int *));
234 static void craft_constructor PARAMS ((tree, tree));
235 static int verify_constructor_super PARAMS ((tree));
236 static tree create_artificial_method PARAMS ((tree, int, tree, tree, tree));
237 static void start_artificial_method_body PARAMS ((tree));
238 static void end_artificial_method_body PARAMS ((tree));
239 static int check_method_redefinition PARAMS ((tree, tree));
240 static int reset_method_name PARAMS ((tree));
241 static int check_method_types_complete PARAMS ((tree));
242 static void java_check_regular_methods PARAMS ((tree));
243 static void java_check_abstract_methods PARAMS ((tree));
244 static tree maybe_build_primttype_type_ref PARAMS ((tree, tree));
245 static void unreachable_stmt_error PARAMS ((tree));
246 static tree find_expr_with_wfl PARAMS ((tree));
247 static void missing_return_error PARAMS ((tree));
248 static tree build_new_array_init PARAMS ((int, tree));
249 static tree patch_new_array_init PARAMS ((tree, tree));
250 static tree maybe_build_array_element_wfl PARAMS ((tree));
251 static int array_constructor_check_entry PARAMS ((tree, tree));
252 static const char *purify_type_name PARAMS ((const char *));
253 static tree fold_constant_for_init PARAMS ((tree, tree));
254 static tree strip_out_static_field_access_decl PARAMS ((tree));
255 static jdeplist *reverse_jdep_list PARAMS ((struct parser_ctxt *));
256 static void static_ref_err PARAMS ((tree, tree, tree));
257 static void parser_add_interface PARAMS ((tree, tree, tree));
258 static void add_superinterfaces PARAMS ((tree, tree));
259 static tree jdep_resolve_class PARAMS ((jdep *));
260 static int note_possible_classname PARAMS ((const char *, int));
261 static void java_complete_expand_classes PARAMS ((void));
262 static void java_complete_expand_class PARAMS ((tree));
263 static void java_complete_expand_methods PARAMS ((tree));
264 static tree cut_identifier_in_qualified PARAMS ((tree));
265 static tree java_stabilize_reference PARAMS ((tree));
266 static tree do_unary_numeric_promotion PARAMS ((tree));
267 static char * operator_string PARAMS ((tree));
268 static tree do_merge_string_cste PARAMS ((tree, const char *, int, int));
269 static tree merge_string_cste PARAMS ((tree, tree, int));
270 static tree java_refold PARAMS ((tree));
271 static int java_decl_equiv PARAMS ((tree, tree));
272 static int binop_compound_p PARAMS ((enum tree_code));
273 static tree search_loop PARAMS ((tree));
274 static int labeled_block_contains_loop_p PARAMS ((tree, tree));
275 static void check_abstract_method_definitions PARAMS ((int, tree, tree));
276 static void java_check_abstract_method_definitions PARAMS ((tree));
277 static void java_debug_context_do PARAMS ((int));
278 static void java_parser_context_push_initialized_field PARAMS ((void));
279 static void java_parser_context_pop_initialized_field PARAMS ((void));
280 static tree reorder_static_initialized PARAMS ((tree));
281 static void java_parser_context_suspend PARAMS ((void));
282 static void java_parser_context_resume PARAMS ((void));
283
284 /* JDK 1.1 work. FIXME */
285
286 static tree maybe_make_nested_class_name PARAMS ((tree));
287 static void make_nested_class_name PARAMS ((tree));
288 static void set_nested_class_simple_name_value PARAMS ((tree, int));
289 static void link_nested_class_to_enclosing PARAMS ((void));
290 static tree find_as_inner_class PARAMS ((tree, tree, tree));
291 static tree find_as_inner_class_do PARAMS ((tree, tree));
292 static int check_inner_class_redefinition PARAMS ((tree, tree));
293
294 static tree build_thisn_assign PARAMS ((void));
295 static tree build_current_thisn PARAMS ((tree));
296 static tree build_access_to_thisn PARAMS ((tree, tree, int));
297 static tree maybe_build_thisn_access_method PARAMS ((tree));
298
299 static tree build_outer_field_access PARAMS ((tree, tree));
300 static tree build_outer_field_access_methods PARAMS ((tree));
301 static tree build_outer_field_access_expr PARAMS ((int, tree, tree, 
302                                                   tree, tree));
303 static tree build_outer_method_access_method PARAMS ((tree));
304 static tree build_new_access_id PARAMS ((void));
305 static tree build_outer_field_access_method PARAMS ((tree, tree, tree,
306                                                     tree, tree));
307
308 static int outer_field_access_p PARAMS ((tree, tree));
309 static int outer_field_expanded_access_p PARAMS ((tree, tree *, 
310                                                  tree *, tree *));
311 static tree outer_field_access_fix PARAMS ((tree, tree, tree));
312 static tree build_incomplete_class_ref PARAMS ((int, tree));
313 static tree patch_incomplete_class_ref PARAMS ((tree));
314 static tree create_anonymous_class PARAMS ((int, tree));
315 static void patch_anonymous_class PARAMS ((tree, tree, tree));
316 static void add_inner_class_fields PARAMS ((tree, tree));
317
318 static tree build_dot_class_method PARAMS ((tree));
319 static tree build_dot_class_method_invocation PARAMS ((tree));
320 static void create_new_parser_context PARAMS ((int));
321
322 /* Number of error found so far. */
323 int java_error_count; 
324 /* Number of warning found so far. */
325 int java_warning_count;
326 /* Tell when not to fold, when doing xrefs */
327 int do_not_fold;
328 /* Cyclic inheritance report, as it can be set by layout_class */
329 char *cyclic_inheritance_report;
330
331 /* Tell when we're within an instance initializer */
332 static int in_instance_initializer;
333
334 /* The current parser context */
335 struct parser_ctxt *ctxp;
336
337 /* List of things that were analyzed for which code will be generated */
338 static struct parser_ctxt *ctxp_for_generation = NULL;
339
340 /* binop_lookup maps token to tree_code. It is used where binary
341    operations are involved and required by the parser. RDIV_EXPR
342    covers both integral/floating point division. The code is changed
343    once the type of both operator is worked out.  */
344
345 static enum tree_code binop_lookup[19] = 
346   { 
347     PLUS_EXPR, MINUS_EXPR, MULT_EXPR, RDIV_EXPR, TRUNC_MOD_EXPR,
348     LSHIFT_EXPR, RSHIFT_EXPR, URSHIFT_EXPR, 
349     BIT_AND_EXPR, BIT_XOR_EXPR, BIT_IOR_EXPR,
350     TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR,
351     EQ_EXPR, NE_EXPR, GT_EXPR, GE_EXPR, LT_EXPR, LE_EXPR,
352    };
353 #define BINOP_LOOKUP(VALUE)                                             \
354   binop_lookup [((VALUE) - PLUS_TK)%                                    \
355                 (sizeof (binop_lookup) / sizeof (binop_lookup[0]))]
356
357 /* This is the end index for binary operators that can also be used
358    in compound assignements. */
359 #define BINOP_COMPOUND_CANDIDATES 11
360
361 /* Fake WFL used to report error message. It is initialized once if
362    needed and reused with it's location information is overriden.  */
363 tree wfl_operator = NULL_TREE;
364
365 /* The "$L" identifier we use to create labels.  */
366 static tree label_id = NULL_TREE;
367
368 /* The "StringBuffer" identifier used for the String `+' operator. */
369 static tree wfl_string_buffer = NULL_TREE; 
370
371 /* The "append" identifier used for String `+' operator.  */
372 static tree wfl_append = NULL_TREE;
373
374 /* The "toString" identifier used for String `+' operator. */
375 static tree wfl_to_string = NULL_TREE;
376
377 /* The "java.lang" import qualified name.  */
378 static tree java_lang_id = NULL_TREE;
379
380 /* The generated `inst$' identifier used for generated enclosing
381    instance/field access functions.  */
382 static tree inst_id = NULL_TREE;
383
384 /* The "java.lang.Cloneable" qualified name.  */
385 static tree java_lang_cloneable = NULL_TREE;
386
387 /* Context and flag for static blocks */
388 static tree current_static_block = NULL_TREE;
389
390 /* The generated `write_parm_value$' identifier.  */
391 static tree wpv_id;
392
393 /* The list of all packages we've seen so far */
394 static tree package_list = NULL_TREE;
395  
396 /* Check modifiers. If one doesn't fit, retrieve it in its declaration
397    line and point it out.  */
398 /* Should point out the one that don't fit. ASCII/unicode, going
399    backward. FIXME */
400
401 #define check_modifiers(__message, __value, __mask) do {        \
402   if ((__value) & ~(__mask))                                    \
403     {                                                           \
404       int i, remainder = (__value) & ~(__mask);                 \
405       for (i = 0; i <= 10; i++)                                 \
406         if ((1 << i) & remainder)                               \
407           parse_error_context (ctxp->modifier_ctx [i], (__message), \
408                                java_accstring_lookup (1 << i)); \
409     }                                                           \
410 } while (0)
411
412 %}
413
414 %union {
415   tree node;
416   int sub_token;
417   struct {
418     int token;
419     int location;
420   } operator;
421   int value;
422 }
423
424 %{
425 #include "lex.c"
426 %}
427
428 %pure_parser
429
430 /* Things defined here have to match the order of what's in the
431    binop_lookup table.  */
432
433 %token   PLUS_TK         MINUS_TK        MULT_TK         DIV_TK    REM_TK
434 %token   LS_TK           SRS_TK          ZRS_TK
435 %token   AND_TK          XOR_TK          OR_TK
436 %token   BOOL_AND_TK BOOL_OR_TK 
437 %token   EQ_TK NEQ_TK GT_TK GTE_TK LT_TK LTE_TK
438
439 /* This maps to the same binop_lookup entry than the token above */
440
441 %token   PLUS_ASSIGN_TK  MINUS_ASSIGN_TK MULT_ASSIGN_TK DIV_ASSIGN_TK
442 %token   REM_ASSIGN_TK   
443 %token   LS_ASSIGN_TK    SRS_ASSIGN_TK   ZRS_ASSIGN_TK
444 %token   AND_ASSIGN_TK   XOR_ASSIGN_TK   OR_ASSIGN_TK
445
446
447 /* Modifier TOKEN have to be kept in this order. Don't scramble it */
448
449 %token   PUBLIC_TK       PRIVATE_TK         PROTECTED_TK
450 %token   STATIC_TK       FINAL_TK           SYNCHRONIZED_TK
451 %token   VOLATILE_TK     TRANSIENT_TK       NATIVE_TK
452 %token   PAD_TK          ABSTRACT_TK        MODIFIER_TK
453
454 /* Keep those two in order, too */
455 %token   DECR_TK INCR_TK
456
457 /* From now one, things can be in any order */
458
459 %token   DEFAULT_TK      IF_TK              THROW_TK
460 %token   BOOLEAN_TK      DO_TK              IMPLEMENTS_TK
461 %token   THROWS_TK       BREAK_TK           IMPORT_TK       
462 %token   ELSE_TK         INSTANCEOF_TK      RETURN_TK
463 %token   VOID_TK         CATCH_TK           INTERFACE_TK
464 %token   CASE_TK         EXTENDS_TK         FINALLY_TK
465 %token   SUPER_TK        WHILE_TK           CLASS_TK
466 %token   SWITCH_TK       CONST_TK           TRY_TK
467 %token   FOR_TK          NEW_TK             CONTINUE_TK
468 %token   GOTO_TK         PACKAGE_TK         THIS_TK
469
470 %token   BYTE_TK         SHORT_TK           INT_TK            LONG_TK
471 %token   CHAR_TK         INTEGRAL_TK
472
473 %token   FLOAT_TK        DOUBLE_TK          FP_TK
474
475 %token   ID_TK
476
477 %token   REL_QM_TK         REL_CL_TK NOT_TK  NEG_TK
478
479 %token   ASSIGN_ANY_TK   ASSIGN_TK
480 %token   OP_TK  CP_TK  OCB_TK  CCB_TK  OSB_TK  CSB_TK  SC_TK  C_TK DOT_TK
481
482 %token   STRING_LIT_TK   CHAR_LIT_TK        INT_LIT_TK        FP_LIT_TK
483 %token   TRUE_TK         FALSE_TK           BOOL_LIT_TK       NULL_TK
484
485 %type    <value>        modifiers MODIFIER_TK final synchronized
486
487 %type    <node>         super ID_TK identifier
488 %type    <node>         name simple_name qualified_name
489 %type    <node>         type_declaration compilation_unit
490                         field_declaration method_declaration extends_interfaces
491                         interfaces interface_type_list
492                         class_member_declaration
493                         import_declarations package_declaration 
494                         type_declarations interface_body
495                         interface_member_declaration constant_declaration
496                         interface_member_declarations interface_type
497                         abstract_method_declaration interface_type_list
498 %type    <node>         class_body_declaration class_member_declaration
499                         static_initializer constructor_declaration block
500 %type    <node>         class_body_declarations constructor_header
501 %type    <node>         class_or_interface_type class_type class_type_list
502                         constructor_declarator explicit_constructor_invocation
503 %type    <node>         dim_expr dim_exprs this_or_super throws
504
505 %type    <node>         variable_declarator_id variable_declarator
506                         variable_declarators variable_initializer
507                         variable_initializers constructor_body
508                         array_initializer
509
510 %type    <node>         class_body block_end constructor_block_end
511 %type    <node>         statement statement_without_trailing_substatement
512                         labeled_statement if_then_statement label_decl
513                         if_then_else_statement while_statement for_statement
514                         statement_nsi labeled_statement_nsi do_statement
515                         if_then_else_statement_nsi while_statement_nsi
516                         for_statement_nsi statement_expression_list for_init
517                         for_update statement_expression expression_statement
518                         primary_no_new_array expression primary
519                         array_creation_expression array_type
520                         class_instance_creation_expression field_access
521                         method_invocation array_access something_dot_new
522                         argument_list postfix_expression while_expression 
523                         post_increment_expression post_decrement_expression
524                         unary_expression_not_plus_minus unary_expression
525                         pre_increment_expression pre_decrement_expression
526                         unary_expression_not_plus_minus cast_expression
527                         multiplicative_expression additive_expression
528                         shift_expression relational_expression 
529                         equality_expression and_expression 
530                         exclusive_or_expression inclusive_or_expression
531                         conditional_and_expression conditional_or_expression
532                         conditional_expression assignment_expression
533                         left_hand_side assignment for_header for_begin
534                         constant_expression do_statement_begin empty_statement
535                         switch_statement synchronized_statement throw_statement
536                         try_statement switch_expression switch_block
537                         catches catch_clause catch_clause_parameter finally
538                         anonymous_class_creation
539 %type    <node>         return_statement break_statement continue_statement
540
541 %type    <operator>     ASSIGN_TK      MULT_ASSIGN_TK  DIV_ASSIGN_TK  
542 %type    <operator>     REM_ASSIGN_TK  PLUS_ASSIGN_TK  MINUS_ASSIGN_TK
543 %type    <operator>     LS_ASSIGN_TK   SRS_ASSIGN_TK   ZRS_ASSIGN_TK
544 %type    <operator>     AND_ASSIGN_TK  XOR_ASSIGN_TK   OR_ASSIGN_TK
545 %type    <operator>     ASSIGN_ANY_TK  assignment_operator
546 %token   <operator>     EQ_TK GTE_TK ZRS_TK SRS_TK GT_TK LTE_TK LS_TK 
547 %token   <operator>     BOOL_AND_TK AND_TK BOOL_OR_TK OR_TK INCR_TK PLUS_TK
548 %token   <operator>     DECR_TK MINUS_TK MULT_TK DIV_TK XOR_TK REM_TK NEQ_TK
549 %token   <operator>     NEG_TK REL_QM_TK REL_CL_TK NOT_TK LT_TK OCB_TK CCB_TK
550 %token   <operator>     OP_TK OSB_TK DOT_TK THROW_TK INSTANCEOF_TK
551 %type    <operator>     THIS_TK SUPER_TK RETURN_TK BREAK_TK CONTINUE_TK 
552 %type    <operator>     CASE_TK DEFAULT_TK TRY_TK CATCH_TK SYNCHRONIZED_TK
553 %type    <operator>     NEW_TK
554
555 %type    <node>         method_body 
556         
557 %type    <node>         literal INT_LIT_TK FP_LIT_TK BOOL_LIT_TK CHAR_LIT_TK
558                         STRING_LIT_TK NULL_TK VOID_TK
559
560 %type    <node>         IF_TK WHILE_TK FOR_TK
561
562 %type    <node>         formal_parameter_list formal_parameter
563                         method_declarator method_header
564
565 %type    <node>         primitive_type reference_type type 
566                         BOOLEAN_TK INTEGRAL_TK FP_TK
567
568 /* Added or modified JDK 1.1 rule types  */
569 %type    <node>         type_literals array_type_literal
570
571 %%
572 /* 19.2 Production from 2.3: The Syntactic Grammar  */
573 goal:
574         compilation_unit
575                 {}
576 ;
577
578 /* 19.3 Productions from 3: Lexical structure  */
579 literal:
580         INT_LIT_TK
581 |       FP_LIT_TK
582 |       BOOL_LIT_TK
583 |       CHAR_LIT_TK
584 |       STRING_LIT_TK
585 |       NULL_TK
586 ;
587
588 /* 19.4 Productions from 4: Types, Values and Variables  */
589 type:
590         primitive_type
591 |       reference_type
592 ;
593
594 primitive_type:
595         INTEGRAL_TK
596 |       FP_TK
597 |       BOOLEAN_TK
598 ;
599
600 reference_type:
601         class_or_interface_type
602 |       array_type
603 ;
604
605 class_or_interface_type:
606         name
607 ;
608
609 class_type:
610         class_or_interface_type /* Default rule */
611 ;
612
613 interface_type:
614          class_or_interface_type
615 ;
616
617 array_type:
618         primitive_type OSB_TK CSB_TK
619                 { 
620                   $$ = build_java_array_type ($1, -1);
621                   CLASS_LOADED_P ($$) = 1;
622                 }
623 |       name OSB_TK CSB_TK
624                 { $$ = build_unresolved_array_type ($1); }
625 |       array_type OSB_TK CSB_TK
626                 { $$ = build_unresolved_array_type ($1); }
627 |       primitive_type OSB_TK error
628                 {RULE ("']' expected"); RECOVER;}
629 |       array_type OSB_TK error
630                 {RULE ("']' expected"); RECOVER;}
631 ;
632
633 /* 19.5 Productions from 6: Names  */
634 name:
635         simple_name             /* Default rule */
636 |       qualified_name          /* Default rule */
637 ;
638
639 simple_name:
640         identifier              /* Default rule */
641 ;
642
643 qualified_name:
644         name DOT_TK identifier
645                 { $$ = make_qualified_name ($1, $3, $2.location); }
646 ;
647
648 identifier:
649         ID_TK
650 ;
651
652 /* 19.6: Production from 7: Packages  */
653 compilation_unit:
654                 {$$ = NULL;}
655 |       package_declaration
656 |       import_declarations
657 |       type_declarations
658 |       package_declaration import_declarations
659 |       package_declaration type_declarations
660 |       import_declarations type_declarations
661 |       package_declaration import_declarations type_declarations
662 ;
663
664 import_declarations:
665         import_declaration
666                 {
667                   $$ = NULL;
668                 }
669 |       import_declarations import_declaration
670                 {
671                   $$ = NULL;
672                 }
673 ;
674
675 type_declarations:
676         type_declaration
677 |       type_declarations type_declaration
678 ;
679
680 package_declaration:
681         PACKAGE_TK name SC_TK
682                 { 
683                   ctxp->package = EXPR_WFL_NODE ($2);
684                   package_list = tree_cons (ctxp->package, NULL, package_list);
685                 }
686 |       PACKAGE_TK error
687                 {yyerror ("Missing name"); RECOVER;}
688 |       PACKAGE_TK name error
689                 {yyerror ("';' expected"); RECOVER;}
690 ;
691
692 import_declaration:
693         single_type_import_declaration
694 |       type_import_on_demand_declaration
695 ;
696
697 single_type_import_declaration:
698         IMPORT_TK name SC_TK
699                 {
700                   tree name = EXPR_WFL_NODE ($2), node, last_name;
701                   int   i = IDENTIFIER_LENGTH (name)-1;
702                   const char *last = &IDENTIFIER_POINTER (name)[i];
703                   while (last != IDENTIFIER_POINTER (name))
704                     {
705                       if (last [0] == '.')
706                         break;
707                       last--;
708                     }
709                   last_name = get_identifier (++last);
710                   if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (last_name))
711                     {
712                       tree err = find_name_in_single_imports (last_name);
713                       if (err && err != name)
714                         parse_error_context
715                           ($2, "Ambiguous class: `%s' and `%s'",
716                            IDENTIFIER_POINTER (name), 
717                            IDENTIFIER_POINTER (err));
718                       else
719                         REGISTER_IMPORT ($2, last_name)
720                     }
721                   else
722                     REGISTER_IMPORT ($2, last_name);
723                 }
724 |       IMPORT_TK error
725                 {yyerror ("Missing name"); RECOVER;}
726 |       IMPORT_TK name error
727                 {yyerror ("';' expected"); RECOVER;}
728 ;
729
730 type_import_on_demand_declaration:
731         IMPORT_TK name DOT_TK MULT_TK SC_TK
732                 {
733                   tree name = EXPR_WFL_NODE ($2);
734                   /* Don't import java.lang.* twice. */
735                   if (name != java_lang_id)
736                     {
737                       tree node = build_tree_list ($2, NULL_TREE);
738                       read_import_dir ($2);
739                       TREE_CHAIN (node) = ctxp->import_demand_list;
740                       ctxp->import_demand_list = node;
741                     }
742                 }
743 |       IMPORT_TK name DOT_TK error
744                 {yyerror ("'*' expected"); RECOVER;}
745 |       IMPORT_TK name DOT_TK MULT_TK error
746                 {yyerror ("';' expected"); RECOVER;}
747 ;
748
749 type_declaration:
750         class_declaration
751                 { end_class_declaration (0); }
752 |       interface_declaration
753                 { end_class_declaration (0); }
754 |       SC_TK
755                 { $$ = NULL; }
756 |       error
757                 {
758                   YYERROR_NOW;
759                   yyerror ("Class or interface declaration expected");
760                 }
761 ;
762
763 /* 19.7 Shortened from the original:
764    modifiers: modifier | modifiers modifier
765    modifier: any of public...  */
766 modifiers:
767         MODIFIER_TK
768                 {
769                   $$ = (1 << $1);
770                 }
771 |       modifiers MODIFIER_TK
772                 {
773                   int acc = (1 << $2);
774                   if ($$ & acc)
775                     parse_error_context 
776                       (ctxp->modifier_ctx [$2], "Modifier `%s' declared twice",
777                        java_accstring_lookup (acc));
778                   else
779                     {
780                       $$ |= acc;
781                     }
782                 }
783 ;
784
785 /* 19.8.1 Production from $8.1: Class Declaration */
786 class_declaration:
787         modifiers CLASS_TK identifier super interfaces
788                 { create_class ($1, $3, $4, $5); }
789         class_body
790 |       CLASS_TK identifier super interfaces 
791                 { create_class (0, $2, $3, $4); }
792         class_body
793 |       modifiers CLASS_TK error
794                 {yyerror ("Missing class name"); RECOVER;}
795 |       CLASS_TK error
796                 {yyerror ("Missing class name"); RECOVER;}
797 |       CLASS_TK identifier error
798                 {
799                   if (!ctxp->class_err) yyerror ("'{' expected"); 
800                   DRECOVER(class1);
801                 }
802 |       modifiers CLASS_TK identifier error
803                 {if (!ctxp->class_err) yyerror ("'{' expected"); RECOVER;}
804 ;
805
806 super:
807                 { $$ = NULL; }
808 |       EXTENDS_TK class_type
809                 { $$ = $2; }
810 |       EXTENDS_TK class_type error
811                 {yyerror ("'{' expected"); ctxp->class_err=1;}
812 |       EXTENDS_TK error
813                 {yyerror ("Missing super class name"); ctxp->class_err=1;}
814 ;
815
816 interfaces:
817                 { $$ = NULL_TREE; }
818 |       IMPLEMENTS_TK interface_type_list
819                 { $$ = $2; }
820 |       IMPLEMENTS_TK error
821                 {
822                   ctxp->class_err=1;
823                   yyerror ("Missing interface name"); 
824                 }
825 ;
826
827 interface_type_list:
828         interface_type
829                 { 
830                   ctxp->interface_number = 1;
831                   $$ = build_tree_list ($1, NULL_TREE);
832                 }
833 |       interface_type_list C_TK interface_type
834                 { 
835                   ctxp->interface_number++;
836                   $$ = chainon ($1, build_tree_list ($3, NULL_TREE));
837                 }
838 |       interface_type_list C_TK error
839                 {yyerror ("Missing interface name"); RECOVER;}
840 ;
841
842 class_body:
843         OCB_TK CCB_TK
844                 { 
845                   /* Store the location of the `}' when doing xrefs */
846                   if (flag_emit_xref)
847                     DECL_END_SOURCE_LINE (GET_CPC ()) = 
848                       EXPR_WFL_ADD_COL ($2.location, 1);
849                   $$ = GET_CPC ();
850                 }
851 |       OCB_TK class_body_declarations CCB_TK
852                 { 
853                   /* Store the location of the `}' when doing xrefs */
854                   if (flag_emit_xref)
855                     DECL_END_SOURCE_LINE (GET_CPC ()) = 
856                       EXPR_WFL_ADD_COL ($3.location, 1);
857                   $$ = GET_CPC ();
858                 }
859 ;
860
861 class_body_declarations:
862         class_body_declaration
863 |       class_body_declarations class_body_declaration
864 ;
865
866 class_body_declaration:
867         class_member_declaration
868 |       static_initializer
869 |       constructor_declaration
870 |       block                   /* Added, JDK1.1, instance initializer */
871                 {
872                   TREE_CHAIN ($1) = CPC_INSTANCE_INITIALIZER_STMT (ctxp);
873                   SET_CPC_INSTANCE_INITIALIZER_STMT (ctxp, $1);
874                 }
875 ;
876
877 class_member_declaration:
878         field_declaration
879 |       field_declaration SC_TK
880                 { $$ = $1; }
881 |       method_declaration
882 |       class_declaration       /* Added, JDK1.1 inner classes */
883                 { end_class_declaration (1); }
884 |       interface_declaration   /* Added, JDK1.1 inner interfaces */
885                 { end_class_declaration (1); }
886 ;
887
888 /* 19.8.2 Productions from 8.3: Field Declarations  */
889 field_declaration:
890         type variable_declarators SC_TK
891                 { register_fields (0, $1, $2); }
892 |       modifiers type variable_declarators SC_TK
893                 {
894                   check_modifiers 
895                     ("Illegal modifier `%s' for field declaration",
896                      $1, FIELD_MODIFIERS);
897                   check_modifiers_consistency ($1);
898                   register_fields ($1, $2, $3);
899                 }
900 ;
901
902 variable_declarators:
903         /* Should we use build_decl_list () instead ? FIXME */
904         variable_declarator     /* Default rule */
905 |       variable_declarators C_TK variable_declarator
906                 { $$ = chainon ($1, $3); }
907 |       variable_declarators C_TK error
908                 {yyerror ("Missing term"); RECOVER;}
909 ;
910
911 variable_declarator:
912         variable_declarator_id
913                 { $$ = build_tree_list ($1, NULL_TREE); }
914 |       variable_declarator_id ASSIGN_TK variable_initializer
915                 { 
916                   if (java_error_count)
917                     $3 = NULL_TREE;
918                   $$ = build_tree_list 
919                     ($1, build_assignment ($2.token, $2.location, $1, $3));
920                 }
921 |       variable_declarator_id ASSIGN_TK error
922                 {
923                   yyerror ("Missing variable initializer");
924                   $$ = build_tree_list ($1, NULL_TREE);
925                   RECOVER;
926                 }
927 |       variable_declarator_id ASSIGN_TK variable_initializer error
928                 {
929                   yyerror ("';' expected");
930                   $$ = build_tree_list ($1, NULL_TREE);
931                   RECOVER;
932                 }
933 ;
934
935 variable_declarator_id:
936         identifier
937 |       variable_declarator_id OSB_TK CSB_TK
938                 { $$ = build_unresolved_array_type ($1); }
939 |       identifier error
940                 {yyerror ("Invalid declaration"); DRECOVER(vdi);}
941 |       variable_declarator_id OSB_TK error
942                 {yyerror ("']' expected"); DRECOVER(vdi);}
943 |       variable_declarator_id CSB_TK error
944                 {yyerror ("Unbalanced ']'"); DRECOVER(vdi);}
945 ;
946
947 variable_initializer:
948         expression
949 |       array_initializer
950 ;
951
952 /* 19.8.3 Productions from 8.4: Method Declarations  */
953 method_declaration:
954         method_header 
955                 {
956                   current_function_decl = $1;
957                   if (current_function_decl
958                       && TREE_CODE (current_function_decl) == FUNCTION_DECL)
959                     source_start_java_method (current_function_decl);
960                   else
961                     current_function_decl = NULL_TREE;
962                 }
963         method_body
964                 { finish_method_declaration ($3); }
965 |       method_header error
966                 {YYNOT_TWICE yyerror ("'{' expected"); RECOVER;}
967 ;
968
969 method_header:  
970         type method_declarator throws
971                 { $$ = method_header (0, $1, $2, $3); }
972 |       VOID_TK method_declarator throws
973                 { $$ = method_header (0, void_type_node, $2, $3); }
974 |       modifiers type method_declarator throws
975                 { $$ = method_header ($1, $2, $3, $4); }
976 |       modifiers VOID_TK method_declarator throws
977                 { $$ = method_header ($1, void_type_node, $3, $4); }
978 |       type error
979                 {
980                   yyerror ("Invalid method declaration, method name required");
981                   RECOVER;
982                 }
983 |       modifiers type error
984                 {RECOVER;}
985 |       VOID_TK error
986                 {yyerror ("Identifier expected"); RECOVER;}
987 |       modifiers VOID_TK error
988                 {yyerror ("Identifier expected"); RECOVER;}
989 |       modifiers error
990                 {
991                   yyerror ("Invalid method declaration, return type required");
992                   RECOVER;
993                 }
994 ;
995
996 method_declarator:
997         identifier OP_TK CP_TK
998                 { 
999                   ctxp->formal_parameter_number = 0;
1000                   $$ = method_declarator ($1, NULL_TREE);
1001                 }
1002 |       identifier OP_TK formal_parameter_list CP_TK
1003                 { $$ = method_declarator ($1, $3); }
1004 |       method_declarator OSB_TK CSB_TK
1005                 {
1006                   EXPR_WFL_LINECOL (wfl_operator) = $2.location;
1007                   TREE_PURPOSE ($1) = 
1008                     build_unresolved_array_type (TREE_PURPOSE ($1));
1009                   parse_warning_context 
1010                     (wfl_operator, 
1011                      "Discouraged form of returned type specification");
1012                 }
1013 |       identifier OP_TK error
1014                 {yyerror ("')' expected"); DRECOVER(method_declarator);}
1015 |       method_declarator OSB_TK error
1016                 {yyerror ("']' expected"); RECOVER;}
1017 ;
1018
1019 formal_parameter_list:
1020         formal_parameter
1021                 {
1022                   ctxp->formal_parameter_number = 1;
1023                 }
1024 |       formal_parameter_list C_TK formal_parameter
1025                 {
1026                   ctxp->formal_parameter_number += 1;
1027                   $$ = chainon ($1, $3);
1028                 }
1029 |       formal_parameter_list C_TK error
1030                 { yyerror ("Missing formal parameter term"); RECOVER; }
1031 ;
1032
1033 formal_parameter:
1034         type variable_declarator_id
1035                 {
1036                   $$ = build_tree_list ($2, $1);
1037                 }
1038 |       final type variable_declarator_id /* Added, JDK1.1 final parms */
1039                 { 
1040                   $$ = build_tree_list ($3, $2);
1041                   ARG_FINAL_P ($$) = 1;
1042                 }
1043 |       type error
1044                 {
1045                   yyerror ("Missing identifier"); RECOVER;
1046                   $$ = NULL_TREE;
1047                 }
1048 |       final type error
1049                 {
1050                   yyerror ("Missing identifier"); RECOVER;
1051                   $$ = NULL_TREE;
1052                 }
1053 ;
1054
1055 final:
1056         modifiers
1057                 {
1058                   check_modifiers ("Illegal modifier `%s'. Only `final' was expected here",
1059                                    $1, ACC_FINAL);
1060                   if ($1 != ACC_FINAL)
1061                     MODIFIER_WFL (FINAL_TK) = build_wfl_node (NULL_TREE);
1062                 }
1063 ;
1064
1065 throws:
1066                 { $$ = NULL_TREE; }
1067 |       THROWS_TK class_type_list
1068                 { $$ = $2; }
1069 |       THROWS_TK error
1070                 {yyerror ("Missing class type term"); RECOVER;}
1071 ;
1072
1073 class_type_list:
1074         class_type
1075                 { $$ = build_tree_list ($1, $1); }
1076 |       class_type_list C_TK class_type
1077                 { $$ = tree_cons ($3, $3, $1); }
1078 |       class_type_list C_TK error
1079                 {yyerror ("Missing class type term"); RECOVER;}
1080 ;
1081
1082 method_body:
1083         block
1084 |       block SC_TK
1085 |       SC_TK
1086                 { $$ = NULL_TREE; } /* Probably not the right thing to do. */
1087 ;
1088
1089 /* 19.8.4 Productions from 8.5: Static Initializers  */
1090 static_initializer:
1091         static block
1092                 {
1093                   TREE_CHAIN ($2) = CPC_STATIC_INITIALIZER_STMT (ctxp);
1094                   SET_CPC_STATIC_INITIALIZER_STMT (ctxp, $2);
1095                 }
1096 |       static block SC_TK      /* Shouldn't be here. FIXME */
1097                 {
1098                   TREE_CHAIN ($2) = CPC_STATIC_INITIALIZER_STMT (ctxp);
1099                   SET_CPC_STATIC_INITIALIZER_STMT (ctxp, $2);
1100                 }
1101 ;
1102
1103 static:                         /* Test lval.sub_token here */
1104         modifiers
1105                 {
1106                   check_modifiers ("Illegal modifier `%s' for static initializer", $1, ACC_STATIC);
1107                   /* Can't have a static initializer in an innerclass */
1108                   if ($1 | ACC_STATIC &&
1109                       GET_CPC_LIST () && !TOPLEVEL_CLASS_DECL_P (GET_CPC ()))
1110                     parse_error_context 
1111                       (MODIFIER_WFL (STATIC_TK),
1112                        "Can't define static initializer in class `%s'. Static initializer can only be defined in top-level classes",
1113                        IDENTIFIER_POINTER (DECL_NAME (GET_CPC ())));
1114                   SOURCE_FRONTEND_DEBUG (("Modifiers: %d", $1));
1115                 }
1116 ;
1117
1118 /* 19.8.5 Productions from 8.6: Constructor Declarations  */
1119 constructor_declaration:
1120         constructor_header
1121                 {
1122                   current_function_decl = $1;
1123                   source_start_java_method (current_function_decl);
1124                 }
1125         constructor_body
1126                 { finish_method_declaration ($3); }
1127 ;
1128
1129 constructor_header:
1130         constructor_declarator throws
1131                 { $$ = method_header (0, NULL_TREE, $1, $2); }
1132 |       modifiers constructor_declarator throws
1133                 { $$ = method_header ($1, NULL_TREE, $2, $3); }
1134 ;
1135
1136 constructor_declarator:
1137         simple_name OP_TK CP_TK
1138                 { 
1139                   ctxp->formal_parameter_number = 0;  
1140                   $$ = method_declarator ($1, NULL_TREE);
1141                 }
1142 |       simple_name OP_TK formal_parameter_list CP_TK
1143                 { $$ = method_declarator ($1, $3); }
1144 ;
1145
1146 constructor_body:
1147         /* Unlike regular method, we always need a complete (empty)
1148            body so we can safely perform all the required code
1149            addition (super invocation and field initialization) */
1150         block_begin constructor_block_end
1151                 { 
1152                   BLOCK_EXPR_BODY ($2) = empty_stmt_node;
1153                   $$ = $2;
1154                 }
1155 |       block_begin explicit_constructor_invocation constructor_block_end
1156                 { $$ = $3; }
1157 |       block_begin block_statements constructor_block_end
1158                 { $$ = $3; }
1159 |       block_begin explicit_constructor_invocation block_statements constructor_block_end
1160                 { $$ = $4; }
1161 ;
1162
1163 constructor_block_end:
1164         block_end
1165 |       block_end SC_TK
1166
1167 /* Error recovery for that rule moved down expression_statement: rule.  */
1168 explicit_constructor_invocation:
1169         this_or_super OP_TK CP_TK SC_TK
1170                 { 
1171                   $$ = build_method_invocation ($1, NULL_TREE); 
1172                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $$);
1173                   $$ = java_method_add_stmt (current_function_decl, $$);
1174                 }
1175 |       this_or_super OP_TK argument_list CP_TK SC_TK
1176                 { 
1177                   $$ = build_method_invocation ($1, $3); 
1178                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $$);
1179                   $$ = java_method_add_stmt (current_function_decl, $$);
1180                 }
1181         /* Added, JDK1.1 inner classes. Modified because the rule
1182            'primary' couldn't work.  */
1183 |       name DOT_TK SUPER_TK OP_TK argument_list CP_TK SC_TK
1184                 {$$ = parse_jdk1_1_error ("explicit constructor invocation"); }
1185 |       name DOT_TK SUPER_TK OP_TK CP_TK SC_TK
1186                 {$$ = parse_jdk1_1_error ("explicit constructor invocation"); }
1187 ;
1188
1189 this_or_super:                  /* Added, simplifies error diagnostics */
1190         THIS_TK
1191                 {
1192                   tree wfl = build_wfl_node (this_identifier_node);
1193                   EXPR_WFL_LINECOL (wfl) = $1.location;
1194                   $$ = wfl;
1195                 }
1196 |       SUPER_TK
1197                 {
1198                   tree wfl = build_wfl_node (super_identifier_node);
1199                   EXPR_WFL_LINECOL (wfl) = $1.location;
1200                   $$ = wfl;
1201                 }
1202 ;
1203
1204 /* 19.9 Productions from 9: Interfaces  */
1205 /* 19.9.1 Productions from 9.1: Interfaces Declarations  */
1206 interface_declaration:
1207         INTERFACE_TK identifier
1208                 { create_interface (0, $2, NULL_TREE); }
1209         interface_body
1210 |       modifiers INTERFACE_TK identifier
1211                 { create_interface ($1, $3, NULL_TREE); }
1212         interface_body
1213 |       INTERFACE_TK identifier extends_interfaces
1214                 { create_interface (0, $2, $3); }
1215         interface_body
1216 |       modifiers INTERFACE_TK identifier extends_interfaces
1217                 { create_interface ($1, $3, $4); }
1218         interface_body
1219 |       INTERFACE_TK identifier error
1220                 {yyerror ("'{' expected"); RECOVER;}
1221 |       modifiers INTERFACE_TK identifier error
1222                 {yyerror ("'{' expected"); RECOVER;}
1223 ;
1224
1225 extends_interfaces:
1226         EXTENDS_TK interface_type
1227                 { 
1228                   ctxp->interface_number = 1;
1229                   $$ = build_tree_list ($2, NULL_TREE);
1230                 }
1231 |       extends_interfaces C_TK interface_type
1232                 { 
1233                   ctxp->interface_number++;
1234                   $$ = chainon ($1, build_tree_list ($3, NULL_TREE));
1235                 }
1236 |       EXTENDS_TK error
1237                 {yyerror ("Invalid interface type"); RECOVER;}
1238 |       extends_interfaces C_TK error
1239                 {yyerror ("Missing term"); RECOVER;}
1240 ;
1241
1242 interface_body:
1243         OCB_TK CCB_TK
1244                 { $$ = NULL_TREE; }
1245 |       OCB_TK interface_member_declarations CCB_TK
1246                 { $$ = NULL_TREE; }
1247 ;
1248
1249 interface_member_declarations:
1250         interface_member_declaration
1251 |       interface_member_declarations interface_member_declaration
1252 ;
1253
1254 interface_member_declaration:
1255         constant_declaration
1256 |       abstract_method_declaration
1257 |       class_declaration       /* Added, JDK1.1 inner classes */
1258                 { end_class_declaration (1); }
1259 |       interface_declaration   /* Added, JDK1.1 inner interfaces */
1260                 { end_class_declaration (1); }
1261 ;
1262
1263 constant_declaration:
1264         field_declaration
1265 ;
1266
1267 abstract_method_declaration:
1268         method_header SC_TK
1269                 { 
1270                   check_abstract_method_header ($1);
1271                   current_function_decl = NULL_TREE; /* FIXME ? */
1272                 }
1273 |       method_header error
1274                 {yyerror ("';' expected"); RECOVER;}
1275 ;
1276
1277 /* 19.10 Productions from 10: Arrays  */
1278 array_initializer:
1279         OCB_TK CCB_TK
1280                 { $$ = build_new_array_init ($1.location, NULL_TREE); }
1281 |       OCB_TK variable_initializers CCB_TK
1282                 { $$ = build_new_array_init ($1.location, $2); }
1283 |       OCB_TK variable_initializers C_TK CCB_TK
1284                 { $$ = build_new_array_init ($1.location, $2); }
1285 ;
1286
1287 variable_initializers:
1288         variable_initializer
1289                 { 
1290                   $$ = tree_cons (maybe_build_array_element_wfl ($1), 
1291                                   $1, NULL_TREE);
1292                 }
1293 |       variable_initializers C_TK variable_initializer
1294                 {
1295                   $$ = tree_cons (maybe_build_array_element_wfl ($3), $3, $1);
1296                 }
1297 |       variable_initializers C_TK error
1298                 {yyerror ("Missing term"); RECOVER;}
1299 ;
1300
1301 /* 19.11 Production from 14: Blocks and Statements  */
1302 block:
1303         OCB_TK CCB_TK
1304                 { 
1305                   /* Store the location of the `}' when doing xrefs */
1306                   if (current_function_decl && flag_emit_xref)
1307                     DECL_END_SOURCE_LINE (current_function_decl) = 
1308                       EXPR_WFL_ADD_COL ($2.location, 1);
1309                   $$ = empty_stmt_node; 
1310                 }
1311 |       block_begin block_statements block_end
1312                 { $$ = $3; }
1313 ;
1314
1315 block_begin:
1316         OCB_TK
1317                 { enter_block (); }
1318 ;
1319
1320 block_end:
1321         CCB_TK
1322                 { 
1323                   maybe_absorb_scoping_blocks ();
1324                   /* Store the location of the `}' when doing xrefs */
1325                   if (current_function_decl && flag_emit_xref)
1326                     DECL_END_SOURCE_LINE (current_function_decl) = 
1327                       EXPR_WFL_ADD_COL ($1.location, 1);                  
1328                   $$ = exit_block ();
1329                 }
1330 ;
1331
1332 block_statements:
1333         block_statement
1334 |       block_statements block_statement
1335 ;
1336
1337 block_statement:
1338         local_variable_declaration_statement
1339 |       statement
1340                 { java_method_add_stmt (current_function_decl, $1); }
1341 |       class_declaration       /* Added, JDK1.1 local classes */
1342                 { 
1343                   LOCAL_CLASS_P (TREE_TYPE (GET_CPC ())) = 1;
1344                   end_class_declaration (1);
1345                 }
1346 ;
1347
1348 local_variable_declaration_statement:
1349         local_variable_declaration SC_TK /* Can't catch missing ';' here */
1350 ;
1351
1352 local_variable_declaration:
1353         type variable_declarators
1354                 { declare_local_variables (0, $1, $2); }
1355 |       final type variable_declarators /* Added, JDK1.1 final locals */
1356                 { declare_local_variables ($1, $2, $3); }
1357 ;
1358
1359 statement:
1360         statement_without_trailing_substatement
1361 |       labeled_statement
1362 |       if_then_statement
1363 |       if_then_else_statement
1364 |       while_statement
1365 |       for_statement
1366                 { $$ = exit_block (); }
1367 ;
1368
1369 statement_nsi:
1370         statement_without_trailing_substatement
1371 |       labeled_statement_nsi
1372 |       if_then_else_statement_nsi
1373 |       while_statement_nsi
1374 |       for_statement_nsi
1375                 { $$ = exit_block (); }
1376 ;
1377
1378 statement_without_trailing_substatement:
1379         block
1380 |       empty_statement
1381 |       expression_statement
1382 |       switch_statement
1383 |       do_statement
1384 |       break_statement
1385 |       continue_statement
1386 |       return_statement
1387 |       synchronized_statement
1388 |       throw_statement
1389 |       try_statement
1390 ;
1391
1392 empty_statement:
1393         SC_TK
1394                 { $$ = empty_stmt_node; }
1395 ;
1396
1397 label_decl:
1398         identifier REL_CL_TK
1399                 {
1400                   $$ = build_labeled_block (EXPR_WFL_LINECOL ($1), 
1401                                             EXPR_WFL_NODE ($1));
1402                   pushlevel (2);
1403                   push_labeled_block ($$);
1404                   PUSH_LABELED_BLOCK ($$);
1405                 }
1406 ;
1407
1408 labeled_statement:
1409         label_decl statement
1410                 { $$ = finish_labeled_statement ($1, $2); }
1411 |       identifier error
1412                 {yyerror ("':' expected"); RECOVER;}
1413 ;
1414
1415 labeled_statement_nsi:
1416         label_decl statement_nsi
1417                 { $$ = finish_labeled_statement ($1, $2); }
1418 ;
1419
1420 /* We concentrate here a bunch of error handling rules that we couldn't write
1421    earlier, because expression_statement catches a missing ';'.  */
1422 expression_statement:
1423         statement_expression SC_TK
1424                 {
1425                   /* We have a statement. Generate a WFL around it so
1426                      we can debug it */
1427                   $$ = build_expr_wfl ($1, input_filename, lineno, 0);
1428                   /* We know we have a statement, so set the debug
1429                      info to be eventually generate here. */
1430                   $$ = JAVA_MAYBE_GENERATE_DEBUG_INFO ($$);
1431                 }
1432 |       error SC_TK 
1433                 {
1434                   if (ctxp->prevent_ese != lineno)
1435                     yyerror ("Invalid expression statement");
1436                   DRECOVER (expr_stmt);
1437                 }
1438 |       error OCB_TK
1439                 {
1440                   if (ctxp->prevent_ese != lineno)
1441                     yyerror ("Invalid expression statement");
1442                   DRECOVER (expr_stmt);
1443                 }
1444 |       error CCB_TK
1445                 {
1446                   if (ctxp->prevent_ese != lineno)
1447                     yyerror ("Invalid expression statement");
1448                   DRECOVER (expr_stmt);
1449                 }
1450 |       this_or_super OP_TK error
1451                 {yyerror ("')' expected"); RECOVER;}
1452 |       this_or_super OP_TK CP_TK error
1453                 {
1454                   parse_ctor_invocation_error ();
1455                   RECOVER;
1456                 }
1457 |       this_or_super OP_TK argument_list error
1458                 {yyerror ("')' expected"); RECOVER;}
1459 |       this_or_super OP_TK argument_list CP_TK error
1460                 {
1461                   parse_ctor_invocation_error ();
1462                   RECOVER;
1463                 }
1464 |       name DOT_TK SUPER_TK error
1465                 {yyerror ("'(' expected"); RECOVER;}
1466 |       name DOT_TK SUPER_TK OP_TK error
1467                 {yyerror ("')' expected"); RECOVER;}
1468 |       name DOT_TK SUPER_TK OP_TK argument_list error
1469                 {yyerror ("')' expected"); RECOVER;}
1470 |       name DOT_TK SUPER_TK OP_TK argument_list CP_TK error
1471                 {yyerror ("';' expected"); RECOVER;}
1472 |       name DOT_TK SUPER_TK OP_TK CP_TK error
1473                 {yyerror ("';' expected"); RECOVER;}
1474 ;
1475
1476 statement_expression: 
1477         assignment
1478 |       pre_increment_expression
1479 |       pre_decrement_expression
1480 |       post_increment_expression
1481 |       post_decrement_expression
1482 |       method_invocation
1483 |       class_instance_creation_expression
1484 ;
1485
1486 if_then_statement:
1487         IF_TK OP_TK expression CP_TK statement
1488                 { 
1489                   $$ = build_if_else_statement ($2.location, $3, 
1490                                                 $5, NULL_TREE);
1491                 }
1492 |       IF_TK error
1493                 {yyerror ("'(' expected"); RECOVER;}
1494 |       IF_TK OP_TK error
1495                 {yyerror ("Missing term"); RECOVER;}
1496 |       IF_TK OP_TK expression error
1497                 {yyerror ("')' expected"); RECOVER;}
1498 ;
1499
1500 if_then_else_statement:
1501         IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement
1502                 { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
1503 ;
1504
1505 if_then_else_statement_nsi:
1506         IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement_nsi
1507                 { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
1508 ;
1509
1510 switch_statement:
1511         switch_expression
1512                 {
1513                   enter_block ();
1514                 }
1515         switch_block
1516                 { 
1517                   /* Make into "proper list" of COMPOUND_EXPRs.
1518                      I.e. make the last statment also have its own
1519                      COMPOUND_EXPR. */
1520                   maybe_absorb_scoping_blocks ();
1521                   TREE_OPERAND ($1, 1) = exit_block ();
1522                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $1);
1523                 }
1524 ;
1525
1526 switch_expression:
1527         SWITCH_TK OP_TK expression CP_TK
1528                 { 
1529                   $$ = build (SWITCH_EXPR, NULL_TREE, $3, NULL_TREE);
1530                   EXPR_WFL_LINECOL ($$) = $2.location;
1531                 }
1532 |       SWITCH_TK error
1533                 {yyerror ("'(' expected"); RECOVER;}
1534 |       SWITCH_TK OP_TK error
1535                 {yyerror ("Missing term or ')'"); DRECOVER(switch_statement);}
1536 |       SWITCH_TK OP_TK expression CP_TK error
1537                 {yyerror ("'{' expected"); RECOVER;}
1538 ;
1539
1540 /* Default assignment is there to avoid type node on switch_block
1541    node. */
1542
1543 switch_block:
1544         OCB_TK CCB_TK
1545                 { $$ = NULL_TREE; }
1546 |       OCB_TK switch_labels CCB_TK
1547                 { $$ = NULL_TREE; }
1548 |       OCB_TK switch_block_statement_groups CCB_TK
1549                 { $$ = NULL_TREE; }
1550 |       OCB_TK switch_block_statement_groups switch_labels CCB_TK
1551                 { $$ = NULL_TREE; }
1552 ;
1553
1554 switch_block_statement_groups: 
1555         switch_block_statement_group
1556 |       switch_block_statement_groups switch_block_statement_group
1557 ;
1558
1559 switch_block_statement_group:
1560         switch_labels block_statements
1561 ;
1562
1563 switch_labels:
1564         switch_label
1565 |       switch_labels switch_label
1566 ;
1567
1568 switch_label:
1569         CASE_TK constant_expression REL_CL_TK
1570                 { 
1571                   tree lab = build1 (CASE_EXPR, NULL_TREE, $2);
1572                   EXPR_WFL_LINECOL (lab) = $1.location;
1573                   java_method_add_stmt (current_function_decl, lab);
1574                 }
1575 |       DEFAULT_TK REL_CL_TK
1576                 { 
1577                   tree lab = build1 (DEFAULT_EXPR, NULL_TREE, NULL_TREE);
1578                   EXPR_WFL_LINECOL (lab) = $1.location;
1579                   java_method_add_stmt (current_function_decl, lab);
1580                 }
1581 |       CASE_TK error
1582                 {yyerror ("Missing or invalid constant expression"); RECOVER;}
1583 |       CASE_TK constant_expression error
1584                 {yyerror ("':' expected"); RECOVER;}
1585 |       DEFAULT_TK error
1586                 {yyerror ("':' expected"); RECOVER;}
1587 ;
1588
1589 while_expression:
1590         WHILE_TK OP_TK expression CP_TK
1591                 { 
1592                   tree body = build_loop_body ($2.location, $3, 0);
1593                   $$ = build_new_loop (body);
1594                 }
1595 ;
1596
1597 while_statement:
1598         while_expression statement
1599                 { $$ = finish_loop_body (0, NULL_TREE, $2, 0); }
1600 |       WHILE_TK error
1601                 {YYERROR_NOW; yyerror ("'(' expected"); RECOVER;}
1602 |       WHILE_TK OP_TK error
1603                 {yyerror ("Missing term and ')' expected"); RECOVER;}
1604 |       WHILE_TK OP_TK expression error
1605                 {yyerror ("')' expected"); RECOVER;}
1606 ;
1607
1608 while_statement_nsi:
1609         while_expression statement_nsi
1610                 { $$ = finish_loop_body (0, NULL_TREE, $2, 0); }
1611 ;
1612
1613 do_statement_begin:
1614         DO_TK
1615                 { 
1616                   tree body = build_loop_body (0, NULL_TREE, 1);
1617                   $$ = build_new_loop (body);
1618                 }
1619         /* Need error handing here. FIXME */
1620 ;
1621
1622 do_statement: 
1623         do_statement_begin statement WHILE_TK OP_TK expression CP_TK SC_TK
1624                 { $$ = finish_loop_body ($4.location, $5, $2, 1); }
1625 ;
1626
1627 for_statement:
1628         for_begin SC_TK expression SC_TK for_update CP_TK statement
1629                 { $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7); }
1630 |       for_begin SC_TK SC_TK for_update CP_TK statement
1631                 { 
1632                   $$ = finish_for_loop (0, NULL_TREE, $4, $6);
1633                   /* We have not condition, so we get rid of the EXIT_EXPR */
1634                   LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) = 
1635                     empty_stmt_node;
1636                 }
1637 |       for_begin SC_TK error
1638                 {yyerror ("Invalid control expression"); RECOVER;}
1639 |       for_begin SC_TK expression SC_TK error
1640                 {yyerror ("Invalid update expression"); RECOVER;}
1641 |       for_begin SC_TK SC_TK error
1642                 {yyerror ("Invalid update expression"); RECOVER;}
1643 ;
1644
1645 for_statement_nsi:
1646         for_begin SC_TK expression SC_TK for_update CP_TK statement_nsi
1647                 { $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7);}
1648 |       for_begin SC_TK SC_TK for_update CP_TK statement_nsi
1649                 { 
1650                   $$ = finish_for_loop (0, NULL_TREE, $4, $6);
1651                   /* We have not condition, so we get rid of the EXIT_EXPR */
1652                   LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) = 
1653                     empty_stmt_node;
1654                 }
1655 ;
1656
1657 for_header:
1658         FOR_TK OP_TK
1659                 { 
1660                   /* This scope defined for local variable that may be
1661                      defined within the scope of the for loop */
1662                   enter_block (); 
1663                 }
1664 |       FOR_TK error
1665                 {yyerror ("'(' expected"); DRECOVER(for_1);}
1666 |       FOR_TK OP_TK error
1667                 {yyerror ("Invalid init statement"); RECOVER;}
1668 ;
1669
1670 for_begin:
1671         for_header for_init
1672                 { 
1673                   /* We now declare the loop body. The loop is
1674                      declared as a for loop. */
1675                   tree body = build_loop_body (0, NULL_TREE, 0);
1676                   $$ =  build_new_loop (body);
1677                   FOR_LOOP_P ($$) = 1;
1678                   /* The loop is added to the current block the for
1679                      statement is defined within */
1680                   java_method_add_stmt (current_function_decl, $$);
1681                 }
1682 ;
1683 for_init:                       /* Can be empty */
1684                 { $$ = empty_stmt_node; }
1685 |       statement_expression_list
1686                 { 
1687                   /* Init statement recorded within the previously
1688                      defined block scope */
1689                   $$ = java_method_add_stmt (current_function_decl, $1);
1690                 }
1691 |       local_variable_declaration
1692                 { 
1693                   /* Local variable are recorded within the previously
1694                      defined block scope */
1695                   $$ = NULL_TREE;
1696                 }
1697 |       statement_expression_list error
1698                 {yyerror ("';' expected"); DRECOVER(for_init_1);}
1699 ;
1700
1701 for_update:                     /* Can be empty */
1702                 {$$ = empty_stmt_node;}
1703 |       statement_expression_list
1704                 { $$ = build_debugable_stmt (BUILD_LOCATION (), $1); }
1705 ;
1706
1707 statement_expression_list:
1708         statement_expression
1709                 { $$ = add_stmt_to_compound (NULL_TREE, NULL_TREE, $1); }
1710 |       statement_expression_list C_TK statement_expression
1711                 { $$ = add_stmt_to_compound ($1, NULL_TREE, $3); }
1712 |       statement_expression_list C_TK error
1713                 {yyerror ("Missing term"); RECOVER;}
1714 ;
1715
1716 break_statement:
1717         BREAK_TK SC_TK
1718                 { $$ = build_bc_statement ($1.location, 1, NULL_TREE); }
1719 |       BREAK_TK identifier SC_TK
1720                 { $$ = build_bc_statement ($1.location, 1, $2); }
1721 |       BREAK_TK error
1722                 {yyerror ("Missing term"); RECOVER;}
1723 |       BREAK_TK identifier error
1724                 {yyerror ("';' expected"); RECOVER;}
1725 ;
1726
1727 continue_statement:
1728         CONTINUE_TK SC_TK
1729                 { $$ = build_bc_statement ($1.location, 0, NULL_TREE); }
1730 |       CONTINUE_TK identifier SC_TK
1731                 { $$ = build_bc_statement ($1.location, 0, $2); }
1732 |       CONTINUE_TK error
1733                 {yyerror ("Missing term"); RECOVER;}
1734 |       CONTINUE_TK identifier error
1735                 {yyerror ("';' expected"); RECOVER;}
1736 ;
1737
1738 return_statement:
1739         RETURN_TK SC_TK
1740                 { $$ = build_return ($1.location, NULL_TREE); }
1741 |       RETURN_TK expression SC_TK
1742                 { $$ = build_return ($1.location, $2); }
1743 |       RETURN_TK error
1744                 {yyerror ("Missing term"); RECOVER;}
1745 |       RETURN_TK expression error
1746                 {yyerror ("';' expected"); RECOVER;}
1747 ;
1748
1749 throw_statement:
1750         THROW_TK expression SC_TK
1751                 { 
1752                   $$ = build1 (THROW_EXPR, NULL_TREE, $2);
1753                   EXPR_WFL_LINECOL ($$) = $1.location;
1754                 }
1755 |       THROW_TK error
1756                 {yyerror ("Missing term"); RECOVER;}
1757 |       THROW_TK expression error
1758                 {yyerror ("';' expected"); RECOVER;}
1759 ;
1760
1761 synchronized_statement:
1762         synchronized OP_TK expression CP_TK block
1763                 { 
1764                   $$ = build (SYNCHRONIZED_EXPR, NULL_TREE, $3, $5);
1765                   EXPR_WFL_LINECOL ($$) = 
1766                     EXPR_WFL_LINECOL (MODIFIER_WFL (SYNCHRONIZED_TK));
1767                 }
1768 |       synchronized OP_TK expression CP_TK error
1769                 {yyerror ("'{' expected"); RECOVER;}
1770 |       synchronized error
1771                 {yyerror ("'(' expected"); RECOVER;}
1772 |       synchronized OP_TK error CP_TK
1773                 {yyerror ("Missing term"); RECOVER;}
1774 |       synchronized OP_TK error
1775                 {yyerror ("Missing term"); RECOVER;}
1776 ;
1777
1778 synchronized:
1779         modifiers
1780                 {
1781                   check_modifiers (
1782              "Illegal modifier `%s'. Only `synchronized' was expected here",
1783                                    $1, ACC_SYNCHRONIZED);
1784                   if ($1 != ACC_SYNCHRONIZED)
1785                     MODIFIER_WFL (SYNCHRONIZED_TK) = 
1786                       build_wfl_node (NULL_TREE);
1787                 }
1788 ;
1789
1790 try_statement:
1791         TRY_TK block catches
1792                 { $$ = build_try_statement ($1.location, $2, $3); }
1793 |       TRY_TK block finally
1794                 { $$ = build_try_finally_statement ($1.location, $2, $3); }
1795 |       TRY_TK block catches finally
1796                 { $$ = build_try_finally_statement 
1797                     ($1.location, build_try_statement ($1.location,
1798                                                        $2, $3), $4);
1799                 }
1800 |       TRY_TK error
1801                 {yyerror ("'{' expected"); DRECOVER (try_statement);}
1802 ;
1803
1804 catches:
1805         catch_clause
1806 |       catches catch_clause
1807                 { 
1808                   TREE_CHAIN ($2) = $1;
1809                   $$ = $2;
1810                 }
1811 ;
1812
1813 catch_clause:
1814         catch_clause_parameter block
1815                 { 
1816                   java_method_add_stmt (current_function_decl, $2);
1817                   exit_block ();
1818                   $$ = $1;
1819                 }
1820
1821 catch_clause_parameter:
1822         CATCH_TK OP_TK formal_parameter CP_TK
1823                 { 
1824                   /* We add a block to define a scope for
1825                      formal_parameter (CCBP). The formal parameter is
1826                      declared initialized by the appropriate function
1827                      call */
1828                   tree ccpb = enter_block ();
1829                   tree init = build_assignment (ASSIGN_TK, $2.location, 
1830                                                 TREE_PURPOSE ($3), 
1831                                                 soft_exceptioninfo_call_node);
1832                   declare_local_variables (0, TREE_VALUE ($3),
1833                                            build_tree_list (TREE_PURPOSE ($3),
1834                                                             init));
1835                   $$ = build1 (CATCH_EXPR, NULL_TREE, ccpb);
1836                   EXPR_WFL_LINECOL ($$) = $1.location;
1837                 }
1838 |       CATCH_TK error
1839                 {yyerror ("'(' expected"); RECOVER; $$ = NULL_TREE;}
1840 |       CATCH_TK OP_TK error 
1841                 {
1842                   yyerror ("Missing term or ')' expected"); 
1843                   RECOVER; $$ = NULL_TREE;
1844                 }
1845 |       CATCH_TK OP_TK error CP_TK /* That's for () */
1846                 {yyerror ("Missing term"); RECOVER; $$ = NULL_TREE;}
1847 ;
1848
1849 finally:
1850         FINALLY_TK block
1851                 { $$ = $2; }
1852 |       FINALLY_TK error
1853                 {yyerror ("'{' expected"); RECOVER; }
1854 ;
1855
1856 /* 19.12 Production from 15: Expressions  */
1857 primary:
1858         primary_no_new_array
1859 |       array_creation_expression
1860 ;
1861
1862 primary_no_new_array:
1863         literal
1864 |       THIS_TK
1865                 { $$ = build_this ($1.location); }
1866 |       OP_TK expression CP_TK
1867                 {$$ = $2;}
1868 |       class_instance_creation_expression
1869 |       field_access
1870 |       method_invocation
1871 |       array_access
1872 |       type_literals
1873         /* Added, JDK1.1 inner classes. Documentation is wrong
1874            refering to a 'ClassName' (class_name) rule that doesn't
1875            exist. Used name: instead.  */
1876 |       name DOT_TK THIS_TK
1877                 { 
1878                   tree wfl = build_wfl_node (this_identifier_node);
1879                   $$ = make_qualified_primary ($1, wfl, EXPR_WFL_LINECOL ($1));
1880                 }
1881 |       OP_TK expression error 
1882                 {yyerror ("')' expected"); RECOVER;}
1883 |       name DOT_TK error
1884                 {yyerror ("'class' or 'this' expected" ); RECOVER;}
1885 |       primitive_type DOT_TK error
1886                 {yyerror ("'class' expected" ); RECOVER;}
1887 |       VOID_TK DOT_TK error
1888                 {yyerror ("'class' expected" ); RECOVER;}
1889 ;
1890
1891 /* Added, JDK1.1 type literals. We can't use `type' directly, so we
1892    broke the rule down a bit. */
1893
1894 array_type_literal:
1895         primitive_type OSB_TK CSB_TK
1896                 { 
1897                   $$ = build_java_array_type ($1, -1);
1898                   CLASS_LOADED_P ($$) = 1;
1899                 }
1900 |       name OSB_TK CSB_TK
1901                 { $$ = build_unresolved_array_type ($1); }
1902 /* This triggers two reduce/reduce conflict between array_type_literal and
1903    dims. FIXME.
1904 |       array_type OSB_TK CSB_TK
1905                 { $$ = build_unresolved_array_type ($1); }
1906 */
1907 ;
1908
1909 type_literals:
1910         name DOT_TK CLASS_TK
1911                 { $$ = build_incomplete_class_ref ($2.location, $1); }
1912 |       array_type_literal DOT_TK CLASS_TK
1913                 { $$ = build_incomplete_class_ref ($2.location, $1); }
1914 |       primitive_type DOT_TK CLASS_TK
1915                 { $$ = build_class_ref ($1); }
1916 |       VOID_TK DOT_TK CLASS_TK
1917                 { $$ = build_class_ref (void_type_node); }
1918 ;
1919
1920 class_instance_creation_expression:
1921         NEW_TK class_type OP_TK argument_list CP_TK
1922                 { $$ = build_new_invocation ($2, $4); }
1923 |       NEW_TK class_type OP_TK CP_TK
1924                 { $$ = build_new_invocation ($2, NULL_TREE); }
1925 |       anonymous_class_creation
1926         /* Added, JDK1.1 inner classes, modified to use name or
1927            primary instead of primary solely which couldn't work in
1928            all situations.  */
1929 |       something_dot_new identifier OP_TK CP_TK
1930                 { 
1931                   tree ctor = build_new_invocation ($2, NULL_TREE);
1932                   $$ = make_qualified_primary ($1, ctor, 
1933                                                EXPR_WFL_LINECOL ($1));
1934                 }
1935 |       something_dot_new identifier OP_TK CP_TK class_body
1936 |       something_dot_new identifier OP_TK argument_list CP_TK
1937                 { 
1938                   tree ctor = build_new_invocation ($2, $4);
1939                   $$ = make_qualified_primary ($1, ctor, 
1940                                                EXPR_WFL_LINECOL ($1));
1941                 }
1942 |       something_dot_new identifier OP_TK argument_list CP_TK class_body
1943 |       NEW_TK error SC_TK 
1944                 {yyerror ("'(' expected"); DRECOVER(new_1);}
1945 |       NEW_TK class_type error
1946                 {yyerror ("'(' expected"); RECOVER;}
1947 |       NEW_TK class_type OP_TK error
1948                 {yyerror ("')' or term expected"); RECOVER;}
1949 |       NEW_TK class_type OP_TK argument_list error
1950                 {yyerror ("')' expected"); RECOVER;}
1951 |       something_dot_new error
1952                 {YYERROR_NOW; yyerror ("Identifier expected"); RECOVER;}
1953 |       something_dot_new identifier error
1954                 {yyerror ("'(' expected"); RECOVER;}
1955 ;
1956
1957 /* Created after JDK1.1 rules originally added to
1958    class_instance_creation_expression, but modified to use
1959    'class_type' instead of 'TypeName' (type_name) which is mentionned
1960    in the documentation but doesn't exist. */
1961
1962 anonymous_class_creation:
1963         NEW_TK class_type OP_TK argument_list CP_TK 
1964                 { create_anonymous_class ($1.location, $2); }
1965         class_body
1966                 { 
1967                   tree id = build_wfl_node (DECL_NAME (GET_CPC ()));
1968                   EXPR_WFL_LINECOL (id) = EXPR_WFL_LINECOL ($2);
1969
1970                   end_class_declaration (1);
1971
1972                   /* Now we can craft the new expression */
1973                   $$ = build_new_invocation (id, $4);
1974
1975                   /* Note that we can't possibly be here if
1976                      `class_type' is an interface (in which case the
1977                      anonymous class extends Object and implements
1978                      `class_type', hence its constructor can't have
1979                      arguments.) */
1980
1981                   /* Otherwise, the innerclass must feature a
1982                      constructor matching `argument_list'. Anonymous
1983                      classes are a bit special: it's impossible to
1984                      define constructor for them, hence constructors
1985                      must be generated following the hints provided by
1986                      the `new' expression. Whether a super constructor
1987                      of that nature exists or not is to be verified
1988                      later on in verify_constructor_super. 
1989
1990                      It's during the expansion of a `new' statement
1991                      refering to an anonymous class that a ctor will
1992                      be generated for the anonymous class, with the
1993                      right arguments. */
1994
1995                 }
1996 |       NEW_TK class_type OP_TK CP_TK 
1997                 { create_anonymous_class ($1.location, $2); }
1998         class_body         
1999                 { 
2000                   tree id = build_wfl_node (DECL_NAME (GET_CPC ()));
2001                   EXPR_WFL_LINECOL (id) = EXPR_WFL_LINECOL ($2);
2002
2003                   end_class_declaration (1);
2004
2005                   /* Now we can craft the new expression. The
2006                      statement doesn't need to be remember so that a
2007                      constructor can be generated, since its signature
2008                      is already known. */
2009                   $$ = build_new_invocation (id, NULL_TREE);
2010                 }
2011 ;
2012
2013 something_dot_new:              /* Added, not part of the specs. */
2014         name DOT_TK NEW_TK
2015                 { $$ = $1; }
2016 |       primary DOT_TK NEW_TK
2017                 { $$ = $1; }
2018 ;
2019
2020 argument_list:
2021         expression
2022                 { 
2023                   $$ = tree_cons (NULL_TREE, $1, NULL_TREE);
2024                   ctxp->formal_parameter_number = 1; 
2025                 }
2026 |       argument_list C_TK expression
2027                 {
2028                   ctxp->formal_parameter_number += 1;
2029                   $$ = tree_cons (NULL_TREE, $3, $1);
2030                 }
2031 |       argument_list C_TK error
2032                 {yyerror ("Missing term"); RECOVER;}
2033 ;
2034
2035 array_creation_expression:
2036         NEW_TK primitive_type dim_exprs
2037                 { $$ = build_newarray_node ($2, $3, 0); }
2038 |       NEW_TK class_or_interface_type dim_exprs
2039                 { $$ = build_newarray_node ($2, $3, 0); }
2040 |       NEW_TK primitive_type dim_exprs dims
2041                 { $$ = build_newarray_node ($2, $3, CURRENT_OSB (ctxp));}
2042 |       NEW_TK class_or_interface_type dim_exprs dims
2043                 { $$ = build_newarray_node ($2, $3, CURRENT_OSB (ctxp));}
2044         /* Added, JDK1.1 anonymous array. Initial documentation rule
2045            modified */
2046 |       NEW_TK class_or_interface_type dims array_initializer
2047                 {
2048                   char *sig;
2049                   while (CURRENT_OSB (ctxp)--)
2050                     obstack_1grow (&temporary_obstack, '[');
2051                   sig = obstack_finish (&temporary_obstack);
2052                   $$ = build (NEW_ANONYMOUS_ARRAY_EXPR, NULL_TREE,
2053                               $2, get_identifier (sig), $4);
2054                 }
2055 |       NEW_TK primitive_type dims array_initializer
2056                 { 
2057                   tree type = $2;
2058                   while (CURRENT_OSB (ctxp)--)
2059                     type = build_java_array_type (type, -1);
2060                   $$ = build (NEW_ANONYMOUS_ARRAY_EXPR, NULL_TREE, 
2061                               build_pointer_type (type), NULL_TREE, $4);
2062                 }
2063 |       NEW_TK error CSB_TK
2064                 {yyerror ("'[' expected"); DRECOVER ("]");}
2065 |       NEW_TK error OSB_TK
2066                 {yyerror ("']' expected"); RECOVER;}
2067 ;
2068
2069 dim_exprs:
2070         dim_expr
2071                 { $$ = build_tree_list (NULL_TREE, $1); }
2072 |       dim_exprs dim_expr
2073                 { $$ = tree_cons (NULL_TREE, $2, $$); }
2074 ;
2075
2076 dim_expr:
2077         OSB_TK expression CSB_TK
2078                 { 
2079                   EXPR_WFL_LINECOL ($2) = $1.location;
2080                   $$ = $2;
2081                 }
2082 |       OSB_TK expression error
2083                 {yyerror ("']' expected"); RECOVER;}
2084 |       OSB_TK error
2085                 {
2086                   yyerror ("Missing term");
2087                   yyerror ("']' expected");
2088                   RECOVER;
2089                 }
2090 ;
2091
2092 dims:                           
2093         OSB_TK CSB_TK
2094                 { 
2095                   int allocate = 0;
2096                   /* If not initialized, allocate memory for the osb
2097                      numbers stack */
2098                   if (!ctxp->osb_limit)
2099                     {
2100                       allocate = ctxp->osb_limit = 32;
2101                       ctxp->osb_depth = -1;
2102                     }
2103                   /* If capacity overflown, reallocate a bigger chunk */
2104                   else if (ctxp->osb_depth+1 == ctxp->osb_limit)
2105                     allocate = ctxp->osb_limit << 1;
2106                   
2107                   if (allocate)
2108                     {
2109                       allocate *= sizeof (int);
2110                       if (ctxp->osb_number)
2111                         ctxp->osb_number = (int *)xrealloc (ctxp->osb_number,
2112                                                             allocate);
2113                       else
2114                         ctxp->osb_number = (int *)xmalloc (allocate);
2115                     }
2116                   ctxp->osb_depth++;
2117                   CURRENT_OSB (ctxp) = 1;
2118                 }
2119 |       dims OSB_TK CSB_TK
2120                 { CURRENT_OSB (ctxp)++; }
2121 |       dims OSB_TK error
2122                 { yyerror ("']' expected"); RECOVER;}
2123 ;
2124
2125 field_access:
2126         primary DOT_TK identifier
2127                 { $$ = make_qualified_primary ($1, $3, $2.location); }
2128                 /*  FIXME - REWRITE TO: 
2129                 { $$ = build_binop (COMPONENT_REF, $2.location, $1, $3); } */
2130 |       SUPER_TK DOT_TK identifier
2131                 {
2132                   tree super_wfl = 
2133                     build_wfl_node (super_identifier_node);
2134                   EXPR_WFL_LINECOL (super_wfl) = $1.location;
2135                   $$ = make_qualified_name (super_wfl, $3, $2.location);
2136                 }
2137 |       SUPER_TK error
2138                 {yyerror ("Field expected"); DRECOVER (super_field_acces);}
2139 ;
2140
2141 method_invocation:
2142         name OP_TK CP_TK
2143                 { $$ = build_method_invocation ($1, NULL_TREE); }
2144 |       name OP_TK argument_list CP_TK
2145                 { $$ = build_method_invocation ($1, $3); }
2146 |       primary DOT_TK identifier OP_TK CP_TK
2147                 { 
2148                   if (TREE_CODE ($1) == THIS_EXPR)
2149                     $$ = build_this_super_qualified_invocation 
2150                       (1, $3, NULL_TREE, 0, $2.location);
2151                   else
2152                     {
2153                       tree invok = build_method_invocation ($3, NULL_TREE);
2154                       $$ = make_qualified_primary ($1, invok, $2.location);
2155                     }
2156                 }
2157 |       primary DOT_TK identifier OP_TK argument_list CP_TK
2158                 { 
2159                   if (TREE_CODE ($1) == THIS_EXPR)
2160                     $$ = build_this_super_qualified_invocation 
2161                       (1, $3, $5, 0, $2.location);
2162                   else
2163                     {
2164                       tree invok = build_method_invocation ($3, $5);
2165                       $$ = make_qualified_primary ($1, invok, $2.location);
2166                     }
2167                 }
2168 |       SUPER_TK DOT_TK identifier OP_TK CP_TK
2169                 { 
2170                   $$ = build_this_super_qualified_invocation 
2171                     (0, $3, NULL_TREE, $1.location, $2.location);
2172                 }
2173 |       SUPER_TK DOT_TK identifier OP_TK argument_list CP_TK
2174                 {
2175                   $$ = build_this_super_qualified_invocation 
2176                     (0, $3, $5, $1.location, $2.location);
2177                 }
2178         /* Screws up thing. I let it here until I'm convinced it can
2179            be removed. FIXME
2180 |       primary DOT_TK error
2181                 {yyerror ("'(' expected"); DRECOVER(bad);} */
2182 |       SUPER_TK DOT_TK error CP_TK
2183                 { yyerror ("'(' expected"); DRECOVER (method_invocation); }
2184 |       SUPER_TK DOT_TK error DOT_TK
2185                 { yyerror ("'(' expected"); DRECOVER (method_invocation); }
2186 ;
2187
2188 array_access:
2189         name OSB_TK expression CSB_TK
2190                 { $$ = build_array_ref ($2.location, $1, $3); }
2191 |       primary_no_new_array OSB_TK expression CSB_TK
2192                 { $$ = build_array_ref ($2.location, $1, $3); }
2193 |       name OSB_TK error
2194                 {
2195                   yyerror ("Missing term and ']' expected");
2196                   DRECOVER(array_access);
2197                 }
2198 |       name OSB_TK expression error
2199                 {
2200                   yyerror ("']' expected");
2201                   DRECOVER(array_access);
2202                 }
2203 |       primary_no_new_array OSB_TK error
2204                 {
2205                   yyerror ("Missing term and ']' expected");
2206                   DRECOVER(array_access);
2207                 }
2208 |       primary_no_new_array OSB_TK expression error
2209                 {
2210                   yyerror ("']' expected");
2211                   DRECOVER(array_access);
2212                 }
2213 ;
2214
2215 postfix_expression:
2216         primary
2217 |       name
2218 |       post_increment_expression
2219 |       post_decrement_expression
2220 ;
2221
2222 post_increment_expression:
2223         postfix_expression INCR_TK
2224                 { $$ = build_incdec ($2.token, $2.location, $1, 1); }
2225 ;
2226
2227 post_decrement_expression:
2228         postfix_expression DECR_TK
2229                 { $$ = build_incdec ($2.token, $2.location, $1, 1); }
2230 ;
2231
2232 unary_expression:
2233         pre_increment_expression
2234 |       pre_decrement_expression
2235 |       PLUS_TK unary_expression
2236                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2237 |       MINUS_TK unary_expression
2238                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2239 |       unary_expression_not_plus_minus
2240 |       PLUS_TK error
2241                 {yyerror ("Missing term"); RECOVER}
2242 |       MINUS_TK error
2243                 {yyerror ("Missing term"); RECOVER}
2244 ;
2245
2246 pre_increment_expression:
2247         INCR_TK unary_expression
2248                 {$$ = build_incdec ($1.token, $1.location, $2, 0); }
2249 |       INCR_TK error
2250                 {yyerror ("Missing term"); RECOVER}
2251 ;
2252
2253 pre_decrement_expression:
2254         DECR_TK unary_expression
2255                 {$$ = build_incdec ($1.token, $1.location, $2, 0); }
2256 |       DECR_TK error
2257                 {yyerror ("Missing term"); RECOVER}
2258 ;
2259
2260 unary_expression_not_plus_minus:
2261         postfix_expression
2262 |       NOT_TK unary_expression
2263                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2264 |       NEG_TK unary_expression
2265                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2266 |       cast_expression
2267 |       NOT_TK error
2268                 {yyerror ("Missing term"); RECOVER}
2269 |       NEG_TK error
2270                 {yyerror ("Missing term"); RECOVER}
2271 ;
2272
2273 cast_expression:                /* Error handling here is potentially weak */
2274         OP_TK primitive_type dims CP_TK unary_expression
2275                 { 
2276                   tree type = $2;
2277                   while (CURRENT_OSB (ctxp)--)
2278                     type = build_java_array_type (type, -1);
2279                   ctxp->osb_depth--;
2280                   $$ = build_cast ($1.location, type, $5); 
2281                 }
2282 |       OP_TK primitive_type CP_TK unary_expression
2283                 { $$ = build_cast ($1.location, $2, $4); }
2284 |       OP_TK expression CP_TK unary_expression_not_plus_minus
2285                 { $$ = build_cast ($1.location, $2, $4); }
2286 |       OP_TK name dims CP_TK unary_expression_not_plus_minus
2287                 { 
2288                   const char *ptr;
2289                   while (CURRENT_OSB (ctxp)--)
2290                     obstack_1grow (&temporary_obstack, '[');
2291                   ctxp->osb_depth--;
2292                   obstack_grow0 (&temporary_obstack, 
2293                                  IDENTIFIER_POINTER (EXPR_WFL_NODE ($2)),
2294                                  IDENTIFIER_LENGTH (EXPR_WFL_NODE ($2)));
2295                   ptr = obstack_finish (&temporary_obstack);
2296                   EXPR_WFL_NODE ($2) = get_identifier (ptr);
2297                   $$ = build_cast ($1.location, $2, $5);
2298                 }
2299 |       OP_TK primitive_type OSB_TK error
2300                 {yyerror ("']' expected, invalid type expression");}
2301 |       OP_TK error
2302                 {
2303                   if (ctxp->prevent_ese != lineno)
2304                     yyerror ("Invalid type expression"); RECOVER;
2305                   RECOVER;
2306                 }
2307 |       OP_TK primitive_type dims CP_TK error
2308                 {yyerror ("Missing term"); RECOVER;}
2309 |       OP_TK primitive_type CP_TK error
2310                 {yyerror ("Missing term"); RECOVER;}
2311 |       OP_TK name dims CP_TK error
2312                 {yyerror ("Missing term"); RECOVER;}
2313 ;
2314
2315 multiplicative_expression:
2316         unary_expression
2317 |       multiplicative_expression MULT_TK unary_expression
2318                 { 
2319                   $$ = build_binop (BINOP_LOOKUP ($2.token), 
2320                                     $2.location, $1, $3);
2321                 }
2322 |       multiplicative_expression DIV_TK unary_expression
2323                 {
2324                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2325                                     $1, $3); 
2326                 }
2327 |       multiplicative_expression REM_TK unary_expression
2328                 {
2329                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2330                                     $1, $3); 
2331                 }
2332 |       multiplicative_expression MULT_TK error
2333                 {yyerror ("Missing term"); RECOVER;}
2334 |       multiplicative_expression DIV_TK error
2335                 {yyerror ("Missing term"); RECOVER;}
2336 |       multiplicative_expression REM_TK error
2337                 {yyerror ("Missing term"); RECOVER;}
2338 ;
2339
2340 additive_expression:
2341         multiplicative_expression
2342 |       additive_expression PLUS_TK multiplicative_expression
2343                 {
2344                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2345                                     $1, $3); 
2346                 }
2347 |       additive_expression MINUS_TK multiplicative_expression
2348                 {
2349                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2350                                     $1, $3); 
2351                 }
2352 |       additive_expression PLUS_TK error
2353                 {yyerror ("Missing term"); RECOVER;}
2354 |       additive_expression MINUS_TK error
2355                 {yyerror ("Missing term"); RECOVER;}
2356 ;
2357
2358 shift_expression:
2359         additive_expression
2360 |       shift_expression LS_TK additive_expression
2361                 {
2362                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2363                                     $1, $3); 
2364                 }
2365 |       shift_expression SRS_TK additive_expression
2366                 {
2367                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2368                                     $1, $3); 
2369                 }
2370 |       shift_expression ZRS_TK additive_expression
2371                 {
2372                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2373                                     $1, $3); 
2374                 }
2375 |       shift_expression LS_TK error
2376                 {yyerror ("Missing term"); RECOVER;}
2377 |       shift_expression SRS_TK error
2378                 {yyerror ("Missing term"); RECOVER;}
2379 |       shift_expression ZRS_TK error
2380                 {yyerror ("Missing term"); RECOVER;}
2381 ;
2382
2383 relational_expression:
2384         shift_expression
2385 |       relational_expression LT_TK shift_expression
2386                 {
2387                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2388                                     $1, $3); 
2389                 }
2390 |       relational_expression GT_TK shift_expression
2391                 {
2392                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2393                                     $1, $3); 
2394                 }
2395 |       relational_expression LTE_TK shift_expression
2396                 {
2397                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2398                                     $1, $3); 
2399                 }
2400 |       relational_expression GTE_TK shift_expression
2401                 {
2402                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2403                                     $1, $3); 
2404                 }
2405 |       relational_expression INSTANCEOF_TK reference_type
2406                 { $$ = build_binop (INSTANCEOF_EXPR, $2.location, $1, $3); }
2407 |       relational_expression LT_TK error
2408                 {yyerror ("Missing term"); RECOVER;}
2409 |       relational_expression GT_TK error
2410                 {yyerror ("Missing term"); RECOVER;}
2411 |       relational_expression LTE_TK error
2412                 {yyerror ("Missing term"); RECOVER;}
2413 |       relational_expression GTE_TK error
2414                 {yyerror ("Missing term"); RECOVER;}
2415 |       relational_expression INSTANCEOF_TK error
2416                 {yyerror ("Invalid reference type"); RECOVER;}
2417 ;
2418
2419 equality_expression:
2420         relational_expression
2421 |       equality_expression EQ_TK relational_expression
2422                 {
2423                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2424                                     $1, $3); 
2425                 }
2426 |       equality_expression NEQ_TK relational_expression
2427                 {
2428                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2429                                     $1, $3); 
2430                 }
2431 |       equality_expression EQ_TK error
2432                 {yyerror ("Missing term"); RECOVER;}
2433 |       equality_expression NEQ_TK error
2434                 {yyerror ("Missing term"); RECOVER;}
2435 ;
2436
2437 and_expression:
2438         equality_expression
2439 |       and_expression AND_TK equality_expression
2440                 {
2441                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2442                                     $1, $3); 
2443                 }
2444 |       and_expression AND_TK error
2445                 {yyerror ("Missing term"); RECOVER;}
2446 ;
2447
2448 exclusive_or_expression:
2449         and_expression
2450 |       exclusive_or_expression XOR_TK and_expression
2451                 {
2452                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2453                                     $1, $3); 
2454                 }
2455 |       exclusive_or_expression XOR_TK error
2456                 {yyerror ("Missing term"); RECOVER;}
2457 ;
2458
2459 inclusive_or_expression:
2460         exclusive_or_expression
2461 |       inclusive_or_expression OR_TK exclusive_or_expression
2462                 {
2463                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2464                                     $1, $3); 
2465                 }
2466 |       inclusive_or_expression OR_TK error
2467                 {yyerror ("Missing term"); RECOVER;}
2468 ;
2469
2470 conditional_and_expression:
2471         inclusive_or_expression
2472 |       conditional_and_expression BOOL_AND_TK inclusive_or_expression
2473                 {
2474                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2475                                     $1, $3); 
2476                 }
2477 |       conditional_and_expression BOOL_AND_TK error
2478                 {yyerror ("Missing term"); RECOVER;}
2479 ;
2480
2481 conditional_or_expression:
2482         conditional_and_expression
2483 |       conditional_or_expression BOOL_OR_TK conditional_and_expression
2484                 {
2485                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2486                                     $1, $3); 
2487                 }
2488 |       conditional_or_expression BOOL_OR_TK error
2489                 {yyerror ("Missing term"); RECOVER;}
2490 ;
2491
2492 conditional_expression:         /* Error handling here is weak */
2493         conditional_or_expression
2494 |       conditional_or_expression REL_QM_TK expression REL_CL_TK conditional_expression
2495                 {
2496                   $$ = build (CONDITIONAL_EXPR, NULL_TREE, $1, $3, $5);
2497                   EXPR_WFL_LINECOL ($$) = $2.location;
2498                 }
2499 |       conditional_or_expression REL_QM_TK REL_CL_TK error
2500                 {
2501                   YYERROR_NOW;
2502                   yyerror ("Missing term");
2503                   DRECOVER (1);
2504                 }
2505 |       conditional_or_expression REL_QM_TK error
2506                 {yyerror ("Missing term"); DRECOVER (2);}
2507 |       conditional_or_expression REL_QM_TK expression REL_CL_TK error
2508                 {yyerror ("Missing term"); DRECOVER (3);}
2509 ;
2510
2511 assignment_expression:
2512         conditional_expression
2513 |       assignment
2514 ;
2515
2516 assignment:
2517         left_hand_side assignment_operator assignment_expression
2518                 { $$ = build_assignment ($2.token, $2.location, $1, $3); }
2519 |       left_hand_side assignment_operator error
2520                 {
2521                   if (ctxp->prevent_ese != lineno)
2522                     yyerror ("Missing term");
2523                   DRECOVER (assign);
2524                 }
2525 ;
2526
2527 left_hand_side:
2528         name
2529 |       field_access
2530 |       array_access
2531 ;
2532
2533 assignment_operator:
2534         ASSIGN_ANY_TK
2535 |       ASSIGN_TK
2536 ;
2537
2538 expression:
2539         assignment_expression
2540 ;
2541
2542 constant_expression:
2543         expression
2544 ;
2545
2546 %%
2547 \f
2548
2549 /* This section of the code deal with save/restoring parser contexts.
2550    Add mode documentation here. FIXME */
2551
2552 /* Helper function. Create a new parser context. With
2553    COPY_FROM_PREVIOUS set to a non zero value, content of the previous
2554    context is copied, otherwise, the new context is zeroed. The newly
2555    created context becomes the current one.  */
2556
2557 static void
2558 create_new_parser_context (copy_from_previous)
2559     int copy_from_previous;
2560 {
2561   struct parser_ctxt *new;
2562
2563   new =  (struct parser_ctxt *)xmalloc(sizeof (struct parser_ctxt));
2564   if (copy_from_previous)
2565     {
2566       memcpy ((PTR)new, (PTR)ctxp, sizeof (struct parser_ctxt));
2567       new->saved_data_ctx = 1;
2568     }
2569   else
2570     bzero ((PTR) new, sizeof (struct parser_ctxt));
2571       
2572   new->next = ctxp;
2573   ctxp = new;
2574 }
2575
2576 /* Create a new parser context and make it the current one. */
2577
2578 void
2579 java_push_parser_context ()
2580 {
2581   create_new_parser_context (0);
2582   if (ctxp->next)
2583     {
2584       ctxp->incomplete_class = ctxp->next->incomplete_class;
2585       ctxp->gclass_list = ctxp->next->gclass_list;
2586     }
2587 }  
2588
2589 void 
2590 java_pop_parser_context (generate)
2591      int generate;
2592 {
2593   tree current;
2594   struct parser_ctxt *toFree, *next;
2595
2596   if (!ctxp)
2597     return;
2598
2599   toFree = ctxp;
2600   next = ctxp->next;
2601   if (next)
2602     {
2603       next->incomplete_class = ctxp->incomplete_class;
2604       next->gclass_list = ctxp->gclass_list;
2605       lineno = ctxp->lineno;
2606       finput = ctxp->finput;
2607       current_class = ctxp->current_class;
2608     }
2609
2610   /* Set the single import class file flag to 0 for the current list
2611      of imported things */
2612   for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
2613     IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_PURPOSE (current)) = 0;
2614
2615   /* And restore those of the previous context */
2616   if ((ctxp = next))            /* Assignment is really meant here */
2617     for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
2618       IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_PURPOSE (current)) = 1;
2619   
2620   /* If we pushed a context to parse a class intended to be generated,
2621      we keep it so we can remember the class. What we could actually
2622      do is to just update a list of class names.  */
2623   if (generate)
2624     {
2625       toFree->next = ctxp_for_generation;
2626       ctxp_for_generation = toFree;
2627     }
2628   else
2629     free (toFree);
2630 }
2631
2632 /* Create a parser context for the use of saving some global
2633    variables.  */
2634
2635 void
2636 java_parser_context_save_global ()
2637 {
2638   if (!ctxp)
2639     {
2640       java_push_parser_context ();
2641       ctxp->saved_data_ctx = 1;
2642     }
2643
2644   /* If this context already stores data, create a new one suitable
2645      for data storage. */
2646   else if (ctxp->saved_data)
2647     create_new_parser_context (1);
2648
2649   ctxp->finput = finput;
2650   ctxp->lineno = lineno;
2651   ctxp->current_class = current_class;
2652   ctxp->filename = input_filename;
2653   ctxp->current_function_decl = current_function_decl;
2654   ctxp->saved_data = 1;
2655 }
2656
2657 /* Restore some global variables from the previous context. Make the
2658    previous context the current one.  */
2659
2660 void
2661 java_parser_context_restore_global ()
2662 {
2663   finput = ctxp->finput;
2664   lineno = ctxp->lineno;
2665   current_class = ctxp->current_class;
2666   input_filename = ctxp->filename;
2667   current_function_decl = ctxp->current_function_decl;
2668   ctxp->saved_data = 0;
2669   if (ctxp->saved_data_ctx)
2670     java_pop_parser_context (0);
2671 }
2672
2673 /* Suspend vital data for the current class/function being parsed so
2674    that an other class can be parsed. Used to let local/anonymous
2675    classes be parsed.  */
2676
2677 static void
2678 java_parser_context_suspend ()
2679 {
2680   /* This makes debugging through java_debug_context easier */
2681   static char *name = "<inner buffer context>";
2682
2683   /* Duplicate the previous context, use it to save the globals we're
2684      interested in */
2685   create_new_parser_context (1);
2686   ctxp->current_function_decl = current_function_decl;
2687   ctxp->current_class = current_class;
2688
2689   /* Then create a new context which inherits all data from the
2690      previous one. This will be the new current context  */
2691   create_new_parser_context (1);
2692
2693   /* Help debugging */
2694   ctxp->next->filename = name;
2695 }
2696
2697 /* Resume vital data for the current class/function being parsed so
2698    that an other class can be parsed. Used to let local/anonymous
2699    classes be parsed.  The trick is the data storing file position
2700    informations must be restored to their current value, so parsing
2701    can resume as if no context was ever saved. */
2702
2703 static void
2704 java_parser_context_resume ()
2705 {
2706   struct parser_ctxt *old = ctxp;             /* This one is to be discarded */
2707   struct parser_ctxt *saver = old->next;      /* This one contain saved info */
2708   struct parser_ctxt *restored = saver->next; /* This one is the old current */
2709
2710   /* We need to inherit the list of classes to complete/generate */
2711   restored->incomplete_class = old->incomplete_class;
2712   restored->gclass_list = old->gclass_list;
2713   restored->classd_list = old->classd_list;
2714   restored->class_list = old->class_list;
2715
2716   /* Restore the current class and function from the saver */
2717   current_class = saver->current_class;
2718   current_function_decl = saver->current_function_decl;
2719
2720   /* Retrive the restored context */
2721   ctxp = restored;
2722
2723   /* Re-installed the data for the parsing to carry on */
2724   bcopy (&old->marker_begining, &ctxp->marker_begining,
2725          (size_t)(&ctxp->marker_end - &ctxp->marker_begining));
2726
2727   /* Buffer context can now be discarded */
2728   free (saver);
2729   free (old);
2730 }
2731
2732 /* Add a new anchor node to which all statement(s) initializing static
2733    and non static initialized upon declaration field(s) will be
2734    linked.  */
2735
2736 static void
2737 java_parser_context_push_initialized_field ()
2738 {
2739   tree node;
2740
2741   node = build_tree_list (NULL_TREE, NULL_TREE);
2742   TREE_CHAIN (node) = CPC_STATIC_INITIALIZER_LIST (ctxp);
2743   CPC_STATIC_INITIALIZER_LIST (ctxp) = node;
2744
2745   node = build_tree_list (NULL_TREE, NULL_TREE);
2746   TREE_CHAIN (node) = CPC_INITIALIZER_LIST (ctxp);
2747   CPC_INITIALIZER_LIST (ctxp) = node;
2748
2749   node = build_tree_list (NULL_TREE, NULL_TREE);
2750   TREE_CHAIN (node) = CPC_INSTANCE_INITIALIZER_LIST (ctxp);
2751   CPC_INSTANCE_INITIALIZER_LIST (ctxp) = node;
2752 }
2753
2754 /* Pop the lists of initialized field. If this lists aren't empty,
2755    remember them so we can use it to create and populate the $finit$
2756    or <clinit> functions. */
2757
2758 static void
2759 java_parser_context_pop_initialized_field ()
2760 {
2761   tree stmts;
2762   tree class_type = TREE_TYPE (GET_CPC ());
2763
2764   if (CPC_INITIALIZER_LIST (ctxp))
2765     {
2766       stmts = CPC_INITIALIZER_STMT (ctxp);
2767       CPC_INITIALIZER_LIST (ctxp) = TREE_CHAIN (CPC_INITIALIZER_LIST (ctxp));
2768       if (stmts && !java_error_count)
2769         TYPE_FINIT_STMT_LIST (class_type) = reorder_static_initialized (stmts);
2770     }
2771
2772   if (CPC_STATIC_INITIALIZER_LIST (ctxp))
2773     {
2774       stmts = CPC_STATIC_INITIALIZER_STMT (ctxp);
2775       CPC_STATIC_INITIALIZER_LIST (ctxp) = 
2776         TREE_CHAIN (CPC_STATIC_INITIALIZER_LIST (ctxp));
2777       /* Keep initialization in order to enforce 8.5 */
2778       if (stmts && !java_error_count)
2779         TYPE_CLINIT_STMT_LIST (class_type) = nreverse (stmts);
2780     }
2781
2782   /* JDK 1.1 instance initializers */
2783   if (CPC_INSTANCE_INITIALIZER_LIST (ctxp))
2784     {
2785       stmts = CPC_INSTANCE_INITIALIZER_STMT (ctxp);
2786       CPC_INSTANCE_INITIALIZER_LIST (ctxp) = 
2787         TREE_CHAIN (CPC_INSTANCE_INITIALIZER_LIST (ctxp));
2788       if (stmts && !java_error_count)
2789         TYPE_II_STMT_LIST (class_type) = nreverse (stmts);
2790     }
2791 }
2792
2793 static tree
2794 reorder_static_initialized (list)
2795      tree list;
2796 {
2797   /* We have to keep things in order. The alias initializer have to
2798      come first, then the initialized regular field, in reverse to
2799      keep them in lexical order. */
2800   tree marker, previous = NULL_TREE;
2801   for (marker = list; marker; previous = marker, marker = TREE_CHAIN (marker))
2802     if (TREE_CODE (marker) == TREE_LIST 
2803         && !TREE_VALUE (marker) && !TREE_PURPOSE (marker))
2804       break;
2805   
2806   /* No static initialized, the list is fine as is */
2807   if (!previous)
2808     list = TREE_CHAIN (marker);
2809
2810   /* No marker? reverse the whole list */
2811   else if (!marker)
2812     list = nreverse (list);
2813
2814   /* Otherwise, reverse what's after the marker and the new reordered
2815      sublist will replace the marker. */
2816   else
2817     {
2818       TREE_CHAIN (previous) = NULL_TREE;
2819       list = nreverse (list);
2820       list = chainon (TREE_CHAIN (marker), list);
2821     }
2822   return list;
2823 }
2824
2825 /* Helper functions to dump the parser context stack.  */
2826
2827 #define TAB_CONTEXT(C) \
2828   {int i; for (i = 0; i < (C); i++) fputc (' ', stderr);}
2829
2830 static void
2831 java_debug_context_do (tab)
2832      int tab;
2833 {
2834   struct parser_ctxt *copy = ctxp;
2835   while (copy)
2836     {
2837       TAB_CONTEXT (tab);
2838       fprintf (stderr, "ctxt: 0x%0lX\n", (unsigned long)copy);
2839       TAB_CONTEXT (tab);
2840       fprintf (stderr, "filename: %s\n", copy->filename);
2841       TAB_CONTEXT (tab);
2842       fprintf (stderr, "lineno: %d\n", copy->lineno);
2843       TAB_CONTEXT (tab);
2844       fprintf (stderr, "package: %s\n",
2845                (copy->package ? 
2846                 IDENTIFIER_POINTER (copy->package) : "<none>"));
2847       TAB_CONTEXT (tab);
2848       fprintf (stderr, "context for saving: %d\n", copy->saved_data_ctx);
2849       TAB_CONTEXT (tab);
2850       fprintf (stderr, "saved data: %d\n", copy->saved_data);
2851       copy = copy->next;
2852       tab += 2;
2853     }
2854 }
2855
2856 /* Dump the stacked up parser contexts. Intended to be called from a
2857    debugger.  */
2858
2859 void
2860 java_debug_context ()
2861 {
2862   java_debug_context_do (0);
2863 }
2864
2865 \f
2866
2867 /* Flag for the error report routine to issue the error the first time
2868    it's called (overriding the default behavior which is to drop the
2869    first invocation and honor the second one, taking advantage of a
2870    richer context.  */
2871 static int force_error = 0;
2872
2873 /* Reporting an constructor invocation error.  */
2874 static void
2875 parse_ctor_invocation_error ()
2876 {
2877   if (DECL_CONSTRUCTOR_P (current_function_decl))
2878     yyerror ("Constructor invocation must be first thing in a constructor"); 
2879   else
2880     yyerror ("Only constructors can invoke constructors");
2881 }
2882
2883 /* Reporting JDK1.1 features not implemented.  */
2884
2885 static tree
2886 parse_jdk1_1_error (msg)
2887     const char *msg;
2888 {
2889   sorry (": `%s' JDK1.1(TM) feature", msg);
2890   java_error_count++;
2891   return empty_stmt_node;
2892 }
2893
2894 static int do_warning = 0;
2895
2896 void
2897 yyerror (msg)
2898      const char *msg;
2899 {
2900   static java_lc elc;
2901   static int  prev_lineno;
2902   static const char *prev_msg;
2903
2904   int save_lineno;
2905   char *remainder, *code_from_source;
2906   extern struct obstack temporary_obstack;
2907   
2908   if (!force_error && prev_lineno == lineno)
2909     return;
2910
2911   /* Save current error location but report latter, when the context is
2912      richer.  */
2913   if (ctxp->java_error_flag == 0)
2914     {
2915       ctxp->java_error_flag = 1;
2916       elc = ctxp->elc;
2917       /* Do something to use the previous line if we're reaching the
2918          end of the file... */
2919 #ifdef VERBOSE_SKELETON
2920       printf ("* Error detected (%s)\n", (msg ? msg : "(null)"));
2921 #endif
2922       return;
2923     }
2924
2925   /* Ignore duplicate message on the same line. BTW, this is dubious. FIXME */
2926   if (!force_error && msg == prev_msg && prev_lineno == elc.line)
2927     return;
2928
2929   ctxp->java_error_flag = 0;
2930   if (do_warning)
2931     java_warning_count++;
2932   else
2933     java_error_count++;
2934   
2935   if (elc.col == 0 && msg && msg[1] == ';')
2936     {
2937       elc.col  = ctxp->p_line->char_col-1;
2938       elc.line = ctxp->p_line->lineno;
2939     }
2940
2941   save_lineno = lineno;
2942   prev_lineno = lineno = elc.line;
2943   prev_msg = msg;
2944
2945   code_from_source = java_get_line_col (ctxp->filename, elc.line, elc.col);
2946   obstack_grow0 (&temporary_obstack, 
2947                  code_from_source, strlen (code_from_source));
2948   remainder = obstack_finish (&temporary_obstack);
2949   if (do_warning)
2950     warning ("%s.\n%s", msg, remainder);
2951   else
2952     error ("%s.\n%s", msg, remainder);
2953
2954   /* This allow us to cheaply avoid an extra 'Invalid expression
2955      statement' error report when errors have been already reported on
2956      the same line. This occurs when we report an error but don't have
2957      a synchronization point other than ';', which
2958      expression_statement is the only one to take care of.  */
2959   ctxp->prevent_ese = lineno = save_lineno;
2960 }
2961
2962 static void
2963 issue_warning_error_from_context (cl, msg, ap)
2964      tree cl;
2965      const char *msg;
2966      va_list ap;
2967 {
2968   char *saved, *saved_input_filename;
2969   char buffer [4096];
2970   vsprintf (buffer, msg, ap);
2971   force_error = 1;
2972
2973   ctxp->elc.line = EXPR_WFL_LINENO (cl);
2974   ctxp->elc.col  = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 : 
2975                     (EXPR_WFL_COLNO (cl) == 0xffe ? -2 : EXPR_WFL_COLNO (cl)));
2976
2977   /* We have a CL, that's a good reason for using it if it contains data */
2978   saved = ctxp->filename;
2979   if (TREE_CODE (cl) == EXPR_WITH_FILE_LOCATION && EXPR_WFL_FILENAME_NODE (cl))
2980     ctxp->filename = EXPR_WFL_FILENAME (cl);
2981   saved_input_filename = input_filename;
2982   input_filename = ctxp->filename;
2983   java_error (NULL);
2984   java_error (buffer);
2985   ctxp->filename = saved;
2986   input_filename = saved_input_filename;
2987   force_error = 0;
2988 }
2989
2990 /* Issue an error message at a current source line CL */
2991
2992 void
2993 parse_error_context VPARAMS ((tree cl, const char *msg, ...))
2994 {
2995 #ifndef ANSI_PROTOTYPES
2996   tree cl;
2997   const char *msg;
2998 #endif
2999   va_list ap;
3000
3001   VA_START (ap, msg);
3002 #ifndef ANSI_PROTOTYPES
3003   cl = va_arg (ap, tree);
3004   msg = va_arg (ap, const char *);
3005 #endif
3006   issue_warning_error_from_context (cl, msg, ap);
3007   va_end (ap);
3008 }
3009
3010 /* Issue a warning at a current source line CL */
3011
3012 static void
3013 parse_warning_context VPARAMS ((tree cl, const char *msg, ...))
3014 {
3015 #ifndef ANSI_PROTOTYPES
3016   tree cl;
3017   const char *msg;
3018 #endif
3019   va_list ap;
3020
3021   VA_START (ap, msg);
3022 #ifndef ANSI_PROTOTYPES
3023   cl = va_arg (ap, tree);
3024   msg = va_arg (ap, const char *);
3025 #endif
3026
3027   force_error = do_warning = 1;
3028   issue_warning_error_from_context (cl, msg, ap);
3029   do_warning = force_error = 0;
3030   va_end (ap);
3031 }
3032
3033 static tree
3034 find_expr_with_wfl (node)
3035      tree node;
3036 {
3037   while (node)
3038     {
3039       char code;
3040       tree to_return;
3041
3042       switch (TREE_CODE (node))
3043         {
3044         case BLOCK:
3045           node = BLOCK_EXPR_BODY (node);
3046           continue;
3047
3048         case COMPOUND_EXPR:
3049           to_return = find_expr_with_wfl (TREE_OPERAND (node, 0));
3050           if (to_return)
3051             return to_return;
3052           node = TREE_OPERAND (node, 1);
3053           continue;
3054
3055         case LOOP_EXPR:
3056           node = TREE_OPERAND (node, 0);
3057           continue;
3058           
3059         case LABELED_BLOCK_EXPR:
3060           node = TREE_OPERAND (node, 1);
3061           continue;
3062
3063         default:
3064           code = TREE_CODE_CLASS (TREE_CODE (node));
3065           if (((code == '1') || (code == '2') || (code == 'e'))
3066               && EXPR_WFL_LINECOL (node))
3067             return node;
3068           return NULL_TREE;
3069         }
3070     }
3071   return NULL_TREE;
3072 }
3073
3074 /* Issue a missing return statement error. Uses METHOD to figure the
3075    last line of the method the error occurs in.  */
3076
3077 static void
3078 missing_return_error (method)
3079      tree method;
3080 {
3081   EXPR_WFL_SET_LINECOL (wfl_operator, DECL_SOURCE_LINE_LAST (method), -2);
3082   parse_error_context (wfl_operator, "Missing return statement");
3083 }
3084
3085 /* Issue an unreachable statement error. From NODE, find the next
3086    statement to report appropriately.  */
3087 static void
3088 unreachable_stmt_error (node)
3089      tree node;
3090 {
3091   /* Browse node to find the next expression node that has a WFL. Use
3092      the location to report the error */
3093   if (TREE_CODE (node) == COMPOUND_EXPR)
3094     node = find_expr_with_wfl (TREE_OPERAND (node, 1));
3095   else
3096     node = find_expr_with_wfl (node);
3097
3098   if (node)
3099     {
3100       EXPR_WFL_SET_LINECOL (wfl_operator, EXPR_WFL_LINENO (node), -2);
3101       parse_error_context (wfl_operator, "Unreachable statement");
3102     }
3103   else
3104     fatal ("Can't get valid statement - unreachable_stmt_error");
3105 }
3106
3107 int
3108 java_report_errors ()
3109 {
3110   if (java_error_count)
3111     fprintf (stderr, "%d error%s", 
3112              java_error_count, (java_error_count == 1 ? "" : "s"));
3113   if (java_warning_count)
3114     fprintf (stderr, "%s%d warning%s", (java_error_count ? ", " : ""),
3115              java_warning_count, (java_warning_count == 1 ? "" : "s"));
3116   if (java_error_count || java_warning_count)
3117     putc ('\n', stderr);
3118   return java_error_count;
3119 }
3120
3121 static char *
3122 java_accstring_lookup (flags)
3123      int flags;
3124 {
3125   static char buffer [80];
3126 #define COPY_RETURN(S) {strcpy (buffer, S); return buffer;}
3127
3128   /* Access modifier looked-up first for easier report on forbidden
3129      access. */
3130   if (flags & ACC_PUBLIC) COPY_RETURN ("public");
3131   if (flags & ACC_PRIVATE) COPY_RETURN ("private");
3132   if (flags & ACC_PROTECTED) COPY_RETURN ("protected");
3133   if (flags & ACC_STATIC) COPY_RETURN ("static");
3134   if (flags & ACC_FINAL) COPY_RETURN ("final");
3135   if (flags & ACC_SYNCHRONIZED) COPY_RETURN ("synchronized");
3136   if (flags & ACC_VOLATILE) COPY_RETURN ("volatile");
3137   if (flags & ACC_TRANSIENT) COPY_RETURN ("transient");
3138   if (flags & ACC_NATIVE) COPY_RETURN ("native");
3139   if (flags & ACC_INTERFACE) COPY_RETURN ("interface");
3140   if (flags & ACC_ABSTRACT) COPY_RETURN ("abstract");
3141
3142   buffer [0] = '\0';
3143   return buffer;
3144 #undef COPY_RETURN
3145 }
3146
3147 /* Issuing error messages upon redefinition of classes, interfaces or
3148    variables. */
3149
3150 static void
3151 classitf_redefinition_error (context, id, decl, cl)
3152      const char *context;
3153      tree id, decl, cl;
3154 {
3155   parse_error_context (cl, "%s `%s' already defined in %s:%d", 
3156                        context, IDENTIFIER_POINTER (id), 
3157                        DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
3158   /* Here we should point out where its redefined. It's a unicode. FIXME */
3159 }
3160
3161 static void
3162 variable_redefinition_error (context, name, type, line)
3163      tree context, name, type;
3164      int line;
3165 {
3166   const char *type_name;
3167
3168   /* Figure a proper name for type. We might haven't resolved it */
3169   if (TREE_CODE (type) == POINTER_TYPE && !TREE_TYPE (type))
3170     type_name = IDENTIFIER_POINTER (TYPE_NAME (type));
3171   else
3172     type_name = lang_printable_name (type, 0);
3173
3174   parse_error_context (context,
3175                        "Variable `%s' is already defined in this method and was declared `%s %s' at line %d", 
3176                        IDENTIFIER_POINTER (name),
3177                        type_name, IDENTIFIER_POINTER (name), line);
3178 }
3179
3180 static tree
3181 build_array_from_name (type, type_wfl, name, ret_name)
3182      tree type, type_wfl, name, *ret_name;
3183 {
3184   int more_dims = 0;
3185   const char *string;
3186
3187   /* Eventually get more dims */
3188   string = IDENTIFIER_POINTER (name);
3189   while (string [more_dims] == '[')
3190     more_dims++;
3191   
3192   /* If we have, then craft a new type for this variable */
3193   if (more_dims)
3194     {
3195       name = get_identifier (&string [more_dims]);
3196
3197       /* If we have a pointer, use its type */
3198       if (TREE_CODE (type) == POINTER_TYPE)
3199         type = TREE_TYPE (type);
3200
3201       /* Building the first dimension of a primitive type uses this
3202          function */
3203       if (JPRIMITIVE_TYPE_P (type))
3204         {
3205           type = build_java_array_type (type, -1);
3206           CLASS_LOADED_P (type) = 1;
3207           more_dims--;
3208         }
3209       /* Otherwise, if we have a WFL for this type, use it (the type
3210          is already an array on an unresolved type, and we just keep
3211          on adding dimensions) */
3212       else if (type_wfl)
3213         type = type_wfl;
3214
3215       /* Add all the dimensions */
3216       while (more_dims--)
3217         type = build_unresolved_array_type (type);
3218
3219       /* The type may have been incomplete in the first place */
3220       if (type_wfl)
3221         type = obtain_incomplete_type (type);
3222     }
3223
3224   if (ret_name)
3225     *ret_name = name;
3226   return type;
3227 }
3228
3229 /* Build something that the type identifier resolver will identify as
3230    being an array to an unresolved type. TYPE_WFL is a WFL on a
3231    identifier. */
3232
3233 static tree
3234 build_unresolved_array_type (type_or_wfl)
3235      tree type_or_wfl;
3236 {
3237   const char *ptr;
3238
3239   /* TYPE_OR_WFL might be an array on a resolved type. In this case,
3240      just create a array type */
3241   if (TREE_CODE (type_or_wfl) == RECORD_TYPE)
3242     {
3243       tree type = build_java_array_type (type_or_wfl, -1);
3244       CLASS_LOADED_P (type) = CLASS_LOADED_P (type_or_wfl);
3245       return type;
3246     }
3247
3248   obstack_1grow (&temporary_obstack, '[');
3249   obstack_grow0 (&temporary_obstack,
3250                  IDENTIFIER_POINTER (EXPR_WFL_NODE (type_or_wfl)),
3251                  IDENTIFIER_LENGTH (EXPR_WFL_NODE (type_or_wfl)));
3252   ptr = obstack_finish (&temporary_obstack);
3253   return build_expr_wfl (get_identifier (ptr),
3254                          EXPR_WFL_FILENAME (type_or_wfl),
3255                          EXPR_WFL_LINENO (type_or_wfl),
3256                          EXPR_WFL_COLNO (type_or_wfl));
3257 }
3258
3259 static void
3260 parser_add_interface (class_decl, interface_decl, wfl)
3261      tree class_decl, interface_decl, wfl;
3262 {
3263   if (maybe_add_interface (TREE_TYPE (class_decl), TREE_TYPE (interface_decl)))
3264     parse_error_context (wfl, "Interface `%s' repeated",
3265                          IDENTIFIER_POINTER (DECL_NAME (interface_decl)));
3266 }
3267
3268 /* Bulk of common class/interface checks. Return 1 if an error was
3269    encountered. TAG is 0 for a class, 1 for an interface.  */
3270
3271 static int
3272 check_class_interface_creation (is_interface, flags, raw_name, qualified_name, decl, cl)
3273      int is_interface, flags;
3274      tree raw_name, qualified_name, decl, cl;
3275 {
3276   tree node;
3277   int sca = 0;                  /* Static class allowed */
3278   int icaf = 0;                 /* Inner class allowed flags */
3279   int uaaf = CLASS_MODIFIERS;   /* Usually allowed access flags */
3280
3281   if (!quiet_flag)
3282     fprintf (stderr, " %s%s %s", 
3283              (CPC_INNER_P () ? "inner" : ""),
3284              (is_interface ? "interface" : "class"), 
3285              IDENTIFIER_POINTER (qualified_name));
3286
3287   /* Scope of an interface/class type name:
3288        - Can't be imported by a single type import
3289        - Can't already exists in the package */
3290   if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (raw_name)
3291       && (node = find_name_in_single_imports (raw_name)))
3292     {
3293       parse_error_context 
3294         (cl, "%s name `%s' clashes with imported type `%s'",
3295          (is_interface ? "Interface" : "Class"),
3296          IDENTIFIER_POINTER (raw_name), IDENTIFIER_POINTER (node));
3297       return 1;
3298     }
3299   if (decl && CLASS_COMPLETE_P (decl))
3300     {
3301       classitf_redefinition_error ((is_interface ? "Interface" : "Class"), 
3302                                    qualified_name, decl, cl);
3303       return 1;
3304     }
3305
3306   if (check_inner_class_redefinition (raw_name, cl))
3307     return 1;
3308
3309   /* If public, file name should match class/interface name, except
3310      when dealing with an inner class */
3311   if (!CPC_INNER_P () && (flags & ACC_PUBLIC ))
3312     {
3313       const char *f;
3314
3315       /* Contains OS dependent assumption on path separator. FIXME */
3316       for (f = &input_filename [strlen (input_filename)]; 
3317            f != input_filename && f[0] != '/' && f[0] != DIR_SEPARATOR;
3318            f--)
3319         ;
3320       if (f[0] == '/' || f[0] == DIR_SEPARATOR)
3321         f++;
3322       if (strncmp (IDENTIFIER_POINTER (raw_name), 
3323                    f , IDENTIFIER_LENGTH (raw_name)) ||
3324           f [IDENTIFIER_LENGTH (raw_name)] != '.')
3325         parse_error_context
3326           (cl, "Public %s `%s' must be defined in a file called `%s.java'", 
3327                              (is_interface ? "interface" : "class"),
3328                              IDENTIFIER_POINTER (qualified_name),
3329                              IDENTIFIER_POINTER (raw_name));
3330     }
3331
3332   /* Static classes can be declared only in top level classes. Note:
3333      once static, a inner class is a top level class. */
3334   if (flags & ACC_STATIC)
3335     {
3336       /* Catch the specific error of declaring an class inner class
3337          with no toplevel enclosing class. Prevent check_modifiers from
3338          complaining a second time */
3339       if (CPC_INNER_P () && !TOPLEVEL_CLASS_DECL_P (GET_CPC()))
3340         {
3341           parse_error_context (cl, "Inner class `%s' can't be static. Static classes can only occur in interfaces and top-level classes", 
3342                                IDENTIFIER_POINTER (qualified_name));
3343           sca = ACC_STATIC;
3344         }
3345       /* Else, in the context of a top-level class declaration, let
3346          `check_modifiers' do its job, otherwise, give it a go */
3347       else
3348         sca = (GET_CPC_LIST () ? ACC_STATIC : 0);
3349     }
3350
3351   /* Inner classes can be declared private or protected
3352      within their enclosing classes. */
3353   if (CPC_INNER_P ())
3354     {
3355       /* A class which is local to a block can't be public, private,
3356          protected or static. But it is created final, so allow this
3357          one. */
3358       if (current_function_decl)
3359         icaf = sca = uaaf = ACC_FINAL;
3360       else
3361         {
3362           check_modifiers_consistency (flags);
3363           icaf = ACC_PRIVATE|ACC_PROTECTED;
3364         }
3365     }
3366
3367   if (is_interface) 
3368     {
3369       if (CPC_INNER_P ())
3370         uaaf = INTERFACE_INNER_MODIFIERS;
3371       else
3372         uaaf = INTERFACE_MODIFIERS;
3373       
3374       check_modifiers ("Illegal modifier `%s' for interface declaration", 
3375                        flags, uaaf);
3376     }
3377   else
3378     check_modifiers ((current_function_decl ?
3379                       "Illegal modifier `%s' for local class declaration" :
3380                       "Illegal modifier `%s' for class declaration"),
3381                      flags, uaaf|sca|icaf);
3382   return 0;
3383 }
3384
3385 static void
3386 make_nested_class_name (cpc_list)
3387      tree cpc_list;
3388 {
3389   tree name;
3390
3391   if (!cpc_list)
3392     return;
3393   else
3394     make_nested_class_name (TREE_CHAIN (cpc_list));
3395
3396   /* Pick the qualified name when dealing with the first upmost
3397      enclosing class */
3398   name = (TREE_CHAIN (cpc_list) ? 
3399           TREE_PURPOSE (cpc_list) : DECL_NAME (TREE_VALUE (cpc_list)));
3400   obstack_grow (&temporary_obstack,
3401                 IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name));
3402   /* Why is NO_DOLLAR_IN_LABEL defined? */
3403 #if 0
3404 #ifdef NO_DOLLAR_IN_LABEL
3405   fatal ("make_nested_class_name: Can't use '$' as a separator "
3406          "for inner classes");
3407 #endif
3408 #endif
3409   obstack_1grow (&temporary_obstack, '$');
3410 }
3411
3412 /* Can't redefine a class already defined in an earlier scope. */
3413
3414 static int
3415 check_inner_class_redefinition (raw_name, cl)
3416      tree raw_name, cl;
3417 {
3418   tree scope_list;
3419
3420   for (scope_list = GET_CPC_LIST (); scope_list; 
3421        scope_list = GET_NEXT_ENCLOSING_CPC (scope_list))
3422     if (raw_name == GET_CPC_UN_NODE (scope_list))
3423       {
3424         parse_error_context 
3425           (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",
3426            IDENTIFIER_POINTER (raw_name));
3427         return 1;
3428       }
3429   return 0;
3430 }
3431
3432 static tree
3433 find_as_inner_class (enclosing, name, cl)
3434      tree enclosing, name, cl;
3435 {
3436   tree qual, to_return;
3437   if (!enclosing)
3438     return NULL_TREE;
3439
3440   name = TYPE_NAME (name);
3441
3442   /* First search: within the scope of `enclosing', search for name */
3443   if (QUALIFIED_P (name) && cl && EXPR_WFL_NODE (cl) == name)
3444     qual = EXPR_WFL_QUALIFICATION (cl);
3445   else if (cl)
3446     qual = build_tree_list (cl, NULL_TREE);
3447   else
3448     qual = build_tree_list (build_expr_wfl (name, NULL, 0, 0), NULL_TREE);
3449   
3450   if ((to_return = find_as_inner_class_do (qual, enclosing)))
3451     return to_return;
3452
3453   /* We're dealing with a qualified name. Try to resolve thing until
3454      we get something that is an enclosing class. */
3455   if (QUALIFIED_P (name) && cl && EXPR_WFL_NODE (cl) == name)
3456     {
3457       tree acc = NULL_TREE, decl = NULL_TREE, ptr;
3458
3459       for(qual = EXPR_WFL_QUALIFICATION (cl); qual && !decl; 
3460           qual = TREE_CHAIN (qual))
3461         {
3462           acc = merge_qualified_name (acc, 
3463                                       EXPR_WFL_NODE (TREE_PURPOSE (qual)));
3464           BUILD_PTR_FROM_NAME (ptr, acc);
3465           decl = do_resolve_class (NULL_TREE, ptr, NULL_TREE, cl);
3466         }
3467
3468       /* A NULL qual and a decl means that the search ended
3469          successfully?!? We have to do something then. FIXME */
3470       
3471       if (decl)
3472         enclosing = decl;
3473       else
3474         qual = EXPR_WFL_QUALIFICATION (cl);
3475     }
3476   /* Otherwise, create a qual for the other part of the resolution. */
3477   else
3478     qual = build_tree_list (build_expr_wfl (name, NULL, 0, 0), NULL_TREE);
3479
3480   return find_as_inner_class_do (qual, enclosing);
3481 }
3482
3483 /* We go inside the list of sub classes and try to find a way
3484    through. */
3485
3486 static tree
3487 find_as_inner_class_do (qual, enclosing)
3488      tree qual, enclosing;
3489 {
3490   if (!qual)
3491     return NULL_TREE;
3492
3493   for (; qual && enclosing; qual = TREE_CHAIN (qual))
3494     {
3495       tree name_to_match = EXPR_WFL_NODE (TREE_PURPOSE (qual));
3496       tree next_enclosing = NULL_TREE;
3497       tree inner_list;
3498
3499       for (inner_list = DECL_INNER_CLASS_LIST (enclosing);
3500            inner_list; inner_list = TREE_CHAIN (inner_list))
3501         {
3502           if (TREE_VALUE (inner_list) == name_to_match)
3503             {
3504               next_enclosing = TREE_PURPOSE (inner_list);
3505               break;
3506             }
3507         }
3508       enclosing = next_enclosing;
3509     }
3510
3511   return (!qual && enclosing ? enclosing : NULL_TREE);
3512 }
3513
3514 /* Reach all inner classes and tie their unqualified name to a
3515    DECL. */
3516
3517 static void
3518 set_nested_class_simple_name_value (outer, set)
3519      tree outer;
3520      int set;
3521 {
3522   tree l;
3523
3524   for (l = DECL_INNER_CLASS_LIST (outer); l; l = TREE_CHAIN (l))
3525     IDENTIFIER_GLOBAL_VALUE (TREE_VALUE (l)) = (set ? 
3526                                                 TREE_PURPOSE (l) : NULL_TREE);
3527 }
3528
3529 static void
3530 link_nested_class_to_enclosing ()
3531 {
3532   if (GET_ENCLOSING_CPC ())
3533     {
3534       tree enclosing = GET_ENCLOSING_CPC_CONTEXT ();
3535       DECL_INNER_CLASS_LIST (enclosing) = 
3536         tree_cons (GET_CPC (), GET_CPC_UN (),
3537                    DECL_INNER_CLASS_LIST (enclosing));
3538       enclosing = enclosing;
3539     }
3540 }
3541
3542 static tree
3543 maybe_make_nested_class_name (name)
3544      tree name;
3545 {
3546   tree id = NULL_TREE;
3547
3548   if (CPC_INNER_P ())
3549     {
3550       make_nested_class_name (GET_CPC_LIST ());
3551       obstack_grow0 (&temporary_obstack,
3552                      IDENTIFIER_POINTER (name), 
3553                      IDENTIFIER_LENGTH (name));
3554       id = get_identifier (obstack_finish (&temporary_obstack));
3555       if (ctxp->package)
3556         QUALIFIED_P (id) = 1;
3557     }
3558   return id;
3559 }
3560
3561 /* If DECL is NULL, create and push a new DECL, record the current
3562    line CL and do other maintenance things.  */
3563
3564 static tree
3565 maybe_create_class_interface_decl (decl, raw_name, qualified_name, cl)
3566      tree decl, raw_name, qualified_name, cl;
3567 {
3568   if (!decl)
3569     decl = push_class (make_class (), qualified_name);
3570
3571   /* Take care of the file and line business */
3572   DECL_SOURCE_FILE (decl) = EXPR_WFL_FILENAME (cl);
3573   /* If we're emiting xrefs, store the line/col number information */
3574   if (flag_emit_xref)
3575     DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (cl);
3576   else
3577     DECL_SOURCE_LINE (decl) = EXPR_WFL_LINENO (cl);
3578   CLASS_FROM_SOURCE_P (TREE_TYPE (decl)) = 1;
3579   CLASS_FROM_CURRENTLY_COMPILED_SOURCE_P (TREE_TYPE (decl)) =
3580     IS_A_COMMAND_LINE_FILENAME_P (EXPR_WFL_FILENAME_NODE (cl));
3581
3582   PUSH_CPC (decl, raw_name);
3583   DECL_CONTEXT (decl) = GET_ENCLOSING_CPC_CONTEXT ();
3584
3585   /* Link the declaration to the already seen ones */
3586   TREE_CHAIN (decl) = ctxp->class_list;
3587   ctxp->class_list = decl;
3588
3589   /* Create a new nodes in the global lists */
3590   ctxp->gclass_list = tree_cons (NULL_TREE, decl, ctxp->gclass_list);
3591   all_class_list = tree_cons (NULL_TREE, decl, all_class_list);
3592
3593   /* Install a new dependency list element */
3594   create_jdep_list (ctxp);
3595
3596   SOURCE_FRONTEND_DEBUG (("Defining class/interface %s", 
3597                           IDENTIFIER_POINTER (qualified_name)));
3598   return decl;
3599 }
3600
3601 static void
3602 add_superinterfaces (decl, interface_list)
3603      tree decl, interface_list;
3604 {
3605   tree node;
3606   /* Superinterface(s): if present and defined, parser_check_super_interface ()
3607      takes care of ensuring that:
3608        - This is an accessible interface type,
3609        - Circularity detection.
3610    parser_add_interface is then called. If present but not defined,
3611    the check operation is delayed until the super interface gets
3612    defined.  */
3613   for (node = interface_list; node; node = TREE_CHAIN (node))
3614     {
3615       tree current = TREE_PURPOSE (node);
3616       tree idecl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (current));
3617       if (idecl && CLASS_LOADED_P (TREE_TYPE (idecl)))
3618         {
3619           if (!parser_check_super_interface (idecl, decl, current))
3620             parser_add_interface (decl, idecl, current);
3621         }
3622       else
3623         register_incomplete_type (JDEP_INTERFACE,
3624                                   current, decl, NULL_TREE);
3625     }
3626 }
3627
3628 /* Create an interface in pass1 and return its decl. Return the
3629    interface's decl in pass 2.  */
3630
3631 static tree
3632 create_interface (flags, id, super)
3633      int flags;
3634      tree id, super;
3635 {
3636   tree raw_name = EXPR_WFL_NODE (id);
3637   tree q_name = parser_qualified_classname (flags & ACC_STATIC, raw_name);
3638   tree decl = IDENTIFIER_CLASS_VALUE (q_name);
3639
3640   EXPR_WFL_NODE (id) = q_name;  /* Keep source location, even if refined. */
3641
3642   /* Basic checks: scope, redefinition, modifiers */ 
3643   if (check_class_interface_creation (1, flags, raw_name, q_name, decl, id))
3644     {
3645       PUSH_ERROR ();
3646       return NULL_TREE;
3647     }
3648
3649   /* Suspend the current parsing context if we're parsing an inner
3650      interface */
3651   if (CPC_INNER_P ())
3652     java_parser_context_suspend ();
3653
3654   /* Push a new context for (static) initialized upon declaration fields */
3655   java_parser_context_push_initialized_field ();
3656
3657   /* Interface modifiers check
3658        - public/abstract allowed (already done at that point)
3659        - abstract is obsolete (comes first, it's a warning, or should be)
3660        - Can't use twice the same (checked in the modifier rule) */
3661   if ((flags & ACC_ABSTRACT) && flag_redundant)
3662     parse_warning_context 
3663       (MODIFIER_WFL (ABSTRACT_TK),
3664        "Redundant use of `abstract' modifier. Interface `%s' is implicitely abstract", IDENTIFIER_POINTER (raw_name));
3665
3666   /* Create a new decl if DECL is NULL, otherwise fix it */
3667   decl = maybe_create_class_interface_decl (decl, raw_name, q_name, id);
3668
3669   /* Set super info and mark the class a complete */
3670   set_super_info (ACC_INTERFACE | flags, TREE_TYPE (decl), 
3671                   object_type_node, ctxp->interface_number);
3672   ctxp->interface_number = 0;
3673   CLASS_COMPLETE_P (decl) = 1;
3674   add_superinterfaces (decl, super);
3675
3676   return decl;
3677 }
3678
3679 /* Anonymous class counter. Will be reset to 1 every time a non
3680    anonymous class gets created. */
3681 static int anonymous_class_counter = 1;
3682
3683 /* Patch anonymous class CLASS, by either extending or implementing
3684    DEP.  */
3685
3686 static void
3687 patch_anonymous_class (type_decl, class_decl, wfl)
3688     tree type_decl, class_decl, wfl;
3689 {
3690   tree class = TREE_TYPE (class_decl);
3691   tree type =  TREE_TYPE (type_decl);
3692   tree binfo = TYPE_BINFO (class);
3693
3694   /* If it's an interface, implement it */
3695   if (CLASS_INTERFACE (type_decl))
3696     {
3697       tree s_binfo;
3698       int length;
3699
3700       if (parser_check_super_interface (type_decl, class_decl, wfl))
3701         return;
3702
3703       s_binfo = TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (class)), 0);
3704       length = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (class))+1;
3705       TYPE_BINFO_BASETYPES (class) = make_tree_vec (length);
3706       TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (class)), 0) = s_binfo;
3707       /* And add the interface */
3708       parser_add_interface (class_decl, type_decl, wfl);
3709     }
3710   /* Otherwise, it's a type we want to extend */
3711   else
3712     {
3713       if (parser_check_super (type_decl, class_decl, wfl))
3714         return;
3715       BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo), 0)) = type;
3716     }
3717 }
3718
3719 static tree
3720 create_anonymous_class (location, type_name)
3721     int location;
3722     tree type_name;
3723 {
3724   char buffer [80];
3725   tree super = NULL_TREE, itf = NULL_TREE;
3726   tree id, type_decl, class;
3727
3728   /* The unqualified name of the anonymous class. It's just a number. */
3729   sprintf (buffer, "%d", anonymous_class_counter++);
3730   id = build_wfl_node (get_identifier (buffer));
3731   EXPR_WFL_LINECOL (id) = location;
3732
3733   /* We know about the type to extend/implement. We go ahead */
3734   if ((type_decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (type_name))))
3735     {
3736       /* Create a class which either implements on extends the designated
3737          class. The class bears an innacessible name. */
3738       if (CLASS_INTERFACE (type_decl))
3739         {
3740           /* It's OK to modify it here. It's been already used and
3741              shouldn't be reused */
3742           ctxp->interface_number = 1;
3743           /* Interfaces should presented as a list of WFLs */
3744           itf = build_tree_list (type_name, NULL_TREE);
3745         }
3746       else
3747         super = type_name;
3748     }
3749
3750   class = create_class (ACC_FINAL, id, super, itf);
3751
3752   /* We didn't know anything about the stuff. We register a dependence. */
3753   if (!type_decl)
3754     register_incomplete_type (JDEP_ANONYMOUS, type_name, class, NULL_TREE);
3755
3756   ANONYMOUS_CLASS_P (TREE_TYPE (class)) = 1;
3757   return class;
3758 }
3759
3760 /* Create a class in pass1 and return its decl. Return class
3761    interface's decl in pass 2.  */
3762
3763 static tree
3764 create_class (flags, id, super, interfaces)
3765      int flags;
3766      tree id, super, interfaces;
3767 {
3768   tree raw_name = EXPR_WFL_NODE (id);
3769   tree class_id, decl;
3770   tree super_decl_type;
3771
3772   class_id = parser_qualified_classname (0, raw_name);
3773   decl = IDENTIFIER_CLASS_VALUE (class_id);
3774   EXPR_WFL_NODE (id) = class_id;
3775
3776   /* Basic check: scope, redefinition, modifiers */
3777   if (check_class_interface_creation (0, flags, raw_name, class_id, decl, id))
3778     {
3779       PUSH_ERROR ();
3780       return NULL_TREE;
3781     }
3782   
3783   /* Suspend the current parsing context if we're parsing an inner
3784      class or an anonymous class. */
3785   if (CPC_INNER_P ())
3786     java_parser_context_suspend ();
3787   /* Push a new context for (static) initialized upon declaration fields */
3788   java_parser_context_push_initialized_field ();
3789
3790   /* Class modifier check: 
3791        - Allowed modifier (already done at that point)
3792        - abstract AND final forbidden 
3793        - Public classes defined in the correct file */
3794   if ((flags & ACC_ABSTRACT) && (flags & ACC_FINAL))
3795     parse_error_context
3796       (id, "Class `%s' can't be declared both abstract and final",
3797        IDENTIFIER_POINTER (raw_name));
3798
3799   /* Create a new decl if DECL is NULL, otherwise fix it */
3800   decl = maybe_create_class_interface_decl (decl, raw_name, class_id, id);
3801
3802   /* If SUPER exists, use it, otherwise use Object */
3803   if (super)
3804     {
3805       /* Can't extend java.lang.Object */
3806       if (TREE_TYPE (IDENTIFIER_CLASS_VALUE (class_id)) == object_type_node)
3807         {
3808           parse_error_context (id, "Can't extend `java.lang.Object'");
3809           return NULL_TREE;
3810         }
3811
3812       super_decl_type = 
3813         register_incomplete_type (JDEP_SUPER, super, decl, NULL_TREE);
3814     }
3815   else if (TREE_TYPE (decl) != object_type_node)
3816     super_decl_type = object_type_node;
3817   /* We're defining java.lang.Object */
3818   else
3819     super_decl_type = NULL_TREE;
3820
3821   /* Set super info and mark the class a complete */
3822   set_super_info (flags, TREE_TYPE (decl), super_decl_type, 
3823                   ctxp->interface_number);
3824   ctxp->interface_number = 0;
3825   CLASS_COMPLETE_P (decl) = 1;
3826   add_superinterfaces (decl, interfaces);
3827
3828   /* If the class is a top level inner class, install an alias. */
3829   if (INNER_CLASS_DECL_P (decl) && CLASS_STATIC (decl))
3830     {
3831       tree alias = parser_qualified_classname (1, raw_name);
3832       IDENTIFIER_GLOBAL_VALUE (alias) = decl;
3833     }
3834
3835   /* Add the private this$<n> field, Replicate final locals still in
3836      scope as private final fields mangled like val$<local_name>.
3837      This doesn't not occur for top level (static) inner classes. */
3838   if (PURE_INNER_CLASS_DECL_P (decl))
3839     add_inner_class_fields (decl, current_function_decl);
3840
3841   /* If doing xref, store the location at which the inherited class
3842      (if any) was seen. */
3843   if (flag_emit_xref && super)
3844     DECL_INHERITED_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (super);
3845
3846   /* Eventually sets the @deprecated tag flag */
3847   CHECK_DEPRECATED (decl);
3848
3849   /* Reset the anonymous class counter when declaring non inner classes */
3850   if (!INNER_CLASS_DECL_P (decl))
3851     anonymous_class_counter = 1;
3852
3853   return decl;
3854 }
3855
3856 /* End a class declaration: register the statements used to create
3857    $finit$ and <clinit>, pop the current class and resume the prior
3858    parser context if necessary.  */
3859
3860 static void
3861 end_class_declaration (resume)
3862      int resume;
3863 {
3864   /* If an error occured, context weren't pushed and won't need to be
3865      popped by a resume. */
3866   int no_error_occured = ctxp->next && GET_CPC () != error_mark_node;
3867
3868   java_parser_context_pop_initialized_field ();
3869   POP_CPC ();
3870   if (resume && no_error_occured)
3871     java_parser_context_resume ();
3872 }
3873
3874 static void
3875 add_inner_class_fields (class_decl, fct_decl)
3876      tree class_decl;
3877      tree fct_decl;
3878 {
3879   tree block, marker, f;
3880
3881   f = add_field (TREE_TYPE (class_decl),
3882                  build_current_thisn (TREE_TYPE (class_decl)),
3883                  build_pointer_type (TREE_TYPE (DECL_CONTEXT (class_decl))), 
3884                  ACC_PRIVATE);
3885   FIELD_THISN (f) = 1;
3886
3887   if (!fct_decl)
3888     return;
3889     
3890   for (block = GET_CURRENT_BLOCK (fct_decl); 
3891        block && TREE_CODE (block) == BLOCK; block = BLOCK_SUPERCONTEXT (block))
3892     {
3893       tree decl;
3894       for (decl = BLOCK_EXPR_DECLS (block); decl; decl = TREE_CHAIN (decl))
3895         {
3896           char *name, *pname;
3897           tree wfl, init, list;
3898           
3899           /* Avoid non final arguments. */
3900           if (!LOCAL_FINAL (decl))
3901             continue;
3902           
3903           MANGLE_OUTER_LOCAL_VARIABLE_NAME (name, DECL_NAME (decl));
3904           MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_ID (pname, DECL_NAME (decl));
3905           wfl = build_wfl_node (get_identifier (name));
3906           init = build_wfl_node (get_identifier (pname));
3907           /* Build an initialization for the field: it will be
3908              initialized by a parameter added to $finit$, bearing a
3909              mangled name of the field itself (param$<n>.) The
3910              parameter is provided to $finit$ by the constructor
3911              invoking it (hence the constructor will also feature a
3912              hidden parameter, set to the value of the outer context
3913              local at the time the inner class is created.)
3914              
3915              Note: we take into account all possible locals that can
3916              be accessed by the inner class. It's actually not trivial
3917              to minimize these aliases down to the ones really
3918              used. One way to do that would be to expand all regular
3919              methods first, then $finit$ to get a picture of what's
3920              used.  It works with the exception that we would have to
3921              go back on all constructor invoked in regular methods to
3922              have their invokation reworked (to include the right amount
3923              of alias initializer parameters.)
3924
3925              The only real way around, I think, is a first pass to
3926              identify locals really used in the inner class. We leave
3927              the flag FIELD_LOCAL_ALIAS_USED around for that future
3928              use.
3929              
3930              On the other hand, it only affect local inner classes,
3931              whose constructors (and $finit$ call) will be featuring
3932              unecessary arguments. It's easy for a developper to keep
3933              this number of parameter down by using the `final'
3934              keyword only when necessary. For the time being, we can
3935              issue a warning on unecessary finals. FIXME */
3936           init = build_assignment (ASSIGN_TK, EXPR_WFL_LINECOL (wfl), 
3937                                    wfl, init);
3938
3939           /* Register the field. The TREE_LIST holding the part
3940              initialized/initializer will be marked ARG_FINAL_P so
3941              that the created field can be marked
3942              FIELD_LOCAL_ALIAS. */
3943           list = build_tree_list (wfl, init);
3944           ARG_FINAL_P (list) = 1;
3945           register_fields (ACC_PRIVATE | ACC_FINAL, TREE_TYPE (decl), list);
3946         }
3947     }
3948
3949   if (!CPC_INITIALIZER_STMT (ctxp))
3950     return;
3951
3952   /* If we ever registered an alias field, insert and marker to
3953      remeber where the list ends. The second part of the list (the one
3954      featuring initialized fields) so it can be later reversed to
3955      enforce 8.5. The marker will be removed during that operation. */
3956   marker = build_tree_list (NULL_TREE, NULL_TREE);
3957   TREE_CHAIN (marker) = CPC_INITIALIZER_STMT (ctxp);
3958   SET_CPC_INITIALIZER_STMT (ctxp, marker);
3959 }
3960
3961 /* Can't use lookup_field () since we don't want to load the class and
3962    can't set the CLASS_LOADED_P flag */
3963
3964 static tree
3965 find_field (class, name)
3966      tree class;
3967      tree name;
3968 {
3969   tree decl;
3970   for (decl = TYPE_FIELDS (class); decl; decl = TREE_CHAIN (decl))
3971     {
3972       if (DECL_NAME (decl) == name)
3973         return decl;
3974     }
3975   return NULL_TREE;
3976 }
3977
3978 /* Wrap around lookup_field that doesn't potentially upset the value
3979    of CLASS */
3980
3981 static tree
3982 lookup_field_wrapper (class, name)
3983      tree class, name;
3984 {
3985   tree type = class;
3986   tree decl;
3987   java_parser_context_save_global ();
3988   decl = lookup_field (&type, name);
3989   java_parser_context_restore_global ();
3990   return decl == error_mark_node ? NULL : decl;
3991 }
3992
3993 /* Find duplicate field within the same class declarations and report
3994    the error. Returns 1 if a duplicated field was found, 0
3995    otherwise.  */
3996
3997 static int
3998 duplicate_declaration_error_p (new_field_name, new_type, cl)
3999      tree new_field_name, new_type, cl;
4000 {
4001   /* This might be modified to work with method decl as well */
4002   tree decl = find_field (TREE_TYPE (GET_CPC ()), new_field_name);
4003   if (decl)
4004     {
4005       char *t1 = xstrdup (purify_type_name
4006                          ((TREE_CODE (new_type) == POINTER_TYPE 
4007                            && TREE_TYPE (new_type) == NULL_TREE) ?
4008                           IDENTIFIER_POINTER (TYPE_NAME (new_type)) :
4009                           lang_printable_name (new_type, 1)));
4010       /* The type may not have been completed by the time we report
4011          the error */
4012       char *t2 = xstrdup (purify_type_name
4013                          ((TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE 
4014                            && TREE_TYPE (TREE_TYPE (decl)) == NULL_TREE) ?
4015                           IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl))) :
4016                           lang_printable_name (TREE_TYPE (decl), 1)));
4017       parse_error_context 
4018         (cl , "Duplicate variable declaration: `%s %s' was `%s %s' (%s:%d)", 
4019          t1, IDENTIFIER_POINTER (new_field_name),
4020          t2, IDENTIFIER_POINTER (DECL_NAME (decl)),
4021          DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
4022       free (t1);
4023       free (t2);
4024       return 1;
4025     }
4026   return 0;
4027 }
4028
4029 /* Field registration routine. If TYPE doesn't exist, field
4030    declarations are linked to the undefined TYPE dependency list, to
4031    be later resolved in java_complete_class () */
4032
4033 static void
4034 register_fields (flags, type, variable_list)
4035      int flags;
4036      tree type, variable_list;
4037 {
4038   tree current, saved_type;
4039   tree class_type = NULL_TREE;
4040   int saved_lineno = lineno;
4041   int must_chain = 0;
4042   tree wfl = NULL_TREE;
4043
4044   if (GET_CPC ())
4045     class_type = TREE_TYPE (GET_CPC ());
4046
4047   if (!class_type || class_type == error_mark_node)
4048     return;
4049
4050   /* If we're adding fields to interfaces, those fields are public,
4051      static, final */
4052   if (CLASS_INTERFACE (TYPE_NAME (class_type)))
4053     {
4054       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (PUBLIC_TK),
4055                                  flags, ACC_PUBLIC, "interface field(s)");
4056       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (STATIC_TK),
4057                                  flags, ACC_STATIC, "interface field(s)");
4058       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (FINAL_TK),
4059                                  flags, ACC_FINAL, "interface field(s)");
4060       check_modifiers ("Illegal interface member modifier `%s'", flags,
4061                        INTERFACE_FIELD_MODIFIERS);
4062       flags |= (ACC_PUBLIC | ACC_STATIC | ACC_FINAL);
4063     }
4064
4065   /* Obtain a suitable type for resolution, if necessary */
4066   SET_TYPE_FOR_RESOLUTION (type, wfl, must_chain);
4067
4068   /* If TYPE is fully resolved and we don't have a reference, make one */
4069   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4070
4071   for (current = variable_list, saved_type = type; current; 
4072        current = TREE_CHAIN (current), type = saved_type)
4073     {
4074       tree real_type;
4075       tree field_decl;
4076       tree cl = TREE_PURPOSE (current);
4077       tree init = TREE_VALUE (current);
4078       tree current_name = EXPR_WFL_NODE (cl);
4079
4080       /* Can't declare static fields in inner classes */
4081       if ((flags & ACC_STATIC) && !TOPLEVEL_CLASS_TYPE_P (class_type)
4082           && !CLASS_INTERFACE (TYPE_NAME (class_type)))
4083         parse_error_context 
4084           (cl, "Field `%s' can't be static in innerclass `%s'. Only members of interfaces and top-level classes can be static",
4085            IDENTIFIER_POINTER (EXPR_WFL_NODE (cl)),
4086            lang_printable_name (class_type, 0));
4087
4088       /* Process NAME, as it may specify extra dimension(s) for it */
4089       type = build_array_from_name (type, wfl, current_name, &current_name);
4090
4091       /* Type adjustment. We may have just readjusted TYPE because
4092          the variable specified more dimensions. Make sure we have
4093          a reference if we can and don't have one already. Also
4094          change the name if we have an init. */
4095       if (type != saved_type)
4096         {
4097           PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4098           if (init)
4099             EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = current_name;
4100         }
4101
4102       real_type = GET_REAL_TYPE (type);
4103       /* Check for redeclarations */
4104       if (duplicate_declaration_error_p (current_name, real_type, cl))
4105         continue;
4106
4107       /* Set lineno to the line the field was found and create a
4108          declaration for it. Eventually sets the @deprecated tag flag. */
4109       if (flag_emit_xref)
4110         lineno = EXPR_WFL_LINECOL (cl);
4111       else
4112         lineno = EXPR_WFL_LINENO (cl);
4113       field_decl = add_field (class_type, current_name, real_type, flags);
4114       CHECK_DEPRECATED (field_decl);
4115
4116       /* If the couple initializer/initialized is marked ARG_FINAL_P, we
4117          mark the created field FIELD_LOCAL_ALIAS, so that we can 
4118          hide parameters to this inner class $finit$ and constructors. */
4119       if (ARG_FINAL_P (current))
4120         FIELD_LOCAL_ALIAS (field_decl) = 1;
4121       
4122       /* Check if we must chain. */
4123       if (must_chain)
4124         register_incomplete_type (JDEP_FIELD, wfl, field_decl, type);
4125           
4126       /* If we have an initialization value tied to the field */
4127       if (init)
4128         {
4129           /* The field is declared static */
4130           if (flags & ACC_STATIC)
4131             {
4132               /* We include the field and its initialization part into
4133                  a list used to generate <clinit>. After <clinit> is
4134                  walked, field initializations will be processed and
4135                  fields initialized with known constants will be taken
4136                  out of <clinit> and have their DECL_INITIAL set
4137                  appropriately. */
4138               TREE_CHAIN (init) = CPC_STATIC_INITIALIZER_STMT (ctxp);
4139               SET_CPC_STATIC_INITIALIZER_STMT (ctxp, init);
4140               if (TREE_OPERAND (init, 1) 
4141                   && TREE_CODE (TREE_OPERAND (init, 1)) == NEW_ARRAY_INIT)
4142                 TREE_STATIC (TREE_OPERAND (init, 1)) = 1;
4143             }
4144           /* A non-static field declared with an immediate initialization is
4145              to be initialized in <init>, if any.  This field is remembered
4146              to be processed at the time of the generation of <init>. */
4147           else
4148             {
4149               TREE_CHAIN (init) = CPC_INITIALIZER_STMT (ctxp);
4150               SET_CPC_INITIALIZER_STMT (ctxp, init);
4151             }
4152           MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
4153           DECL_INITIAL (field_decl) = TREE_OPERAND (init, 1);
4154         }
4155     }
4156   lineno = saved_lineno;
4157 }
4158
4159 /* Generate $finit$, using the list of initialized fields to populate
4160    its body. $finit$'s parameter(s) list is adjusted to include the
4161    one(s) used to initialized the field(s) caching outer context
4162    local(s). */
4163
4164 static tree
4165 generate_finit (class_type)
4166      tree class_type;
4167 {
4168   int count = 0;
4169   tree list = TYPE_FINIT_STMT_LIST (class_type);
4170   tree mdecl, current, parms;
4171
4172   parms = build_alias_initializer_parameter_list (AIPL_FUNCTION_CREATION, 
4173                                                   class_type, NULL_TREE, 
4174                                                   &count);
4175   CRAFTED_PARAM_LIST_FIXUP (parms);
4176   mdecl = create_artificial_method (class_type, ACC_PRIVATE, void_type_node,
4177                                     finit_identifier_node, parms);
4178   fix_method_argument_names (parms, mdecl);
4179   layout_class_method (class_type, CLASSTYPE_SUPER (class_type),
4180                        mdecl, NULL_TREE);
4181   DECL_FUNCTION_NAP (mdecl) = count;
4182   start_artificial_method_body (mdecl);
4183
4184   for (current = list; current; current = TREE_CHAIN (current))
4185     java_method_add_stmt (mdecl, 
4186                           build_debugable_stmt (EXPR_WFL_LINECOL (current), 
4187                                                 current));
4188   end_artificial_method_body (mdecl);
4189   return mdecl;
4190 }
4191
4192 static void
4193 add_instance_initializer (mdecl)
4194      tree mdecl;
4195 {
4196   tree current;
4197   tree stmt_list = TYPE_II_STMT_LIST (DECL_CONTEXT (mdecl));
4198   tree compound = NULL_TREE;
4199
4200   if (stmt_list)
4201     {
4202       for (current = stmt_list; current; current = TREE_CHAIN (current))
4203         compound = add_stmt_to_compound (compound, NULL_TREE, current);
4204
4205       java_method_add_stmt (mdecl, build1 (INSTANCE_INITIALIZERS_EXPR,
4206                                            NULL_TREE, compound));
4207     }
4208 }
4209
4210 /* Shared accros method_declarator and method_header to remember the
4211    patch stage that was reached during the declaration of the method.
4212    A method DECL is built differently is there is no patch
4213    (JDEP_NO_PATCH) or a patch (JDEP_METHOD or JDEP_METHOD_RETURN)
4214    pending on the currently defined method.  */
4215
4216 static int patch_stage;
4217
4218 /* Check the method declaration and add the method to its current
4219    class.  If the argument list is known to contain incomplete types,
4220    the method is partially added and the registration will be resume
4221    once the method arguments resolved. If TYPE is NULL, we're dealing
4222    with a constructor.  */
4223
4224 static tree
4225 method_header (flags, type, mdecl, throws)
4226      int flags;
4227      tree type, mdecl, throws;
4228 {
4229   tree meth = TREE_VALUE (mdecl);
4230   tree id = TREE_PURPOSE (mdecl);
4231   tree type_wfl = NULL_TREE;
4232   tree meth_name = NULL_TREE;
4233   tree current, orig_arg, this_class = NULL;
4234   int saved_lineno;
4235   int constructor_ok = 0, must_chain;
4236   int count;
4237   
4238   check_modifiers_consistency (flags);
4239
4240   if (GET_CPC ())
4241     this_class = TREE_TYPE (GET_CPC ());
4242
4243   if (!this_class || this_class == error_mark_node)
4244     return NULL_TREE;
4245   
4246   /* There are some forbidden modifiers for an abstract method and its
4247      class must be abstract as well.  */
4248   if (type && (flags & ACC_ABSTRACT))
4249     {
4250       ABSTRACT_CHECK (flags, ACC_PRIVATE, id, "Private");
4251       ABSTRACT_CHECK (flags, ACC_STATIC, id, "Static");
4252       ABSTRACT_CHECK (flags, ACC_FINAL, id, "Final");
4253       ABSTRACT_CHECK (flags, ACC_NATIVE, id, "Native");
4254       ABSTRACT_CHECK (flags, ACC_SYNCHRONIZED,id, "Synchronized");
4255       if (!CLASS_ABSTRACT (TYPE_NAME (this_class))
4256           && !CLASS_INTERFACE (TYPE_NAME (this_class)))
4257         parse_error_context 
4258           (id, "Class `%s' must be declared abstract to define abstract method `%s'", 
4259            IDENTIFIER_POINTER (DECL_NAME (ctxp->current_parsed_class)),
4260            IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
4261     }
4262
4263   /* Things to be checked when declaring a constructor */
4264   if (!type)
4265     {
4266       int ec = java_error_count;
4267       /* 8.6: Constructor declarations: we might be trying to define a
4268          method without specifying a return type. */
4269       if (EXPR_WFL_NODE (id) != GET_CPC_UN ())
4270         parse_error_context 
4271           (id, "Invalid method declaration, return type required");
4272       /* 8.6.3: Constructor modifiers */
4273       else
4274         {
4275           JCONSTRUCTOR_CHECK (flags, ACC_ABSTRACT, id, "abstract");
4276           JCONSTRUCTOR_CHECK (flags, ACC_STATIC, id, "static");
4277           JCONSTRUCTOR_CHECK (flags, ACC_FINAL, id, "final");
4278           JCONSTRUCTOR_CHECK (flags, ACC_NATIVE, id, "native");
4279           JCONSTRUCTOR_CHECK (flags, ACC_SYNCHRONIZED, id, "synchronized");
4280         }
4281       /* If we found error here, we don't consider it's OK to tread
4282          the method definition as a constructor, for the rest of this
4283          function */
4284       if (ec == java_error_count)
4285         constructor_ok = 1;
4286     }
4287
4288   /* Method declared within the scope of an interface are implicitly
4289      abstract and public. Conflicts with other erroneously provided
4290      modifiers are checked right after. */
4291
4292   if (CLASS_INTERFACE (TYPE_NAME (this_class)))
4293     {
4294       /* If FLAGS isn't set because of a modifier, turn the
4295          corresponding modifier WFL to NULL so we issue a warning on
4296          the obsolete use of the modifier */
4297       if (!(flags & ACC_PUBLIC))
4298         MODIFIER_WFL (PUBLIC_TK) = NULL;
4299       if (!(flags & ACC_ABSTRACT))
4300         MODIFIER_WFL (ABSTRACT_TK) = NULL;
4301       flags |= ACC_PUBLIC;
4302       flags |= ACC_ABSTRACT;
4303     }
4304
4305   /* Inner class can't declare static methods */
4306   if ((flags & ACC_STATIC) && !TOPLEVEL_CLASS_TYPE_P (this_class))
4307     {
4308       parse_error_context 
4309         (id, "Method `%s' can't be static in inner class `%s'. Only members of interfaces and top-level classes can be static",
4310          IDENTIFIER_POINTER (EXPR_WFL_NODE (id)),
4311          lang_printable_name (this_class, 0));
4312     }
4313
4314   /* Modifiers context reset moved up, so abstract method declaration
4315      modifiers can be later checked.  */
4316
4317   /* Set constructor returned type to void and method name to <init>,
4318      unless we found an error identifier the constructor (in which
4319      case we retain the original name) */
4320   if (!type)
4321     {
4322       type = void_type_node;
4323       if (constructor_ok)
4324         meth_name = init_identifier_node;
4325     }
4326   else
4327     meth_name = EXPR_WFL_NODE (id);
4328
4329   /* Do the returned type resolution and registration if necessary */
4330   SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
4331
4332   if (meth_name)
4333     type = build_array_from_name (type, type_wfl, meth_name, &meth_name);
4334   EXPR_WFL_NODE (id) = meth_name;
4335   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4336
4337   if (must_chain)
4338     {
4339       patch_stage = JDEP_METHOD_RETURN;
4340       register_incomplete_type (patch_stage, type_wfl, id, type);
4341       TREE_TYPE (meth) = GET_REAL_TYPE (type);
4342     }
4343   else
4344     TREE_TYPE (meth) = type;
4345
4346   saved_lineno = lineno;
4347   /* When defining an abstract or interface method, the curly
4348      bracket at level 1 doesn't exist because there is no function
4349      body */
4350   lineno = (ctxp->first_ccb_indent1 ? ctxp->first_ccb_indent1 : 
4351             EXPR_WFL_LINENO (id));
4352
4353   /* Remember the original argument list */
4354   orig_arg = TYPE_ARG_TYPES (meth);
4355
4356   if (patch_stage)              /* includes ret type and/or all args */
4357     {
4358       jdep *jdep;
4359       meth = add_method_1 (this_class, flags, meth_name, meth);
4360       /* Patch for the return type */
4361       if (patch_stage == JDEP_METHOD_RETURN)
4362         {
4363           jdep = CLASSD_LAST (ctxp->classd_list);
4364           JDEP_GET_PATCH (jdep) = &TREE_TYPE (TREE_TYPE (meth));
4365         }
4366       /* This is the stop JDEP. METH allows the function's signature
4367          to be computed. */
4368       register_incomplete_type (JDEP_METHOD_END, NULL_TREE, meth, NULL_TREE);
4369     }
4370   else
4371     meth = add_method (this_class, flags, meth_name, 
4372                        build_java_signature (meth));
4373
4374   /* Remember final parameters */
4375   MARK_FINAL_PARMS (meth, orig_arg);
4376
4377   /* Fix the method argument list so we have the argument name
4378      information */
4379   fix_method_argument_names (orig_arg, meth);
4380
4381   /* Register the parameter number and re-install the current line
4382      number */
4383   DECL_MAX_LOCALS (meth) = ctxp->formal_parameter_number+1;
4384   lineno = saved_lineno;
4385
4386   /* Register exception specified by the `throws' keyword for
4387      resolution and set the method decl appropriate field to the list.
4388      Note: the grammar ensures that what we get here are class
4389      types. */
4390   if (throws)
4391     {
4392       throws = nreverse (throws);
4393       for (current = throws; current; current = TREE_CHAIN (current))
4394         {
4395           register_incomplete_type (JDEP_EXCEPTION, TREE_VALUE (current),
4396                                     NULL_TREE, NULL_TREE);
4397           JDEP_GET_PATCH (CLASSD_LAST (ctxp->classd_list)) = 
4398             &TREE_VALUE (current);
4399         }
4400       DECL_FUNCTION_THROWS (meth) = throws;
4401     }
4402
4403   /* We set the DECL_NAME to ID so we can track the location where
4404      the function was declared. This allow us to report
4405      redefinition error accurately. When method are verified,
4406      DECL_NAME is reinstalled properly (using the content of the
4407      WFL node ID) (see check_method_redefinition). We don't do that
4408      when Object is being defined. Constructor <init> names will be
4409      reinstalled the same way. */
4410   if (TREE_TYPE (GET_CPC ()) != object_type_node)
4411     DECL_NAME (meth) = id;
4412
4413   /* Set the flag if we correctly processed a constructor */
4414   if (constructor_ok)
4415     {
4416       DECL_CONSTRUCTOR_P (meth) = 1;
4417       /* Compute and store the number of artificial parameters declared
4418          for this constructor */
4419       for (count = 0, current = TYPE_FIELDS (this_class); current; 
4420            current = TREE_CHAIN (current))
4421         if (FIELD_LOCAL_ALIAS (current))
4422           count++;
4423       DECL_FUNCTION_NAP (meth) = count;
4424     }
4425
4426   /* Eventually set the @deprecated tag flag */
4427   CHECK_DEPRECATED (meth);
4428
4429   /* If doing xref, store column and line number information instead
4430      of the line number only. */
4431   if (flag_emit_xref)
4432     DECL_SOURCE_LINE (meth) = EXPR_WFL_LINECOL (id);
4433
4434   return meth;
4435 }
4436
4437 static void
4438 fix_method_argument_names (orig_arg, meth)
4439     tree orig_arg, meth;
4440 {
4441   tree arg = TYPE_ARG_TYPES (TREE_TYPE (meth));
4442   if (TREE_CODE (TREE_TYPE (meth)) == METHOD_TYPE)
4443     {
4444       TREE_PURPOSE (arg) = this_identifier_node;
4445       arg = TREE_CHAIN (arg);
4446     }
4447   while (orig_arg != end_params_node)
4448     {
4449       TREE_PURPOSE (arg) = TREE_PURPOSE (orig_arg);
4450       orig_arg = TREE_CHAIN (orig_arg);
4451       arg = TREE_CHAIN (arg);
4452     }
4453 }
4454
4455 /* Complete the method declaration with METHOD_BODY.  */
4456
4457 static void
4458 finish_method_declaration (method_body)
4459      tree method_body;
4460 {
4461   int flags;
4462
4463   if (!current_function_decl)
4464     return;
4465
4466   flags = get_access_flags_from_decl (current_function_decl);
4467
4468   /* 8.4.5 Method Body */
4469   if ((flags & ACC_ABSTRACT || flags & ACC_NATIVE) && method_body)
4470     {
4471       tree wfl = DECL_NAME (current_function_decl);
4472       parse_error_context (wfl, 
4473                            "%s method `%s' can't have a body defined",
4474                            (METHOD_NATIVE (current_function_decl) ?
4475                             "Native" : "Abstract"),
4476                            IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
4477       method_body = NULL_TREE;
4478     }
4479   else if (!(flags & ACC_ABSTRACT) && !(flags & ACC_NATIVE) && !method_body)
4480     {
4481       tree wfl = DECL_NAME (current_function_decl);
4482       parse_error_context
4483         (wfl, 
4484          "Non native and non abstract method `%s' must have a body defined",
4485          IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
4486       method_body = NULL_TREE;
4487     }
4488
4489   if (flag_emit_class_files && method_body 
4490       && TREE_CODE (method_body) == NOP_EXPR 
4491       && TREE_TYPE (current_function_decl) 
4492       && TREE_TYPE (TREE_TYPE (current_function_decl)) == void_type_node)
4493     method_body = build1 (RETURN_EXPR, void_type_node, NULL);
4494     
4495   BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (current_function_decl)) = method_body;
4496   maybe_absorb_scoping_blocks ();
4497   /* Exit function's body */
4498   exit_block ();
4499   /* Merge last line of the function with first line, directly in the
4500      function decl. It will be used to emit correct debug info. */
4501   if (!flag_emit_xref)
4502     DECL_SOURCE_LINE_MERGE (current_function_decl, ctxp->last_ccb_indent1);
4503
4504   /* Since function's argument's list are shared, reset the
4505      ARG_FINAL_P parameter that might have been set on some of this
4506      function parameters. */
4507   UNMARK_FINAL_PARMS (current_function_decl);
4508   
4509   /* So we don't have an irrelevant function declaration context for
4510      the next static block we'll see. */
4511   current_function_decl = NULL_TREE;
4512 }
4513
4514 /* Build a an error message for constructor circularity errors.  */
4515
4516 static char *
4517 constructor_circularity_msg (from, to)
4518      tree from, to;
4519 {
4520   static char string [4096];
4521   char *t = xstrdup (lang_printable_name (from, 0));
4522   sprintf (string, "`%s' invokes `%s'", t, lang_printable_name (to, 0));
4523   free (t);
4524   return string;
4525 }
4526
4527 /* Verify a circular call to METH. Return 1 if an error is found, 0
4528    otherwise.  */
4529
4530 static int
4531 verify_constructor_circularity (meth, current)
4532      tree meth, current;
4533 {
4534   static tree list = NULL_TREE;
4535   tree c;
4536   for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
4537     {
4538       if (TREE_VALUE (c) == meth)
4539         {
4540           char *t;
4541           if (list)
4542             {
4543               tree liste;
4544               list = nreverse (list);
4545               for (liste = list; liste; liste = TREE_CHAIN (liste))
4546                 {
4547                   parse_error_context 
4548                     (TREE_PURPOSE (TREE_PURPOSE (liste)), "%s",
4549                      constructor_circularity_msg
4550                       (TREE_VALUE (liste), TREE_VALUE (TREE_PURPOSE (liste)))); 
4551                   java_error_count--;
4552                 }
4553             }
4554           t = xstrdup (lang_printable_name (meth, 0));
4555           parse_error_context (TREE_PURPOSE (c), 
4556                                "%s: recursive invocation of constructor `%s'",
4557                                constructor_circularity_msg (current, meth), t);
4558           free (t);
4559           list = NULL_TREE;
4560           return 1;
4561         }
4562     }
4563   for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
4564     {
4565       list = tree_cons (c, current, list);
4566       if (verify_constructor_circularity (meth, TREE_VALUE (c)))
4567         return 1;
4568       list = TREE_CHAIN (list);
4569     }
4570   return 0;
4571 }
4572
4573 /* Check modifiers that can be declared but exclusively */
4574
4575 static void
4576 check_modifiers_consistency (flags)
4577      int flags;
4578 {
4579   int acc_count = 0;
4580   tree cl = NULL_TREE;
4581
4582   THIS_MODIFIER_ONLY (flags, ACC_PUBLIC, PUBLIC_TK, acc_count, cl);
4583   THIS_MODIFIER_ONLY (flags, ACC_PRIVATE, PRIVATE_TK, acc_count, cl);
4584   THIS_MODIFIER_ONLY (flags, ACC_PROTECTED, PROTECTED_TK, acc_count, cl);
4585   if (acc_count > 1)
4586     parse_error_context
4587       (cl, "Inconsistent member declaration.  At most one of `public', `private', or `protected' may be specified");
4588
4589   acc_count = 0;
4590   cl = NULL_TREE;
4591   THIS_MODIFIER_ONLY (flags, ACC_FINAL, FINAL_TK - PUBLIC_TK,
4592                       acc_count, cl);
4593   THIS_MODIFIER_ONLY (flags, ACC_VOLATILE, VOLATILE_TK - PUBLIC_TK,
4594                       acc_count, cl);
4595   if (acc_count > 1)
4596     parse_error_context (cl,
4597                          "Inconsistent member declaration.  At most one of `final' or `volatile' may be specified");
4598 }
4599
4600 /* Check the methode header METH for abstract specifics features */
4601
4602 static void
4603 check_abstract_method_header (meth)
4604      tree meth;
4605 {
4606   int flags = get_access_flags_from_decl (meth);
4607   /* DECL_NAME might still be a WFL node */
4608   tree name = GET_METHOD_NAME (meth);
4609
4610   OBSOLETE_MODIFIER_WARNING2 (MODIFIER_WFL (ABSTRACT_TK), flags,
4611                               ACC_ABSTRACT, "abstract method",
4612                               IDENTIFIER_POINTER (name));
4613   OBSOLETE_MODIFIER_WARNING2 (MODIFIER_WFL (PUBLIC_TK), flags, 
4614                               ACC_PUBLIC, "abstract method",
4615                               IDENTIFIER_POINTER (name));
4616
4617   check_modifiers ("Illegal modifier `%s' for interface method",
4618                   flags, INTERFACE_METHOD_MODIFIERS);
4619 }
4620
4621 /* Create a FUNCTION_TYPE node and start augmenting it with the
4622    declared function arguments. Arguments type that can't be resolved
4623    are left as they are, but the returned node is marked as containing
4624    incomplete types.  */
4625
4626 static tree
4627 method_declarator (id, list)
4628      tree id, list;
4629 {
4630   tree arg_types = NULL_TREE, current, node;
4631   tree meth = make_node (FUNCTION_TYPE);
4632   jdep *jdep;
4633
4634   patch_stage = JDEP_NO_PATCH;
4635
4636   /* If we're dealing with an inner class constructor, we hide the
4637      this$<n> decl in the name field of its parameter declaration.  We
4638      also might have to hide the outer context local alias
4639      initializers. Not done when the class is a toplevel class. */
4640   if (PURE_INNER_CLASS_DECL_P (GET_CPC ()) 
4641       && EXPR_WFL_NODE (id) == GET_CPC_UN ())
4642     {
4643       tree aliases_list, type, thisn;
4644       /* First the aliases, linked to the regular parameters */
4645       aliases_list =
4646         build_alias_initializer_parameter_list (AIPL_FUNCTION_DECLARATION, 
4647                                                 TREE_TYPE (GET_CPC ()),
4648                                                 NULL_TREE, NULL);
4649       list = chainon (nreverse (aliases_list), list);
4650
4651       /* Then this$<n> */
4652       type = TREE_TYPE (DECL_CONTEXT (GET_CPC ()));
4653       thisn = build_current_thisn (TYPE_NAME (GET_CPC ()));
4654       list = tree_cons (build_wfl_node (thisn), build_pointer_type (type),
4655                         list);
4656     }
4657   
4658   for (current = list; current; current = TREE_CHAIN (current))
4659     {
4660       int must_chain = 0;
4661       tree wfl_name = TREE_PURPOSE (current);
4662       tree type = TREE_VALUE (current);
4663       tree name = EXPR_WFL_NODE (wfl_name);
4664       tree already, arg_node;
4665       tree type_wfl = NULL_TREE;
4666       tree real_type;
4667
4668       /* Obtain a suitable type for resolution, if necessary */
4669       SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
4670
4671       /* Process NAME, as it may specify extra dimension(s) for it */
4672       type = build_array_from_name (type, type_wfl, name, &name);
4673       EXPR_WFL_NODE (wfl_name) = name;
4674
4675       real_type = GET_REAL_TYPE (type);
4676       if (TREE_CODE (real_type) == RECORD_TYPE)
4677         {
4678           real_type = promote_type (real_type);
4679           if (TREE_CODE (type) == TREE_LIST)
4680             TREE_PURPOSE (type) = real_type;
4681         }
4682
4683       /* Check redefinition */
4684       for (already = arg_types; already; already = TREE_CHAIN (already))
4685         if (TREE_PURPOSE (already) == name)
4686           {
4687             parse_error_context
4688               (wfl_name, "Variable `%s' is used more than once in the argument list of method `%s'",
4689                IDENTIFIER_POINTER (name),
4690                IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
4691             break;
4692           }
4693
4694       /* If we've an incomplete argument type, we know there is a location
4695          to patch when the type get resolved, later.  */
4696       jdep = NULL;
4697       if (must_chain)
4698         {
4699           patch_stage = JDEP_METHOD;
4700           type = register_incomplete_type (patch_stage, 
4701                                            type_wfl, wfl_name, type);
4702           jdep = CLASSD_LAST (ctxp->classd_list);
4703           JDEP_MISC (jdep) = id;
4704         }
4705
4706       /* The argument node: a name and a (possibly) incomplete type.  */
4707       arg_node = build_tree_list (name, real_type);
4708       /* Remeber arguments declared final. */
4709       ARG_FINAL_P (arg_node) = ARG_FINAL_P (current);
4710       
4711       if (jdep)
4712         JDEP_GET_PATCH (jdep) = &TREE_VALUE (arg_node);
4713       TREE_CHAIN (arg_node) = arg_types;
4714       arg_types = arg_node;
4715     }
4716   TYPE_ARG_TYPES (meth) = chainon (nreverse (arg_types), end_params_node);
4717   node = build_tree_list (id, meth);
4718   return node;
4719 }
4720
4721 static int
4722 unresolved_type_p (wfl, returned)
4723      tree wfl;
4724      tree *returned;
4725      
4726 {
4727   if (TREE_CODE (wfl) == EXPR_WITH_FILE_LOCATION)
4728     {
4729       if (returned)
4730         {
4731           tree decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (wfl));
4732           if (decl && current_class && (decl == TYPE_NAME (current_class)))
4733             *returned = TREE_TYPE (decl);
4734           else if (GET_CPC_UN () == EXPR_WFL_NODE (wfl))
4735             *returned = TREE_TYPE (GET_CPC ());
4736           else
4737             *returned = NULL_TREE;
4738         }
4739       return 1;
4740     }
4741   if (returned)
4742     *returned = wfl;
4743   return 0;
4744 }
4745
4746 /* From NAME, build a qualified identifier node using the
4747    qualification from the current package definition. */
4748
4749 static tree
4750 parser_qualified_classname (is_static, name)
4751      int is_static;
4752      tree name;
4753 {
4754   tree nested_class_name;
4755
4756   if (!is_static 
4757       && (nested_class_name = maybe_make_nested_class_name (name)))
4758     return nested_class_name;
4759
4760   if (ctxp->package)
4761     return merge_qualified_name (ctxp->package, name);
4762   else 
4763     return name;
4764 }
4765
4766 /* Called once the type a interface extends is resolved. Returns 0 if
4767    everything is OK.  */
4768
4769 static int
4770 parser_check_super_interface (super_decl, this_decl, this_wfl)
4771      tree super_decl, this_decl, this_wfl;
4772 {
4773   tree super_type = TREE_TYPE (super_decl);
4774
4775   /* Has to be an interface */
4776   if (!CLASS_INTERFACE (super_decl))
4777     {
4778       parse_error_context 
4779         (this_wfl, "Can't use %s `%s' to implement/extend %s `%s'",
4780          (TYPE_ARRAY_P (super_type) ? "array" : "class"),
4781          IDENTIFIER_POINTER (DECL_NAME (super_decl)),
4782          (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (this_decl))) ? 
4783           "interface" : "class"),
4784          IDENTIFIER_POINTER (DECL_NAME (this_decl)));
4785       return 1;
4786     }
4787
4788   /* Check scope: same package OK, other package: OK if public */
4789   if (check_pkg_class_access (DECL_NAME (super_decl), lookup_cl (this_decl)))
4790     return 1;
4791
4792   SOURCE_FRONTEND_DEBUG (("Completing interface %s with %s",
4793                           IDENTIFIER_POINTER (DECL_NAME (this_decl)),
4794                           IDENTIFIER_POINTER (DECL_NAME (super_decl))));
4795   return 0;
4796 }
4797
4798 /* Makes sure that SUPER_DECL is suitable to extend THIS_DECL. Returns
4799    0 if everthing is OK.  */
4800
4801 static int
4802 parser_check_super (super_decl, this_decl, wfl)
4803      tree super_decl, this_decl, wfl;
4804 {
4805   tree super_type = TREE_TYPE (super_decl);
4806
4807   /* SUPER should be a CLASS (neither an array nor an interface) */
4808   if (TYPE_ARRAY_P (super_type) || CLASS_INTERFACE (TYPE_NAME (super_type)))
4809     {
4810       parse_error_context 
4811         (wfl, "Class `%s' can't subclass %s `%s'",
4812          IDENTIFIER_POINTER (DECL_NAME (this_decl)),
4813          (CLASS_INTERFACE (TYPE_NAME (super_type)) ? "interface" : "array"),
4814          IDENTIFIER_POINTER (DECL_NAME (super_decl)));
4815       return 1;
4816     }
4817
4818   if (CLASS_FINAL (TYPE_NAME (super_type)))
4819     {
4820       parse_error_context (wfl, "Can't subclass final classes: %s",
4821                            IDENTIFIER_POINTER (DECL_NAME (super_decl)));
4822       return 1;
4823     }
4824
4825   /* Check scope: same package OK, other package: OK if public */
4826   if (check_pkg_class_access (DECL_NAME (super_decl), wfl))
4827     return 1;
4828   
4829   SOURCE_FRONTEND_DEBUG (("Completing class %s with %s",
4830                           IDENTIFIER_POINTER (DECL_NAME (this_decl)),
4831                           IDENTIFIER_POINTER (DECL_NAME (super_decl))));
4832   return 0;
4833 }
4834
4835 /* Create a new dependency list and link it (in a LIFO manner) to the
4836    CTXP list of type dependency list.  */
4837
4838 static void
4839 create_jdep_list (ctxp)
4840      struct parser_ctxt *ctxp;
4841 {
4842   jdeplist *new = (jdeplist *)xmalloc (sizeof (jdeplist));      
4843   new->first = new->last = NULL;
4844   new->next = ctxp->classd_list;
4845   ctxp->classd_list = new;
4846 }
4847
4848 static jdeplist *
4849 reverse_jdep_list (ctxp)
4850      struct parser_ctxt *ctxp;
4851 {
4852   register jdeplist *prev = NULL, *current, *next;
4853   for (current = ctxp->classd_list; current; current = next)
4854     {
4855       next = current->next;
4856       current->next = prev;
4857       prev = current;
4858     }
4859   return prev;
4860 }
4861
4862 /* Create a fake pointer based on the ID stored in
4863    TYPE_NAME. TYPE_NAME can be a WFL or a incomplete type asking to be
4864    registered again. */
4865
4866 static tree
4867 obtain_incomplete_type (type_name)
4868      tree type_name;
4869 {
4870   tree ptr, name;
4871
4872   if (TREE_CODE (type_name) == EXPR_WITH_FILE_LOCATION)
4873     name = EXPR_WFL_NODE (type_name);
4874   else if (INCOMPLETE_TYPE_P (type_name))
4875     name = TYPE_NAME (type_name);
4876   else
4877     fatal ("invalid type name - obtain_incomplete_type");
4878
4879   for (ptr = ctxp->incomplete_class; ptr; ptr = TREE_CHAIN (ptr))
4880     if (TYPE_NAME (ptr) == name)
4881       break;
4882
4883   if (!ptr)
4884     {
4885       push_obstacks (&permanent_obstack, &permanent_obstack);
4886       BUILD_PTR_FROM_NAME (ptr, name);
4887       layout_type (ptr);
4888       pop_obstacks ();
4889       TREE_CHAIN (ptr) = ctxp->incomplete_class;
4890       ctxp->incomplete_class = ptr;
4891     }
4892
4893   return ptr;
4894 }
4895
4896 /* Register a incomplete type whose name is WFL. Reuse PTR if PTR is
4897    non NULL instead of computing a new fake type based on WFL. The new
4898    dependency is inserted in the current type dependency list, in FIFO
4899    manner.  */
4900
4901 static tree
4902 register_incomplete_type (kind, wfl, decl, ptr)
4903      int kind;
4904      tree wfl, decl, ptr;
4905 {
4906   jdep *new = (jdep *)xmalloc (sizeof (jdep));
4907
4908   if (!ptr && kind != JDEP_METHOD_END) /* JDEP_METHOD_END is a mere marker */
4909     ptr = obtain_incomplete_type (wfl);
4910
4911   JDEP_KIND (new) = kind;
4912   JDEP_DECL (new) = decl;
4913   JDEP_SOLV (new) = ptr;
4914   JDEP_WFL (new) = wfl;
4915   JDEP_CHAIN (new) = NULL;
4916   JDEP_MISC (new) = NULL_TREE;
4917   if ((kind == JDEP_SUPER || kind == JDEP_INTERFACE)
4918       && GET_ENCLOSING_CPC ())
4919     JDEP_ENCLOSING (new) = TREE_VALUE (GET_ENCLOSING_CPC ());
4920   else
4921     JDEP_ENCLOSING (new) = GET_CPC ();
4922   JDEP_GET_PATCH (new) = (tree *)NULL;
4923
4924   JDEP_INSERT (ctxp->classd_list, new);
4925
4926   return ptr;
4927 }
4928
4929 void
4930 java_check_circular_reference ()
4931 {
4932   tree current;
4933   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
4934     {
4935       tree type = TREE_TYPE (current);
4936       if (CLASS_INTERFACE (current))
4937         {
4938           /* Check all interfaces this class extends */
4939           tree basetype_vec = TYPE_BINFO_BASETYPES (type);
4940           int n, i;
4941
4942           if (!basetype_vec)
4943             return;
4944           n = TREE_VEC_LENGTH (basetype_vec);
4945           for (i = 0; i < n; i++)
4946             {
4947               tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
4948               if (vec_elt && BINFO_TYPE (vec_elt) != object_type_node 
4949                   && interface_of_p (type, BINFO_TYPE (vec_elt)))
4950                 parse_error_context (lookup_cl (current),
4951                                      "Cyclic interface inheritance");
4952             }
4953         }
4954       else
4955         if (inherits_from_p (CLASSTYPE_SUPER (type), type))
4956           parse_error_context (lookup_cl (current), 
4957                                "Cyclic class inheritance%s",
4958                                (cyclic_inheritance_report ?
4959                                 cyclic_inheritance_report : ""));
4960     }
4961 }
4962
4963 /* Augment the parameter list PARM with parameters crafted to
4964    initialize outer context locals aliases. Through ARTIFICIAL, a
4965    count is kept of the number of crafted parameters. MODE governs
4966    what eventually gets created: something suitable for a function
4967    creation or a function invocation, either the constructor or
4968    $finit$.  */
4969
4970 static tree
4971 build_alias_initializer_parameter_list (mode, class_type, parm, artificial)
4972     int mode;
4973     tree class_type, parm;
4974     int *artificial;
4975 {
4976   tree field;
4977   for (field = TYPE_FIELDS (class_type); field; field = TREE_CHAIN (field))
4978     if (FIELD_LOCAL_ALIAS (field))
4979       {
4980         char *buffer = IDENTIFIER_POINTER (DECL_NAME (field));
4981         tree purpose = NULL_TREE, value = NULL_TREE, name = NULL_TREE;
4982
4983         switch (mode)
4984           {
4985           case AIPL_FUNCTION_DECLARATION:
4986             MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (buffer, &buffer [4]);
4987             purpose = build_wfl_node (get_identifier (buffer));
4988             if (TREE_CODE (TREE_TYPE (field)) == POINTER_TYPE)
4989               value = build_wfl_node (TYPE_NAME (TREE_TYPE (field)));
4990             else
4991               value = TREE_TYPE (field);
4992             break;
4993
4994           case AIPL_FUNCTION_CREATION:
4995             MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (buffer, &buffer [4]);
4996             purpose = get_identifier (buffer);
4997             value = TREE_TYPE (field);
4998             break;
4999
5000           case AIPL_FUNCTION_FINIT_INVOCATION:
5001             MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (buffer, &buffer [4]);
5002             /* Now, this is wrong. purpose should always be the NAME
5003                of something and value its matching value (decl, type,
5004                etc...) FIXME -- but there is a lot to fix. */
5005
5006             /* When invoked for this kind of operation, we already
5007                know whether a field is used or not. */
5008             purpose = TREE_TYPE (field);
5009             value = build_wfl_node (get_identifier (buffer));
5010             break;
5011
5012           case AIPL_FUNCTION_CTOR_INVOCATION:
5013             /* There are two case: the constructor invokation happends
5014                outside the local inner, in which case, locales from the outer
5015                context are directly used.
5016
5017                Otherwise, we fold to using the alias directly. */
5018             if (class_type == current_class)
5019               value = field;
5020             else
5021               {
5022                 name = get_identifier (&buffer[4]);
5023                 value = IDENTIFIER_LOCAL_VALUE (name);
5024               }
5025             break;
5026           }
5027         parm = tree_cons (purpose, value, parm);
5028         if (artificial)
5029           *artificial +=1;
5030       }
5031   return parm;
5032 }
5033
5034 /* Craft a constructor for CLASS_DECL -- what we should do when none
5035    where found. ARGS is non NULL when a special signature must be
5036    enforced. This is the case for anonymous classes.  */
5037
5038 static void
5039 craft_constructor (class_decl, args)
5040      tree class_decl, args;
5041 {
5042   tree class_type = TREE_TYPE (class_decl);
5043   tree parm = NULL_TREE;
5044   int flags = (get_access_flags_from_decl (class_decl) & ACC_PUBLIC ?
5045                ACC_PUBLIC : 0);
5046   int i = 0, artificial = 0;
5047   tree decl, ctor_name;
5048   char buffer [80];
5049   
5050   push_obstacks (&permanent_obstack, &permanent_obstack);
5051
5052   /* The constructor name is <init> unless we're dealing with an
5053      anonymous class, in which case the name will be fixed after having
5054      be expanded. */
5055   if (ANONYMOUS_CLASS_P (class_type))
5056     ctor_name = DECL_NAME (class_decl);
5057   else
5058     ctor_name = init_identifier_node;
5059
5060   /* If we're dealing with an inner class constructor, we hide the
5061      this$<n> decl in the name field of its parameter declaration. */
5062   if (PURE_INNER_CLASS_TYPE_P (class_type))
5063     {
5064       tree type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class_type)));
5065       parm = tree_cons (build_current_thisn (class_type),
5066                         build_pointer_type (type), parm);
5067
5068       /* Some more arguments to be hidden here. The values of the local
5069          variables of the outer context that the inner class needs to see. */
5070       parm = build_alias_initializer_parameter_list (AIPL_FUNCTION_CREATION,
5071                                                      class_type, parm, 
5072                                                      &artificial);
5073     }
5074
5075   /* Then if there are any args to be enforced, enforce them now */
5076   for (; args && args != end_params_node; args = TREE_CHAIN (args))
5077     {
5078       sprintf (buffer, "parm%d", i++);
5079       parm = tree_cons (get_identifier (buffer), TREE_VALUE (args), parm);
5080     }
5081
5082   CRAFTED_PARAM_LIST_FIXUP (parm);
5083   decl = create_artificial_method (class_type, flags, void_type_node, 
5084                                    ctor_name, parm);
5085   fix_method_argument_names (parm, decl);
5086   /* Now, mark the artificial parameters. */
5087   DECL_FUNCTION_NAP (decl) = artificial;
5088
5089   pop_obstacks ();
5090   DECL_CONSTRUCTOR_P (decl) = 1;
5091 }
5092
5093
5094 /* Fix the constructors. This will be called right after circular
5095    references have been checked. It is necessary to fix constructors
5096    early even if no code generation will take place for that class:
5097    some generated constructor might be required by the class whose
5098    compilation triggered this one to be simply loaded.  */
5099
5100 void
5101 java_fix_constructors ()
5102 {
5103   tree current;
5104
5105   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
5106     {
5107       tree class_type = TREE_TYPE (current);
5108       int saw_ctor = 0;
5109       tree decl;
5110
5111       if (CLASS_INTERFACE (TYPE_NAME (class_type)))
5112         continue;
5113
5114       for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
5115         {
5116           if (DECL_CONSTRUCTOR_P (decl))
5117             {
5118               fix_constructors (decl);
5119               saw_ctor = 1;
5120             }
5121         }
5122
5123       /* Anonymous class constructor can't be generated that early. */
5124       if (!saw_ctor && !ANONYMOUS_CLASS_P (class_type))
5125         craft_constructor (current, NULL_TREE);
5126     }
5127 }
5128
5129 /* safe_layout_class just makes sure that we can load a class without
5130    disrupting the current_class, input_file, lineno, etc, information
5131    about the class processed currently.  */
5132
5133 void
5134 safe_layout_class (class)
5135      tree class;
5136 {
5137   tree save_current_class = current_class;
5138   char *save_input_filename = input_filename;
5139   int save_lineno = lineno;
5140
5141   push_obstacks (&permanent_obstack, &permanent_obstack);
5142
5143   layout_class (class);
5144   pop_obstacks ();
5145
5146   current_class = save_current_class;
5147   input_filename = save_input_filename;
5148   lineno = save_lineno;
5149   CLASS_LOADED_P (class) = 1;
5150 }
5151
5152 static tree
5153 jdep_resolve_class (dep)
5154      jdep *dep;
5155 {
5156   tree decl;
5157
5158   if (JDEP_RESOLVED_P (dep))
5159     decl = JDEP_RESOLVED_DECL (dep);
5160   else
5161     {
5162       decl = resolve_class (JDEP_ENCLOSING (dep), JDEP_TO_RESOLVE (dep),
5163                             JDEP_DECL (dep), JDEP_WFL (dep));
5164       JDEP_RESOLVED (dep, decl);
5165     }
5166     
5167   if (!decl)
5168     complete_class_report_errors (dep);
5169
5170   return decl;
5171 }
5172
5173 /* Complete unsatisfied class declaration and their dependencies */
5174
5175 void
5176 java_complete_class ()
5177 {
5178   tree cclass;
5179   jdeplist *cclassd;
5180   int error_found;
5181   tree type;
5182
5183   push_obstacks (&permanent_obstack, &permanent_obstack);
5184
5185   /* Process imports and reverse the import on demand list */
5186   process_imports ();
5187   if (ctxp->import_demand_list)
5188     ctxp->import_demand_list = nreverse (ctxp->import_demand_list);
5189
5190   /* Rever things so we have the right order */
5191   ctxp->class_list = nreverse (ctxp->class_list);
5192   ctxp->classd_list = reverse_jdep_list (ctxp);
5193
5194   for (cclassd = ctxp->classd_list, cclass = ctxp->class_list; 
5195        cclass && cclassd; 
5196        cclass = TREE_CHAIN (cclass), cclassd = CLASSD_CHAIN (cclassd))
5197     {
5198       jdep *dep;
5199       for (dep = CLASSD_FIRST (cclassd); dep; dep = JDEP_CHAIN (dep))
5200         {
5201           tree decl;
5202           if (!(decl = jdep_resolve_class (dep)))
5203             continue;
5204
5205           /* Now it's time to patch */
5206           switch (JDEP_KIND (dep))
5207             {
5208             case JDEP_SUPER:
5209               /* Simply patch super */
5210               if (parser_check_super (decl, JDEP_DECL (dep), JDEP_WFL (dep)))
5211                 continue;
5212               BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO 
5213                 (TREE_TYPE (JDEP_DECL (dep)))), 0)) = TREE_TYPE (decl);
5214               break;
5215
5216             case JDEP_FIELD:
5217               {
5218                 /* We do part of the job done in add_field */
5219                 tree field_decl = JDEP_DECL (dep);
5220                 tree field_type = TREE_TYPE (decl);
5221                 push_obstacks (&permanent_obstack, &permanent_obstack);
5222                 if (TREE_CODE (field_type) == RECORD_TYPE)
5223                   field_type = promote_type (field_type);
5224                 pop_obstacks ();
5225                 TREE_TYPE (field_decl) = field_type;
5226                 DECL_ALIGN (field_decl) = 0;
5227                 layout_decl (field_decl, 0);
5228                 SOURCE_FRONTEND_DEBUG 
5229                   (("Completed field/var decl `%s' with `%s'",
5230                     IDENTIFIER_POINTER (DECL_NAME (field_decl)),
5231                     IDENTIFIER_POINTER (DECL_NAME (decl))));
5232                 break;
5233               }
5234             case JDEP_METHOD:   /* We start patching a method */
5235             case JDEP_METHOD_RETURN:
5236               error_found = 0;
5237               while (1)
5238                 {
5239                   if (decl)
5240                     {
5241                       type = TREE_TYPE(decl);
5242                       if (TREE_CODE (type) == RECORD_TYPE)
5243                         type = promote_type (type);
5244                       JDEP_APPLY_PATCH (dep, type);
5245                       SOURCE_FRONTEND_DEBUG 
5246                         (((JDEP_KIND (dep) == JDEP_METHOD_RETURN ?
5247                            "Completing fct `%s' with ret type `%s'":
5248                            "Completing arg `%s' with type `%s'"),
5249                           IDENTIFIER_POINTER (EXPR_WFL_NODE 
5250                                               (JDEP_DECL_WFL (dep))),
5251                           IDENTIFIER_POINTER (DECL_NAME (decl))));
5252                     }
5253                   else
5254                     error_found = 1;
5255                   dep = JDEP_CHAIN (dep);
5256                   if (JDEP_KIND (dep) == JDEP_METHOD_END)
5257                     break;
5258                   else
5259                     decl = jdep_resolve_class (dep);
5260                 }
5261               if (!error_found)
5262                 {
5263                   tree mdecl = JDEP_DECL (dep), signature;
5264                   push_obstacks (&permanent_obstack, &permanent_obstack);
5265                   /* Recompute and reset the signature, check first that
5266                      all types are now defined. If they're not,
5267                      dont build the signature. */
5268                   if (check_method_types_complete (mdecl))
5269                     {
5270                       signature = build_java_signature (TREE_TYPE (mdecl));
5271                       set_java_signature (TREE_TYPE (mdecl), signature);
5272                     }
5273                   pop_obstacks ();
5274                 }
5275               else
5276                 continue;
5277               break;
5278
5279             case JDEP_INTERFACE:
5280               if (parser_check_super_interface (decl, JDEP_DECL (dep),
5281                                                 JDEP_WFL (dep)))
5282                 continue;
5283               parser_add_interface (JDEP_DECL (dep), decl, JDEP_WFL (dep));
5284               break;
5285
5286             case JDEP_PARM:
5287             case JDEP_VARIABLE:
5288               type = TREE_TYPE(decl);
5289               if (TREE_CODE (type) == RECORD_TYPE)
5290                 type = promote_type (type);
5291               JDEP_APPLY_PATCH (dep, type);
5292               break;
5293
5294             case JDEP_TYPE:
5295               JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
5296               SOURCE_FRONTEND_DEBUG 
5297                 (("Completing a random type dependency on a '%s' node",
5298                   tree_code_name [TREE_CODE (JDEP_DECL (dep))]));
5299               break;
5300
5301             case JDEP_EXCEPTION:
5302               JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
5303               SOURCE_FRONTEND_DEBUG 
5304                 (("Completing `%s' `throws' argument node",
5305                   IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)))));
5306               break;
5307
5308             case JDEP_ANONYMOUS:
5309               patch_anonymous_class (decl, JDEP_DECL (dep), JDEP_WFL (dep));
5310               break;
5311
5312             default:
5313               fatal ("Can't handle patch code %d - java_complete_class",
5314                      JDEP_KIND (dep));
5315             }
5316         }
5317     }
5318   pop_obstacks ();
5319   return;
5320 }
5321
5322 /* Resolve class CLASS_TYPE. Handle the case of trying to resolve an
5323    array.  */
5324
5325 static tree
5326 resolve_class (enclosing, class_type, decl, cl)
5327      tree enclosing, class_type, decl, cl;
5328 {
5329   const char *name = IDENTIFIER_POINTER (TYPE_NAME (class_type));
5330   const char *base = name;
5331   tree resolved_type = TREE_TYPE (class_type);
5332   tree resolved_type_decl;
5333   
5334   if (resolved_type != NULL_TREE)
5335     {
5336       tree resolved_type_decl = TYPE_NAME (resolved_type);
5337       if (resolved_type_decl == NULL_TREE
5338           || TREE_CODE (resolved_type_decl) == IDENTIFIER_NODE)
5339         {
5340           resolved_type_decl = build_decl (TYPE_DECL,
5341                                            TYPE_NAME (class_type),
5342                                            resolved_type);
5343         }
5344       return resolved_type_decl;
5345     }
5346
5347   /* 1- Check to see if we have an array. If true, find what we really
5348      want to resolve  */
5349   while (name[0] == '[')
5350     name++;
5351   if (base != name)
5352     TYPE_NAME (class_type) = get_identifier (name);
5353
5354   /* 2- Resolve the bare type */
5355   if (!(resolved_type_decl = do_resolve_class (enclosing, class_type, 
5356                                                decl, cl)))
5357     return NULL_TREE;
5358   resolved_type = TREE_TYPE (resolved_type_decl);
5359
5360   /* 3- If we have and array, reconstruct the array down to its nesting */
5361   if (base != name)
5362     {
5363       while (base != name)
5364         {
5365           if (TREE_CODE (resolved_type) == RECORD_TYPE)
5366             resolved_type  = promote_type (resolved_type);
5367           resolved_type = build_java_array_type (resolved_type, -1);
5368           CLASS_LOADED_P (resolved_type) = 1;
5369           name--;
5370         }
5371       /* Build a fake decl for this, since this is what is expected to
5372          be returned.  */
5373       resolved_type_decl =
5374         build_decl (TYPE_DECL, TYPE_NAME (resolved_type), resolved_type);
5375       /* Figure how those two things are important for error report. FIXME */
5376       DECL_SOURCE_LINE (resolved_type_decl) = 0;
5377       DECL_SOURCE_FILE (resolved_type_decl) = input_filename;
5378       TYPE_NAME (class_type) = TYPE_NAME (resolved_type);
5379     }
5380   TREE_TYPE (class_type) = resolved_type;
5381   return resolved_type_decl;
5382 }
5383
5384 /* Effectively perform the resolution of class CLASS_TYPE. DECL or CL
5385    are used to report error messages.  */
5386
5387 tree
5388 do_resolve_class (enclosing, class_type, decl, cl)
5389      tree enclosing, class_type, decl, cl;
5390 {
5391   tree new_class_decl;
5392   tree original_name = NULL_TREE;
5393
5394   /* Do not try to replace TYPE_NAME (class_type) by a variable, since
5395      its is changed by find_in_imports{_on_demand} */
5396
5397   /* 0- Search in the current class as an inner class */
5398
5399   /* Maybe some code here should be added to load the class or
5400      something, at least if the class isn't an inner class and ended
5401      being loaded from class file. FIXME. */
5402   while (enclosing)
5403     {
5404       tree name;
5405
5406       if ((new_class_decl = find_as_inner_class (enclosing, class_type, cl)))
5407         return new_class_decl;
5408
5409       /* Now go to the upper classes, bail out if necessary. */
5410       enclosing = CLASSTYPE_SUPER (TREE_TYPE (enclosing));
5411       if (!enclosing || enclosing == object_type_node)
5412         break;
5413       
5414       if (TREE_CODE (enclosing) == RECORD_TYPE)
5415         {
5416           enclosing = TYPE_NAME (enclosing);
5417           continue;
5418         }
5419
5420       if (TREE_CODE (enclosing) == IDENTIFIER_NODE)
5421         {
5422           BUILD_PTR_FROM_NAME (name, enclosing);
5423         }
5424       else
5425         name = enclosing;
5426       enclosing = do_resolve_class (NULL, name, NULL, NULL);
5427     }
5428
5429   /* 1- Check for the type in single imports */
5430   if (find_in_imports (class_type))
5431     return NULL_TREE;
5432
5433   /* 2- And check for the type in the current compilation unit. If it fails,
5434      try with a name qualified with the package name we've seen so far */
5435   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
5436     {
5437       if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
5438           !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
5439         load_class (TYPE_NAME (class_type), 0);
5440       return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5441     }
5442
5443   original_name = TYPE_NAME (class_type);
5444   if (!QUALIFIED_P (TYPE_NAME (class_type)))
5445     {
5446       tree package;
5447       for (package = package_list; package; package = TREE_CHAIN (package))
5448         {
5449           tree new_qualified;
5450           
5451           new_qualified = merge_qualified_name (TREE_PURPOSE (package),
5452                                                 original_name);
5453           TYPE_NAME (class_type) = new_qualified;
5454           new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5455           if (!new_class_decl)
5456             load_class (TYPE_NAME (class_type), 0);
5457           new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5458           if (new_class_decl)
5459             {
5460               if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
5461                   !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
5462                 load_class (TYPE_NAME (class_type), 0);
5463               return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5464             }
5465         }
5466     }
5467
5468   TYPE_NAME (class_type) = original_name;
5469
5470   /* 3- Check an other compilation unit that bears the name of type */
5471   load_class (TYPE_NAME (class_type), 0);
5472   if (check_pkg_class_access (TYPE_NAME (class_type), 
5473                               (cl ? cl : lookup_cl (decl))))
5474     return NULL_TREE;
5475
5476   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
5477     return new_class_decl;
5478
5479   /* 4- Check the import on demands. Don't allow bar.baz to be
5480      imported from foo.* */
5481   if (!QUALIFIED_P (TYPE_NAME (class_type)))
5482     if (find_in_imports_on_demand (class_type))
5483       return NULL_TREE;
5484
5485   /* 5- Last call for a resolution */
5486   return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5487 }
5488
5489 /* Resolve NAME and lay it out (if not done and if not the current
5490    parsed class). Return a decl node. This function is meant to be
5491    called when type resolution is necessary during the walk pass.  */
5492
5493 static tree
5494 resolve_and_layout (something, cl)
5495      tree something;
5496      tree cl;
5497 {
5498   tree decl;
5499
5500   /* Don't do that on the current class */
5501   if (something == current_class)
5502     return TYPE_NAME (current_class);
5503
5504   /* Don't do anything for void and other primitive types */
5505   if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
5506     return NULL_TREE;
5507
5508   /* Pointer types can be reall pointer types or fake pointers. When
5509      finding a real pointer, recheck for primitive types */
5510   if (TREE_CODE (something) == POINTER_TYPE)
5511     {
5512       if (TREE_TYPE (something))
5513         {
5514           something = TREE_TYPE (something);
5515           if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
5516             return NULL_TREE;
5517         }
5518       else
5519         something = TYPE_NAME (something);
5520     }
5521
5522   /* Don't do anything for arrays of primitive types */
5523   if (TREE_CODE (something) == RECORD_TYPE && TYPE_ARRAY_P (something)
5524       && JPRIMITIVE_TYPE_P (TYPE_ARRAY_ELEMENT (something)))
5525     return NULL_TREE;
5526
5527   /* Something might be a WFL */
5528   if (TREE_CODE (something) == EXPR_WITH_FILE_LOCATION)
5529     something = EXPR_WFL_NODE (something);
5530
5531   /* Otherwise, if something is not and IDENTIFIER_NODE, it can be a a
5532      TYPE_DECL or a real TYPE */
5533   else if (TREE_CODE (something) != IDENTIFIER_NODE)
5534     something = (TREE_CODE (TYPE_NAME (something)) == TYPE_DECL ?
5535             DECL_NAME (TYPE_NAME (something)) : TYPE_NAME (something));
5536
5537   if (!(decl = resolve_no_layout (something, cl)))
5538     return NULL_TREE;
5539
5540   /* Resolve and layout if necessary */
5541   layout_class_methods (TREE_TYPE (decl));
5542   /* Check methods, but only once */
5543   if (CLASS_FROM_SOURCE_P (TREE_TYPE (decl)) 
5544       && !CLASS_LOADED_P (TREE_TYPE (decl)))
5545     CHECK_METHODS (decl);
5546   if (TREE_TYPE (decl) != current_class && !CLASS_LOADED_P (TREE_TYPE (decl)))
5547     safe_layout_class (TREE_TYPE (decl));
5548
5549   return decl;
5550 }
5551
5552 /* Resolve a class, returns its decl but doesn't perform any
5553    layout. The current parsing context is saved and restored */
5554
5555 static tree
5556 resolve_no_layout (name, cl)
5557      tree name, cl;
5558 {
5559   tree ptr, decl;
5560   BUILD_PTR_FROM_NAME (ptr, name);
5561   java_parser_context_save_global ();
5562   decl = resolve_class (TYPE_NAME (current_class), ptr, NULL_TREE, cl);
5563   java_parser_context_restore_global ();
5564   
5565   return decl;
5566 }
5567
5568 /* Called when reporting errors. Skip leader '[' in a complex array
5569    type description that failed to be resolved.  */
5570
5571 static const char *
5572 purify_type_name (name)
5573      const char *name;
5574 {
5575   while (*name && *name == '[')
5576     name++;
5577   return name;
5578 }
5579
5580 /* The type CURRENT refers to can't be found. We print error messages.  */
5581
5582 static void
5583 complete_class_report_errors (dep)
5584      jdep *dep;
5585 {
5586   const char *name;
5587
5588   if (!JDEP_WFL (dep))
5589     return;
5590
5591   name = IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)));
5592   switch (JDEP_KIND (dep))
5593     {
5594     case JDEP_SUPER:
5595       parse_error_context  
5596         (JDEP_WFL (dep), "Superclass `%s' of class `%s' not found",
5597          purify_type_name (name),
5598          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5599       break;
5600     case JDEP_FIELD:
5601       parse_error_context
5602         (JDEP_WFL (dep), "Type `%s' not found in declaration of field `%s'",
5603          purify_type_name (name),
5604          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5605       break;
5606     case JDEP_METHOD:           /* Covers arguments */
5607       parse_error_context
5608         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the argument `%s' of method `%s'",
5609          purify_type_name (name),
5610          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))),
5611          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_MISC (dep))));
5612       break;
5613     case JDEP_METHOD_RETURN:    /* Covers return type */
5614       parse_error_context
5615         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the return type of method `%s'", 
5616          purify_type_name (name),
5617          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))));
5618       break;
5619     case JDEP_INTERFACE:
5620       parse_error_context
5621         (JDEP_WFL (dep), "Superinterface `%s' of %s `%s' not found",
5622          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))),
5623          (CLASS_OR_INTERFACE (JDEP_DECL (dep), "class", "interface")),
5624          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5625       break;
5626     case JDEP_VARIABLE:
5627       parse_error_context
5628         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the local variable `%s'", 
5629          purify_type_name (IDENTIFIER_POINTER 
5630                            (EXPR_WFL_NODE (JDEP_WFL (dep)))),
5631          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5632       break;
5633     case JDEP_EXCEPTION:        /* As specified by `throws' */
5634       parse_error_context 
5635           (JDEP_WFL (dep), "Class `%s' not found in `throws'",
5636          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))));
5637       break;
5638     default:
5639       /* Fix for -Wall. Just break doing nothing. The error will be
5640          caught later */
5641       break;
5642     }
5643 }
5644
5645 /* Return a static string containing the DECL prototype string. If
5646    DECL is a constructor, use the class name instead of the form
5647    <init> */
5648
5649 static const char *
5650 get_printable_method_name (decl)
5651      tree decl;
5652 {
5653   const char *to_return;
5654   tree name = NULL_TREE;
5655
5656   if (DECL_CONSTRUCTOR_P (decl))
5657     {
5658       name = DECL_NAME (decl);
5659       DECL_NAME (decl) = DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)));
5660     }
5661       
5662   to_return = lang_printable_name (decl, 0);
5663   if (DECL_CONSTRUCTOR_P (decl))
5664     DECL_NAME (decl) = name;
5665   
5666   return to_return;
5667 }
5668
5669 /* Reinstall the proper DECL_NAME on METHOD. Return 0 if the method
5670    nevertheless needs to be verfied, 1 otherwise.  */
5671
5672 static int
5673 reset_method_name (method)
5674      tree method;
5675 {
5676   if (!DECL_CLINIT_P (method) && !DECL_FINIT_P (method))
5677     {
5678       /* NAME is just the plain name when Object is being defined */
5679       if (DECL_CONTEXT (method) != object_type_node)
5680         DECL_NAME (method) = (DECL_CONSTRUCTOR_P (method) ? 
5681                               init_identifier_node : GET_METHOD_NAME (method));
5682       return 0;
5683     }
5684   else 
5685     return 1;
5686 }
5687
5688 /* Return the name of METHOD_DECL, when DECL_NAME is a WFL */
5689
5690 tree
5691 java_get_real_method_name (method_decl)
5692      tree method_decl;
5693 {
5694   tree method_name = DECL_NAME (method_decl);
5695   if (DECL_CONSTRUCTOR_P (method_decl))
5696     return init_identifier_node;
5697
5698   /* Explain here why METHOD_DECL doesn't have the DECL_CONSTRUCTUR_P
5699      and still can be a constructor. FIXME */
5700
5701   /* Don't confuse method only bearing the name of their class as
5702      constructors */
5703   else if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (method_decl))
5704            && ctxp
5705            && GET_CPC_UN () == EXPR_WFL_NODE (method_name)
5706            && get_access_flags_from_decl (method_decl) <= ACC_PROTECTED
5707            && TREE_TYPE (TREE_TYPE (method_decl)) == void_type_node)
5708     return init_identifier_node;
5709   else
5710     return EXPR_WFL_NODE (method_name);
5711 }
5712
5713 /* Track method being redefined inside the same class. As a side
5714    effect, set DECL_NAME to an IDENTIFIER (prior entering this
5715    function it's a FWL, so we can track errors more accurately.)  */
5716
5717 static int
5718 check_method_redefinition (class, method)
5719      tree class, method;
5720 {
5721   tree redef, name;
5722   tree cl = DECL_NAME (method);
5723   tree sig = TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (method));
5724   /* decl name of artificial <clinit> and $finit$ doesn't need to be
5725      fixed and checked */
5726
5727   /* Reset the method name before running the check. If it returns 1,
5728      the method doesn't need to be verified with respect to method
5729      redeclaration and we return 0 */
5730   if (reset_method_name (method))
5731     return 0;
5732
5733   name = DECL_NAME (method);
5734   for (redef = TYPE_METHODS (class); redef; redef = TREE_CHAIN (redef))
5735     {
5736       if (redef == method)
5737         break;
5738       if (DECL_NAME (redef) == name 
5739           && sig == TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (redef)))
5740         {
5741           parse_error_context 
5742             (cl, "Duplicate %s declaration `%s'",
5743              (DECL_CONSTRUCTOR_P (redef) ? "constructor" : "method"),
5744              get_printable_method_name (redef));
5745           return 1;
5746         }
5747     }
5748   return 0;
5749 }
5750
5751 static void
5752 check_abstract_method_definitions (do_interface, class_decl, type)
5753      int do_interface;
5754      tree class_decl, type;
5755 {
5756   tree class = TREE_TYPE (class_decl);
5757   tree method, end_type;
5758
5759   end_type = (do_interface ? object_type_node : type);
5760   for (method = TYPE_METHODS (type); method; method = TREE_CHAIN (method))
5761     {
5762       tree other_super, other_method, method_sig, method_name;
5763       int found = 0;
5764       int end_type_reached = 0;
5765       
5766       if (!METHOD_ABSTRACT (method) || METHOD_FINAL (method))
5767         continue;
5768       
5769       /* Now verify that somewhere in between TYPE and CLASS,
5770          abstract method METHOD gets a non abstract definition
5771          that is inherited by CLASS.  */
5772       
5773       method_sig = build_java_signature (TREE_TYPE (method));
5774       method_name = DECL_NAME (method);
5775       if (TREE_CODE (method_name) == EXPR_WITH_FILE_LOCATION)
5776         method_name = EXPR_WFL_NODE (method_name);
5777
5778       other_super = class;
5779       do {
5780         if (other_super == end_type)
5781           end_type_reached = 1;
5782         
5783         /* Method search */
5784         for (other_method = TYPE_METHODS (other_super); other_method;
5785             other_method = TREE_CHAIN (other_method))
5786           {
5787             tree s = build_java_signature (TREE_TYPE (other_method));
5788             tree other_name = DECL_NAME (other_method);
5789             
5790             if (TREE_CODE (other_name) == EXPR_WITH_FILE_LOCATION)
5791               other_name = EXPR_WFL_NODE (other_name);
5792             if (!DECL_CLINIT_P (other_method)
5793                 && !DECL_CONSTRUCTOR_P (other_method)
5794                 && method_name == other_name && method_sig == s)
5795              {
5796                found = 1;
5797                break;
5798              }
5799           }
5800         other_super = CLASSTYPE_SUPER (other_super);
5801       } while (!end_type_reached);
5802  
5803       /* Report that abstract METHOD didn't find an implementation
5804          that CLASS can use. */
5805       if (!found)
5806         {
5807           char *t = xstrdup (lang_printable_name 
5808                             (TREE_TYPE (TREE_TYPE (method)), 0));
5809           tree ccn = DECL_NAME (TYPE_NAME (DECL_CONTEXT (method)));
5810           tree saved_wfl = NULL_TREE;
5811           
5812           if (TREE_CODE (DECL_NAME (method)) == EXPR_WITH_FILE_LOCATION)
5813             {
5814               saved_wfl = DECL_NAME (method);
5815               DECL_NAME (method) = EXPR_WFL_NODE (DECL_NAME (method));
5816             }
5817           
5818           parse_error_context 
5819             (lookup_cl (class_decl),
5820              "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",
5821              IDENTIFIER_POINTER (DECL_NAME (class_decl)),
5822              t, lang_printable_name (method, 0), 
5823              (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))) ? 
5824               "interface" : "class"),
5825              IDENTIFIER_POINTER (ccn),
5826              (CLASS_INTERFACE (class_decl) ? "interface" : "class"),
5827              IDENTIFIER_POINTER (DECL_NAME (class_decl)));
5828           
5829           free (t);
5830           
5831           if (saved_wfl)
5832             DECL_NAME (method) = saved_wfl;
5833         }
5834     }
5835 }
5836
5837 /* Check that CLASS_DECL somehow implements all inherited abstract
5838    methods.  */
5839
5840 static void
5841 java_check_abstract_method_definitions (class_decl)
5842      tree class_decl;
5843 {
5844   tree class = TREE_TYPE (class_decl);
5845   tree super, vector;
5846   int i;
5847
5848   if (CLASS_ABSTRACT (class_decl))
5849     return;
5850
5851   /* Check for inherited types */
5852   super = class;
5853   do {
5854     super = CLASSTYPE_SUPER (super);
5855     check_abstract_method_definitions (0, class_decl, super);
5856   } while (super != object_type_node);
5857
5858   /* Check for implemented interfaces. */
5859   vector = TYPE_BINFO_BASETYPES (class);
5860   for (i = 1; i < TREE_VEC_LENGTH (vector); i++)
5861     {
5862       super = BINFO_TYPE (TREE_VEC_ELT (vector, i));
5863       check_abstract_method_definitions (1, class_decl, super);
5864     }
5865 }
5866
5867 /* Check all the types method DECL uses and return 1 if all of them
5868    are now complete, 0 otherwise. This is used to check whether its
5869    safe to build a method signature or not.  */
5870
5871 static int
5872 check_method_types_complete (decl)
5873      tree decl;
5874 {
5875   tree type = TREE_TYPE (decl);
5876   tree args;
5877
5878   if (!INCOMPLETE_TYPE_P (TREE_TYPE (type)))
5879     return 0;
5880   
5881   args = TYPE_ARG_TYPES (type);
5882   if (TREE_CODE (type) == METHOD_TYPE)
5883     args = TREE_CHAIN (args);
5884   for (; args != end_params_node; args = TREE_CHAIN (args))
5885     if (INCOMPLETE_TYPE_P (TREE_VALUE (args)))
5886       return 0;
5887
5888   return 1;
5889 }
5890
5891 /* Check all the methods of CLASS_DECL. Methods are first completed
5892    then checked according to regular method existance rules.  If no
5893    constructor for CLASS_DECL were encountered, then build its
5894    declaration.  */
5895
5896 static void
5897 java_check_regular_methods (class_decl)
5898      tree class_decl;
5899 {
5900   int saw_constructor = ANONYMOUS_CLASS_P (TREE_TYPE (class_decl));
5901   tree method;
5902   tree class = CLASS_TO_HANDLE_TYPE (TREE_TYPE (class_decl));
5903   tree saved_found_wfl = NULL_TREE, found = NULL_TREE;
5904   tree mthrows;
5905
5906   /* It is not necessary to check methods defined in java.lang.Object */
5907   if (class == object_type_node)
5908     return;
5909
5910   if (!TYPE_NVIRTUALS (class))
5911     TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
5912
5913   /* Should take interfaces into account. FIXME */
5914   for (method = TYPE_METHODS (class); method; method = TREE_CHAIN (method))
5915     {
5916       tree sig;
5917       tree method_wfl = DECL_NAME (method);
5918       int aflags;
5919
5920       /* If we previously found something and its name was saved,
5921          reinstall it now */
5922       if (found && saved_found_wfl)
5923         {
5924           DECL_NAME (found) = saved_found_wfl;
5925           saved_found_wfl = NULL_TREE;
5926         }
5927
5928       /* Check for redefinitions */
5929       if (check_method_redefinition (class, method))
5930         continue;
5931
5932       /* If we see one constructor a mark so we don't generate the
5933          default one. Also skip other verifications: constructors
5934          can't be inherited hence hiden or overriden */
5935      if (DECL_CONSTRUCTOR_P (method))
5936        {
5937          saw_constructor = 1;
5938          continue;
5939        }
5940
5941       /* We verify things thrown by the method. They must inherits from
5942          java.lang.Throwable */
5943       for (mthrows = DECL_FUNCTION_THROWS (method);
5944            mthrows; mthrows = TREE_CHAIN (mthrows))
5945         {
5946           if (!inherits_from_p (TREE_VALUE (mthrows), throwable_type_node))
5947             parse_error_context 
5948               (TREE_PURPOSE (mthrows), "Class `%s' in `throws' clause must be a subclass of class `java.lang.Throwable'",
5949                IDENTIFIER_POINTER 
5950                  (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))));
5951         }
5952
5953       sig = build_java_argument_signature (TREE_TYPE (method));
5954       found = lookup_argument_method2 (class, DECL_NAME (method), sig);
5955
5956       /* Inner class can't declare static methods */
5957       if (METHOD_STATIC (method) && !TOPLEVEL_CLASS_DECL_P (class_decl))
5958         {
5959           char *t = xstrdup (lang_printable_name (class, 0));
5960           parse_error_context 
5961             (method_wfl, "Method `%s' can't be static in inner class `%s'. Only members of interfaces and top-level classes can be static",
5962              lang_printable_name (method, 0), t);
5963           free (t);
5964         }
5965
5966       /* Nothing overrides or it's a private method. */
5967       if (!found)
5968         continue;
5969       if (METHOD_PRIVATE (found))
5970         {
5971           found = NULL_TREE;
5972           continue;
5973         }
5974
5975       /* If found wasn't verified, it's DECL_NAME won't be set properly. 
5976          We set it temporarily for the sake of the error report. */
5977       saved_found_wfl = DECL_NAME (found);
5978       reset_method_name (found);
5979
5980       /* If `found' is declared in an interface, make sure the
5981          modifier matches. */
5982       if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (found))) 
5983           && clinit_identifier_node != DECL_NAME (found)
5984           && !METHOD_PUBLIC (method))
5985         {
5986           tree found_decl = TYPE_NAME (DECL_CONTEXT (found));
5987           parse_error_context (method_wfl, "Class `%s' must override `%s' with a public method in order to implement interface `%s'",
5988                                IDENTIFIER_POINTER (DECL_NAME (class_decl)),
5989                                lang_printable_name (method, 0),
5990                                IDENTIFIER_POINTER (DECL_NAME (found_decl)));
5991         }
5992
5993       /* Can't override a method with the same name and different return
5994          types. */
5995       if (TREE_TYPE (TREE_TYPE (found)) != TREE_TYPE (TREE_TYPE (method)))
5996         {
5997           char *t = xstrdup 
5998             (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
5999           parse_error_context 
6000             (method_wfl,
6001              "Method `%s' was defined with return type `%s' in class `%s'", 
6002              lang_printable_name (found, 0), t,
6003              IDENTIFIER_POINTER 
6004                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6005           free (t);
6006         }
6007
6008       aflags = get_access_flags_from_decl (found);
6009       /* If the method has default, access in an other package, then
6010          issue a warning that the current method doesn't override the
6011          one that was found elsewhere. Do not issue this warning when
6012          the match was found in java.lang.Object.  */
6013       if (DECL_CONTEXT (found) != object_type_node
6014           && ((aflags & ACC_VISIBILITY) == 0)
6015           && !class_in_current_package (DECL_CONTEXT (found))
6016           && !DECL_CLINIT_P (found)
6017           && flag_not_overriding)
6018         {
6019           parse_warning_context 
6020             (method_wfl, "Method `%s' in class `%s' does not override the corresponding method in class `%s', which is private to a different package",
6021              lang_printable_name (found, 0),
6022              IDENTIFIER_POINTER (DECL_NAME (class_decl)),
6023              IDENTIFIER_POINTER (DECL_NAME 
6024                                  (TYPE_NAME (DECL_CONTEXT (found)))));
6025           continue;
6026         }
6027
6028       /* Can't override final. Can't override static. */
6029       if (METHOD_FINAL (found) || METHOD_STATIC (found))
6030         {
6031           /* Static *can* override static */
6032           if (METHOD_STATIC (found) && METHOD_STATIC (method))
6033             continue;
6034           parse_error_context 
6035             (method_wfl,
6036              "%s methods can't be overriden. Method `%s' is %s in class `%s'",
6037              (METHOD_FINAL (found) ? "Final" : "Static"),
6038              lang_printable_name (found, 0),
6039              (METHOD_FINAL (found) ? "final" : "static"),
6040              IDENTIFIER_POINTER
6041                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6042           continue;
6043         }
6044
6045       /* Static method can't override instance method. */
6046       if (METHOD_STATIC (method))
6047         {
6048           parse_error_context 
6049             (method_wfl,
6050              "Instance methods can't be overriden by a static method. Method `%s' is an instance method in class `%s'",
6051              lang_printable_name (found, 0),
6052              IDENTIFIER_POINTER
6053                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6054           continue;
6055         }
6056
6057       /* - Overriding/hiding public must be public
6058          - Overriding/hiding protected must be protected or public
6059          - If the overriden or hidden method has default (package)
6060            access, then the overriding or hiding method must not be
6061            private; otherwise, a compile-time error occurs.  If
6062            `found' belongs to an interface, things have been already
6063            taken care of.  */
6064       if (!CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (found)))
6065           && ((METHOD_PUBLIC (found) && !METHOD_PUBLIC (method))
6066               || (METHOD_PROTECTED (found) 
6067                   && !(METHOD_PUBLIC (method) || METHOD_PROTECTED (method)))
6068               || (!(aflags & (ACC_PUBLIC | ACC_PRIVATE | ACC_STATIC))
6069                   && METHOD_PRIVATE (method))))
6070         {
6071           parse_error_context 
6072             (method_wfl,
6073              "Methods can't be overridden to be more private. Method `%s' is not %s in class `%s'", lang_printable_name (method, 0),
6074              (METHOD_PUBLIC (method) ? "public" : 
6075               (METHOD_PRIVATE (method) ? "private" : "protected")),
6076              IDENTIFIER_POINTER (DECL_NAME 
6077                                  (TYPE_NAME (DECL_CONTEXT (found)))));
6078           continue;
6079         }
6080
6081       /* Overriding methods must have compatible `throws' clauses on checked
6082          exceptions, if any */
6083       check_throws_clauses (method, method_wfl, found);
6084
6085       /* Inheriting multiple methods with the same signature. FIXME */
6086     }
6087   
6088   /* Don't forget eventual pending found and saved_found_wfl. Take
6089      into account that we might have exited because we saw an
6090      artificial method as the last entry. */
6091
6092   if (found && !DECL_ARTIFICIAL (found) && saved_found_wfl)
6093     DECL_NAME (found) = saved_found_wfl;
6094
6095   if (!TYPE_NVIRTUALS (class))
6096     TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
6097
6098   /* Search for inherited abstract method not yet implemented in this
6099      class.  */
6100   java_check_abstract_method_definitions (class_decl);
6101
6102   if (!saw_constructor)
6103     fatal ("No constructor found");
6104 }
6105
6106 /* Return a non zero value if the `throws' clause of METHOD (if any)
6107    is incompatible with the `throws' clause of FOUND (if any).  */
6108
6109 static void
6110 check_throws_clauses (method, method_wfl, found)
6111      tree method, method_wfl, found;
6112 {
6113   tree mthrows, fthrows;
6114
6115   /* Can't check these things with class loaded from bytecode. FIXME */
6116   if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (found)))
6117     return;
6118
6119   for (mthrows = DECL_FUNCTION_THROWS (method);
6120        mthrows; mthrows = TREE_CHAIN (mthrows))
6121     {
6122       /* We don't verify unchecked expressions */
6123       if (IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (mthrows)))
6124         continue;
6125       /* Checked expression must be compatible */
6126       for (fthrows = DECL_FUNCTION_THROWS (found); 
6127            fthrows; fthrows = TREE_CHAIN (fthrows))
6128         if (inherits_from_p (TREE_VALUE (mthrows), TREE_VALUE (fthrows)))
6129           break;
6130       if (!fthrows)
6131         {
6132           parse_error_context 
6133             (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'",
6134              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))),
6135              lang_printable_name (found, 0),
6136              IDENTIFIER_POINTER 
6137                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6138         }
6139     }
6140 }
6141
6142 /* Check abstract method of interface INTERFACE */
6143
6144 static void
6145 java_check_abstract_methods (interface_decl)
6146      tree interface_decl;
6147 {
6148   int i, n;
6149   tree method, basetype_vec, found;
6150   tree interface = TREE_TYPE (interface_decl);
6151
6152   for (method = TYPE_METHODS (interface); method; method = TREE_CHAIN (method))
6153     {
6154       tree method_wfl = DECL_NAME (method);
6155
6156       /* 2- Check for double definition inside the defining interface */
6157       if (check_method_redefinition (interface, method))
6158         continue;
6159
6160       /* 3- Overriding is OK as far as we preserve the return type and
6161          the thrown exceptions (FIXME) */
6162       found = lookup_java_interface_method2 (interface, method);
6163       if (found)
6164         {
6165           char *t;
6166           tree saved_found_wfl = DECL_NAME (found);
6167           reset_method_name (found);
6168           t = xstrdup (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
6169           parse_error_context 
6170             (method_wfl,
6171              "Method `%s' was defined with return type `%s' in class `%s'",
6172              lang_printable_name (found, 0), t,
6173              IDENTIFIER_POINTER 
6174                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6175           free (t);
6176           DECL_NAME (found) = saved_found_wfl;
6177           continue;
6178         }
6179     }
6180
6181   /* 4- Inherited methods can't differ by their returned types */
6182   if (!(basetype_vec = TYPE_BINFO_BASETYPES (interface)))
6183     return;
6184   n = TREE_VEC_LENGTH (basetype_vec);
6185   for (i = 0; i < n; i++)
6186     {
6187       tree sub_interface_method, sub_interface;
6188       tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
6189       if (!vec_elt)
6190         continue;
6191       sub_interface = BINFO_TYPE (vec_elt);
6192       for (sub_interface_method = TYPE_METHODS (sub_interface); 
6193            sub_interface_method;
6194            sub_interface_method = TREE_CHAIN (sub_interface_method))
6195         {
6196           found = lookup_java_interface_method2 (interface, 
6197                                                  sub_interface_method);
6198           if (found && (found != sub_interface_method))
6199             {
6200               tree saved_found_wfl = DECL_NAME (found);
6201               reset_method_name (found);
6202               parse_error_context 
6203                 (lookup_cl (sub_interface_method),
6204                  "Interface `%s' inherits method `%s' from interface `%s'. This method is redefined with a different return type in interface `%s'",
6205                  IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (interface))),
6206                  lang_printable_name (found, 0),
6207                  IDENTIFIER_POINTER 
6208                    (DECL_NAME (TYPE_NAME 
6209                                (DECL_CONTEXT (sub_interface_method)))),
6210                  IDENTIFIER_POINTER 
6211                    (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6212               DECL_NAME (found) = saved_found_wfl;
6213             }
6214         }
6215     }
6216 }
6217
6218 /* Lookup methods in interfaces using their name and partial
6219    signature. Return a matching method only if their types differ.  */
6220
6221 static tree
6222 lookup_java_interface_method2 (class, method_decl)
6223      tree class, method_decl;
6224 {
6225   int i, n;
6226   tree basetype_vec = TYPE_BINFO_BASETYPES (class), to_return;
6227
6228   if (!basetype_vec)
6229     return NULL_TREE;
6230
6231   n = TREE_VEC_LENGTH (basetype_vec);
6232   for (i = 0; i < n; i++)
6233     {
6234       tree vec_elt = TREE_VEC_ELT (basetype_vec, i), to_return;
6235       if ((BINFO_TYPE (vec_elt) != object_type_node)
6236           && (to_return = 
6237               lookup_java_method2 (BINFO_TYPE (vec_elt), method_decl, 1)))
6238         return to_return;
6239     }
6240   for (i = 0; i < n; i++)
6241     {
6242       to_return = lookup_java_interface_method2 
6243         (BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i)), method_decl);
6244       if (to_return)
6245         return to_return;
6246     }
6247
6248   return NULL_TREE;
6249 }
6250
6251 /* Lookup method using their name and partial signature. Return a
6252    matching method only if their types differ.  */
6253
6254 static tree
6255 lookup_java_method2 (clas, method_decl, do_interface)
6256      tree clas, method_decl;
6257      int do_interface;
6258 {
6259   tree method, method_signature, method_name, method_type, name;
6260
6261   method_signature = build_java_argument_signature (TREE_TYPE (method_decl));
6262   name = DECL_NAME (method_decl);
6263   method_name = (TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ? 
6264                  EXPR_WFL_NODE (name) : name);
6265   method_type = TREE_TYPE (TREE_TYPE (method_decl));
6266
6267   while (clas != NULL_TREE)
6268     {
6269       for (method = TYPE_METHODS (clas);
6270            method != NULL_TREE;  method = TREE_CHAIN (method))
6271         {
6272           tree method_sig = build_java_argument_signature (TREE_TYPE (method));
6273           tree name = DECL_NAME (method);
6274           if ((TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
6275                EXPR_WFL_NODE (name) : name) == method_name
6276               && method_sig == method_signature 
6277               && TREE_TYPE (TREE_TYPE (method)) != method_type)
6278             return method;
6279         }
6280       clas = (do_interface ? NULL_TREE : CLASSTYPE_SUPER (clas));
6281     }
6282   return NULL_TREE;
6283 }
6284
6285 /* Return the line that matches DECL line number, and try its best to
6286    position the column number. Used during error reports.  */
6287
6288 static tree
6289 lookup_cl (decl)
6290      tree decl;
6291 {
6292   static tree cl = NULL_TREE;
6293   char *line, *found;
6294   
6295   if (!decl)
6296     return NULL_TREE;
6297
6298   if (cl == NULL_TREE)
6299     cl = build_expr_wfl (NULL_TREE, NULL, 0, 0);
6300
6301   EXPR_WFL_FILENAME_NODE (cl) = get_identifier (DECL_SOURCE_FILE (decl));
6302   EXPR_WFL_SET_LINECOL (cl, DECL_SOURCE_LINE_FIRST (decl), -1);
6303
6304   line = java_get_line_col (IDENTIFIER_POINTER (EXPR_WFL_FILENAME_NODE (cl)),
6305                             EXPR_WFL_LINENO (cl), EXPR_WFL_COLNO (cl));
6306
6307   found = strstr ((const char *)line, 
6308                   (const char *)IDENTIFIER_POINTER (DECL_NAME (decl)));
6309   if (found)
6310     EXPR_WFL_SET_LINECOL (cl, EXPR_WFL_LINENO (cl), found - line);
6311
6312   return cl;
6313 }
6314
6315 /* Look for a simple name in the single-type import list */
6316
6317 static tree
6318 find_name_in_single_imports (name)
6319      tree name;
6320 {
6321   tree node;
6322
6323   for (node = ctxp->import_list; node; node = TREE_CHAIN (node))
6324     if (TREE_VALUE (node) == name)
6325       return (EXPR_WFL_NODE (TREE_PURPOSE (node)));
6326
6327   return NULL_TREE;
6328 }
6329
6330 /* Process all single-type import. */
6331
6332 static int
6333 process_imports ()
6334 {
6335   tree import;
6336   int error_found;
6337
6338   for (import = ctxp->import_list; import; import = TREE_CHAIN (import))
6339     {
6340       tree to_be_found = EXPR_WFL_NODE (TREE_PURPOSE (import));
6341
6342       /* Don't load twice something already defined. */
6343       if (IDENTIFIER_CLASS_VALUE (to_be_found))
6344         continue;
6345       QUALIFIED_P (to_be_found) = 1;
6346       load_class (to_be_found, 0);
6347       error_found =
6348         check_pkg_class_access (to_be_found, TREE_PURPOSE (import));
6349       if (!IDENTIFIER_CLASS_VALUE (to_be_found))
6350         {
6351           parse_error_context (TREE_PURPOSE (import),
6352                                "Class or interface `%s' not found in import",
6353                                IDENTIFIER_POINTER (to_be_found));
6354           return 1;
6355         }
6356       if (error_found)
6357         return 1;
6358     }
6359   return 0;
6360 }
6361
6362 /* Possibly find a class imported by a single-type import statement. Return
6363    1 if an error occured, 0 otherwise. */
6364
6365 static int
6366 find_in_imports (class_type)
6367      tree class_type;
6368 {
6369   tree import;
6370
6371   for (import = ctxp->import_list; import; import = TREE_CHAIN (import))
6372     if (TREE_VALUE (import) == TYPE_NAME (class_type))
6373       {
6374         TYPE_NAME (class_type) = EXPR_WFL_NODE (TREE_PURPOSE (import));
6375         QUALIFIED_P (TYPE_NAME (class_type)) = 1;
6376       }
6377   return 0;
6378 }
6379
6380 static int
6381 note_possible_classname (name, len)
6382      const char *name;
6383      int len;
6384 {
6385   tree node;
6386   if (len > 5 && strncmp (&name [len-5], ".java", 5) == 0)
6387     len = len - 5;
6388   else if (len > 6 && strncmp (&name [len-6], ".class", 6) == 0)
6389     len = len - 6;
6390   else
6391     return 0;
6392   node = ident_subst (name, len, "", '/', '.', "");
6393   IS_A_CLASSFILE_NAME (node) = 1; /* Or soon to be */
6394   QUALIFIED_P (node) = strchr (name, '/') ? 1 : 0;
6395   return 1;
6396 }
6397
6398 /* Read a import directory, gathering potential match for further type
6399    references. Indifferently reads a filesystem or a ZIP archive
6400    directory.  */
6401
6402 static void
6403 read_import_dir (wfl)
6404      tree wfl;
6405 {
6406   tree package_id = EXPR_WFL_NODE (wfl);
6407   const char *package_name = IDENTIFIER_POINTER (package_id);
6408   int package_length = IDENTIFIER_LENGTH (package_id);
6409   DIR *dirp = NULL;
6410   JCF *saved_jcf = current_jcf;
6411
6412   int found = 0;
6413   int k;
6414   void *entry;
6415   struct buffer filename[1];
6416
6417
6418   if (IS_AN_IMPORT_ON_DEMAND_P (package_id))
6419     return;
6420   IS_AN_IMPORT_ON_DEMAND_P (package_id) = 1;
6421
6422   BUFFER_INIT (filename);
6423   buffer_grow (filename, package_length + 100);
6424
6425   for (entry = jcf_path_start (); entry != NULL; entry = jcf_path_next (entry))
6426     {
6427       const char *entry_name = jcf_path_name (entry);
6428       int entry_length = strlen (entry_name);
6429       if (jcf_path_is_zipfile (entry))
6430         {
6431           ZipFile *zipf;
6432           buffer_grow (filename, entry_length);
6433           memcpy (filename->data, entry_name, entry_length - 1);
6434           filename->data[entry_length-1] = '\0';
6435           zipf = opendir_in_zip (filename->data, jcf_path_is_system (entry));
6436           if (zipf == NULL)
6437             error ("malformed .zip archive in CLASSPATH: %s", entry_name);
6438           else
6439             {
6440               ZipDirectory *zipd = (ZipDirectory *) zipf->central_directory;
6441               BUFFER_RESET (filename);
6442               for (k = 0; k < package_length; k++)
6443                 {
6444                   char ch = package_name[k];
6445                   *filename->ptr++ = ch == '.' ? '/' : ch;
6446                 }
6447               *filename->ptr++ = '/';
6448
6449               for (k = 0; k < zipf->count;  k++, zipd = ZIPDIR_NEXT (zipd))
6450                 {
6451                   const char *current_entry = ZIPDIR_FILENAME (zipd);
6452                   int current_entry_len = zipd->filename_length;
6453
6454                   if (current_entry_len >= BUFFER_LENGTH (filename)
6455                       && strncmp (filename->data, current_entry, 
6456                                   BUFFER_LENGTH (filename)) != 0)
6457                     continue;
6458                   found |= note_possible_classname (current_entry,
6459                                                     current_entry_len);
6460                 }
6461             }
6462         }
6463       else
6464         {
6465           BUFFER_RESET (filename);
6466           buffer_grow (filename, entry_length + package_length + 4);
6467           strcpy (filename->data, entry_name);
6468           filename->ptr = filename->data + entry_length;
6469           for (k = 0; k < package_length; k++)
6470             {
6471               char ch = package_name[k];
6472               *filename->ptr++ = ch == '.' ? '/' : ch;
6473             }
6474           *filename->ptr = '\0';
6475
6476           dirp = opendir (filename->data);
6477           if (dirp == NULL)
6478             continue;
6479           *filename->ptr++ = '/';
6480           for (;;)
6481             {
6482               int len; 
6483               const char *d_name;
6484               struct dirent *direntp = readdir (dirp);
6485               if (!direntp)
6486                 break;
6487               d_name = direntp->d_name;
6488               len = strlen (direntp->d_name);
6489               buffer_grow (filename, len+1);
6490               strcpy (filename->ptr, d_name);
6491               found |= note_possible_classname (filename->data + entry_length,
6492                                                 package_length+len+1);
6493             }
6494           if (dirp)
6495             closedir (dirp);
6496         }
6497     }
6498
6499   free (filename->data);
6500
6501   /* Here we should have a unified way of retrieving an entry, to be
6502      indexed. */
6503   if (!found)
6504     {
6505       static int first = 1;
6506       if (first)
6507         {
6508           error ("Can't find default package `%s'. Check the CLASSPATH environment variable and the access to the archives.", package_name);
6509           java_error_count++;
6510           first = 0;
6511         }
6512       else
6513         parse_error_context (wfl, "Package `%s' not found in import",
6514                              package_name);
6515       current_jcf = saved_jcf;
6516       return;
6517     }
6518   current_jcf = saved_jcf;
6519 }
6520
6521 /* Possibly find a type in the import on demands specified
6522    types. Returns 1 if an error occured, 0 otherwise. Run throught the
6523    entire list, to detected potential double definitions.  */
6524                  
6525 static int
6526 find_in_imports_on_demand (class_type)
6527      tree class_type;
6528 {
6529   tree node, import, node_to_use = NULL_TREE;
6530   int seen_once = -1;
6531   tree cl = NULL_TREE;
6532
6533   for (import = ctxp->import_demand_list; import; import = TREE_CHAIN (import))
6534     {
6535       const char *id_name;
6536       obstack_grow (&temporary_obstack, 
6537                     IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))),
6538                     IDENTIFIER_LENGTH (EXPR_WFL_NODE (TREE_PURPOSE (import))));
6539       obstack_1grow (&temporary_obstack, '.');
6540       obstack_grow0 (&temporary_obstack, 
6541                      IDENTIFIER_POINTER (TYPE_NAME (class_type)),
6542                      IDENTIFIER_LENGTH (TYPE_NAME (class_type)));
6543       id_name = obstack_finish (&temporary_obstack);
6544               
6545       node = maybe_get_identifier (id_name);
6546       if (node && IS_A_CLASSFILE_NAME (node))
6547         {
6548           if (seen_once < 0)
6549             {
6550               cl = TREE_PURPOSE (import);
6551               seen_once = 1;
6552               node_to_use = node;
6553             }
6554           else
6555             {
6556               seen_once++;
6557               parse_error_context 
6558                 (import, "Type `%s' also potentially defined in package `%s'",
6559                  IDENTIFIER_POINTER (TYPE_NAME (class_type)),
6560                  IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))));
6561             }
6562         }
6563     }
6564
6565   if (seen_once == 1)
6566     {
6567       /* Setup lineno so that it refers to the line of the import (in
6568          case we parse a class file and encounter errors */
6569       tree decl;
6570       int saved_lineno = lineno;
6571       lineno = EXPR_WFL_LINENO (cl);
6572       TYPE_NAME (class_type) = node_to_use;
6573       QUALIFIED_P (TYPE_NAME (class_type)) = 1;
6574       decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
6575       /* If there is no DECL set for the class or if the class isn't
6576          loaded and not seen in source yet, the load */
6577       if (!decl || (!CLASS_LOADED_P (TREE_TYPE (decl))
6578                     && !CLASS_FROM_SOURCE_P (TREE_TYPE (decl))))
6579         load_class (node_to_use, 0);
6580       lineno = saved_lineno;
6581       return check_pkg_class_access (TYPE_NAME (class_type), cl);
6582     }
6583   else
6584     return (seen_once < 0 ? 0 : seen_once); /* It's ok not to have found */
6585 }
6586
6587 static tree
6588 resolve_package (pkg, next)
6589      tree pkg, *next;
6590 {
6591   tree current, acc;
6592   tree type_name = NULL_TREE;
6593   const char *name = IDENTIFIER_POINTER (EXPR_WFL_NODE (pkg));
6594
6595   /* The trick is to determine when the package name stops and were
6596      the name of something contained in the package starts. Then we
6597      return a fully qualified name of what we want to get. */
6598
6599   /* Do a quick search on well known package names */
6600   if (!strncmp (name, "java.lang.reflect", 17))
6601     {
6602       *next = 
6603         TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg))));
6604       type_name = lookup_package_type (name, 17);
6605     }
6606   else if (!strncmp (name, "java.lang", 9))
6607     {
6608       *next = TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg)));
6609       type_name = lookup_package_type (name, 9);
6610     }
6611
6612   /* If we found something here, return */
6613   if (type_name)
6614     return type_name; 
6615
6616   *next = EXPR_WFL_QUALIFICATION (pkg);
6617
6618   /* Try the current package. */
6619   if (ctxp->package && !strncmp (name, IDENTIFIER_POINTER (ctxp->package),  
6620                                  IDENTIFIER_LENGTH (ctxp->package)))
6621     {
6622       type_name = 
6623         lookup_package_type_and_set_next (name, 
6624                                           IDENTIFIER_LENGTH (ctxp->package), 
6625                                           next );
6626       if (type_name)
6627         return type_name;
6628     }
6629
6630   /* Search in imported package */
6631   for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
6632     {
6633       tree current_pkg_name = EXPR_WFL_NODE (TREE_PURPOSE (current));
6634       int len = IDENTIFIER_LENGTH (current_pkg_name);
6635       if (!strncmp (name, IDENTIFIER_POINTER (current_pkg_name), len))
6636         {
6637           tree left, dummy;
6638           
6639           breakdown_qualified (&left, &dummy, current_pkg_name);
6640           len = IDENTIFIER_LENGTH (left);
6641           type_name = lookup_package_type_and_set_next (name, len, next);
6642           if (type_name)
6643             break;
6644         }
6645     }
6646
6647   /* Try to progressively construct a type name */
6648   if (TREE_CODE (pkg) == EXPR_WITH_FILE_LOCATION)
6649     for (acc = NULL_TREE, current = EXPR_WFL_QUALIFICATION (pkg); 
6650          current; current = TREE_CHAIN (current))
6651       {
6652         acc = merge_qualified_name (acc, EXPR_WFL_NODE (QUAL_WFL (current)));
6653         if ((type_name = resolve_no_layout (acc, NULL_TREE)))
6654           {
6655             type_name = acc;
6656             *next = TREE_CHAIN (current);
6657             break;
6658           }
6659       }
6660   return type_name;
6661 }
6662
6663 static tree
6664 lookup_package_type_and_set_next (name, len, next)
6665      const char *name;
6666      int len;
6667      tree *next;
6668 {
6669   const char *ptr;
6670   tree type_name = lookup_package_type (name, len);
6671
6672   if (!type_name)
6673     return NULL;
6674   
6675   ptr = IDENTIFIER_POINTER (type_name);
6676   while (ptr && (ptr = strchr (ptr, '.'))) 
6677     {
6678       *next = TREE_CHAIN (*next);
6679       ptr++;
6680     }
6681   return type_name;
6682 }
6683
6684 static tree
6685 lookup_package_type (name, from)
6686      const char *name;
6687      int from;
6688 {
6689   char subname [128];
6690   const char *sub = &name[from+1];
6691   while (*sub != '.' && *sub)
6692     sub++;
6693   strncpy (subname, name, sub-name);
6694   subname [sub-name] = '\0';
6695   return get_identifier (subname);
6696 }
6697
6698 /* Check that CLASS_NAME refers to a PUBLIC class. Return 0 if no
6699    access violations were found, 1 otherwise.  */
6700
6701 static int
6702 check_pkg_class_access (class_name, cl)
6703      tree class_name;
6704      tree cl;
6705 {
6706   tree type;
6707
6708   if (!QUALIFIED_P (class_name) || !IDENTIFIER_CLASS_VALUE (class_name))
6709     return 0;
6710
6711   if (!(type = TREE_TYPE (IDENTIFIER_CLASS_VALUE (class_name))))
6712     return 0;
6713
6714   if (!CLASS_PUBLIC (TYPE_NAME (type)))
6715     {
6716       /* Access to a private class within the same package is
6717          allowed. */
6718       tree l, r;
6719       breakdown_qualified (&l, &r, class_name);
6720       if (l == ctxp->package)
6721         return 0;
6722
6723       parse_error_context 
6724         (cl, "Can't access %s `%s'. Only public classes and interfaces in other packages can be accessed",
6725          (CLASS_INTERFACE (TYPE_NAME (type)) ? "interface" : "class"),
6726          IDENTIFIER_POINTER (class_name));
6727       return 1;
6728     }
6729   return 0;
6730 }
6731
6732 /* Local variable declaration. */
6733
6734 static void
6735 declare_local_variables (modifier, type, vlist)
6736      int modifier;
6737      tree type;
6738      tree vlist;
6739 {
6740   tree decl, current, saved_type;
6741   tree type_wfl = NULL_TREE;
6742   int must_chain = 0;
6743   int final_p = 0;
6744
6745   /* Push a new block if statements were seen between the last time we
6746      pushed a block and now. Keep a cound of block to close */
6747   if (BLOCK_EXPR_BODY (GET_CURRENT_BLOCK (current_function_decl)))
6748     {
6749       tree body = GET_CURRENT_BLOCK (current_function_decl);
6750       tree b = enter_block ();
6751       BLOCK_EXPR_ORIGIN (b) = body;
6752     }
6753
6754   if (modifier)
6755     {
6756       int i;
6757       for (i = 0; i <= 10; i++) if (1 << i & modifier) break;
6758       if (modifier == ACC_FINAL)
6759         final_p = 1;
6760       else 
6761         {
6762           parse_error_context 
6763             (ctxp->modifier_ctx [i], 
6764              "Only `final' is allowed as a local variables modifier");
6765           return;
6766         }
6767     }
6768
6769   /* Obtain an incomplete type if TYPE is not complete. TYPE_WFL will
6770      hold the TYPE value if a new incomplete has to be created (as
6771      opposed to being found already existing and reused). */
6772   SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
6773
6774   /* If TYPE is fully resolved and we don't have a reference, make one */
6775   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
6776
6777   /* Go through all the declared variables */
6778   for (current = vlist, saved_type = type; current;
6779        current = TREE_CHAIN (current), type = saved_type)
6780     {
6781       tree other, real_type;
6782       tree wfl  = TREE_PURPOSE (current);
6783       tree name = EXPR_WFL_NODE (wfl);
6784       tree init = TREE_VALUE (current);
6785
6786       /* Process NAME, as it may specify extra dimension(s) for it */
6787       type = build_array_from_name (type, type_wfl, name, &name);
6788
6789       /* Variable redefinition check */
6790       if ((other = lookup_name_in_blocks (name)))
6791         {
6792           variable_redefinition_error (wfl, name, TREE_TYPE (other),
6793                                        DECL_SOURCE_LINE (other));
6794           continue;
6795         }
6796
6797       /* Type adjustment. We may have just readjusted TYPE because
6798          the variable specified more dimensions. Make sure we have
6799          a reference if we can and don't have one already. */
6800       PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
6801
6802       real_type = GET_REAL_TYPE (type);
6803       /* Never layout this decl. This will be done when its scope
6804          will be entered */
6805       decl = build_decl (VAR_DECL, name, real_type);
6806       LOCAL_FINAL (decl) = final_p;
6807       BLOCK_CHAIN_DECL (decl);
6808       
6809       /* If doing xreferencing, replace the line number with the WFL
6810          compound value */
6811       if (flag_emit_xref)
6812         DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (wfl);
6813       
6814       /* Don't try to use an INIT statement when an error was found */
6815       if (init && java_error_count)
6816         init = NULL_TREE;
6817       
6818       /* Add the initialization function to the current function's code */
6819       if (init)
6820         {
6821           /* Name might have been readjusted */
6822           EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = name;
6823           MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
6824           java_method_add_stmt (current_function_decl,
6825                                 build_debugable_stmt (EXPR_WFL_LINECOL (init),
6826                                                       init));
6827         }
6828     
6829       /* Setup dependency the type of the decl */
6830       if (must_chain)
6831         {
6832           jdep *dep;
6833           register_incomplete_type (JDEP_VARIABLE, type_wfl, decl, type);
6834           dep = CLASSD_LAST (ctxp->classd_list);
6835           JDEP_GET_PATCH (dep) = &TREE_TYPE (decl);
6836         }
6837     }
6838   SOURCE_FRONTEND_DEBUG (("Defined locals"));
6839 }
6840
6841 /* Called during parsing. Build decls from argument list.  */
6842
6843 static void
6844 source_start_java_method (fndecl)
6845      tree fndecl;
6846 {
6847   tree tem;
6848   tree parm_decl;
6849   int i;
6850 #if 0
6851   int flag_inner = DECL_CONSTRUCTOR_P (fndecl)
6852       && (INNER_CLASS_TYPE_P (DECL_CONTEXT (fndecl)) ? 1 : 0);
6853 #endif
6854
6855   if (!fndecl)
6856     return;
6857
6858   current_function_decl = fndecl;
6859
6860   /* New scope for the function */
6861   enter_block ();
6862   for (tem = TYPE_ARG_TYPES (TREE_TYPE (fndecl)), i = 0;
6863        tem != end_params_node; tem = TREE_CHAIN (tem), i++)
6864     {
6865       tree type = TREE_VALUE (tem);
6866       tree name = TREE_PURPOSE (tem);
6867       
6868       /* If type is incomplete. Create an incomplete decl and ask for
6869          the decl to be patched later */
6870       if (INCOMPLETE_TYPE_P (type))
6871         {
6872           jdep *jdep;
6873           tree real_type = GET_REAL_TYPE (type);
6874           parm_decl = build_decl (PARM_DECL, name, real_type);
6875           type = obtain_incomplete_type (type);
6876           register_incomplete_type (JDEP_PARM, NULL_TREE, NULL_TREE, type);
6877           jdep = CLASSD_LAST (ctxp->classd_list);
6878           JDEP_MISC (jdep) = name;
6879           JDEP_GET_PATCH (jdep) = &TREE_TYPE (parm_decl);
6880         }
6881       else
6882         parm_decl = build_decl (PARM_DECL, name, type);
6883
6884       /* Remember if a local variable was declared final (via its
6885          TREE_LIST of type/name.) Set LOCAL_FINAL accordingly. */
6886       if (ARG_FINAL_P (tem))
6887         LOCAL_FINAL (parm_decl) = 1;
6888
6889       BLOCK_CHAIN_DECL (parm_decl);
6890
6891 #if 0
6892       /* If this is a constructor of a inner class, hide the extra
6893          this$<n> parameter */
6894       if (i == 0 && flag_inner)
6895         {
6896           tree link = TREE_CHAIN (tem);
6897           tree type = DECL_CONTEXT (TYPE_NAME (DECL_CONTEXT (fndecl)));
6898
6899           type = build_pointer_type (TREE_TYPE (type));
6900           parm_decl = build_decl (PARM_DECL,
6901                                   build_current_thisn (current_class), type);
6902           BLOCK_CHAIN_DECL (parm_decl);
6903           /* We hide the this$<n> decl in the name field of its
6904              parameter declaration. */
6905           parm_decl = build_tree_list (DECL_NAME (parm_decl), type);
6906           TREE_CHAIN (tem) = parm_decl;
6907           TREE_CHAIN (parm_decl) = link;
6908           tem = parm_decl;
6909           i++;
6910         }
6911 #endif
6912
6913     }
6914   tem = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
6915   BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl)) =
6916     nreverse (tem);
6917   DECL_ARG_SLOT_COUNT (current_function_decl) = i;
6918   DECL_MAX_LOCALS (current_function_decl) = i;
6919 }
6920
6921 /* Called during parsing. Creates an artificial method declaration.  */
6922
6923 static tree
6924 create_artificial_method (class, flags, type, name, args)
6925      tree class;
6926      int flags;
6927      tree type, name, args;
6928 {
6929   tree mdecl;
6930
6931   java_parser_context_save_global ();
6932   lineno = 0;                                                               
6933   mdecl = make_node (FUNCTION_TYPE);                                
6934   TREE_TYPE (mdecl) = type;
6935   TYPE_ARG_TYPES (mdecl) = args;
6936   mdecl = add_method (class, flags, name, build_java_signature (mdecl)); 
6937   java_parser_context_restore_global ();
6938   DECL_ARTIFICIAL (mdecl) = 1;                                      
6939   return mdecl;
6940 }
6941
6942 /* Starts the body if an artifical method.  */
6943
6944 static void
6945 start_artificial_method_body (mdecl)
6946      tree mdecl;
6947 {
6948   DECL_SOURCE_LINE (mdecl) = 1;
6949   DECL_SOURCE_LINE_MERGE (mdecl, 1);
6950   source_start_java_method (mdecl);
6951   enter_block ();
6952 }
6953
6954 static void
6955 end_artificial_method_body (mdecl)
6956      tree mdecl;
6957 {
6958   BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)) = exit_block ();
6959   exit_block ();
6960 }
6961
6962 /* Called during expansion. Push decls formerly built from argument
6963    list so they're usable during expansion. */
6964
6965 static void
6966 expand_start_java_method (fndecl)
6967      tree fndecl;
6968 {
6969   tree tem, *ptr;
6970
6971   current_function_decl = fndecl;
6972
6973   if (! quiet_flag)
6974     fprintf (stderr, " [%s.", lang_printable_name (DECL_CONTEXT (fndecl), 0));
6975   announce_function (fndecl);
6976   if (! quiet_flag)
6977     fprintf (stderr, "]");
6978
6979   pushlevel (1);                /* Prepare for a parameter push */
6980   ptr = &DECL_ARGUMENTS (fndecl);
6981   tem  = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
6982   while (tem)
6983     {
6984       tree next = TREE_CHAIN (tem);
6985       tree type = TREE_TYPE (tem);
6986       if (PROMOTE_PROTOTYPES
6987           && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
6988           && INTEGRAL_TYPE_P (type))
6989         type = integer_type_node;
6990       DECL_ARG_TYPE (tem) = type;
6991       layout_decl (tem, 0);
6992       pushdecl (tem);
6993       *ptr = tem;
6994       ptr = &TREE_CHAIN (tem);
6995       tem = next;
6996     }
6997   *ptr = NULL_TREE;
6998   pushdecl_force_head (DECL_ARGUMENTS (fndecl));
6999   lineno = DECL_SOURCE_LINE_FIRST (fndecl);
7000 }
7001
7002 /* Terminate a function and expand its body.  */
7003
7004 static void
7005 source_end_java_method ()
7006 {
7007   tree fndecl = current_function_decl;
7008   int flag_asynchronous_exceptions = asynchronous_exceptions;
7009
7010   if (!fndecl)
7011     return;
7012
7013   java_parser_context_save_global ();
7014   lineno = ctxp->last_ccb_indent1;
7015
7016   /* Set EH language codes */
7017   java_set_exception_lang_code ();
7018
7019   /* Turn function bodies with only a NOP expr null, so they don't get
7020      generated at all and we won't get warnings when using the -W
7021      -Wall flags. */
7022   if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) == empty_stmt_node)
7023     BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) = NULL_TREE;
7024
7025   /* Generate function's code */
7026   if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl))
7027       && ! flag_emit_class_files
7028       && ! flag_emit_xref)
7029     expand_expr_stmt (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)));
7030
7031   /* pop out of its parameters */
7032   pushdecl_force_head (DECL_ARGUMENTS (fndecl));
7033   poplevel (1, 0, 1);
7034   BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
7035
7036   /* Generate rtl for function exit.  */
7037   if (! flag_emit_class_files && ! flag_emit_xref)
7038     {
7039       lineno = DECL_SOURCE_LINE_LAST (fndecl);
7040       /* Emit catch-finally clauses */
7041       emit_handlers ();
7042       expand_function_end (input_filename, lineno, 0);
7043
7044       /* FIXME: If the current method contains any exception handlers,
7045          force asynchronous_exceptions: this is necessary because signal
7046          handlers in libjava may throw exceptions.  This is far from being
7047          a perfect solution, but it's better than doing nothing at all.*/
7048       if (catch_clauses)
7049         asynchronous_exceptions = 1;
7050
7051       /* Run the optimizers and output assembler code for this function. */
7052       rest_of_compilation (fndecl);
7053     }
7054
7055   current_function_decl = NULL_TREE;
7056   permanent_allocation (1);
7057   java_parser_context_restore_global ();
7058   asynchronous_exceptions = flag_asynchronous_exceptions;
7059 }
7060
7061 /* Record EXPR in the current function block. Complements compound
7062    expression second operand if necessary.  */
7063
7064 tree
7065 java_method_add_stmt (fndecl, expr)
7066      tree fndecl, expr;
7067 {
7068   if (!GET_CURRENT_BLOCK (fndecl))
7069     return NULL_TREE;
7070   return add_stmt_to_block (GET_CURRENT_BLOCK (fndecl), NULL_TREE, expr);
7071 }
7072
7073 static tree
7074 add_stmt_to_block (b, type, stmt)
7075      tree b, type, stmt;
7076 {
7077   tree body = BLOCK_EXPR_BODY (b), c;
7078   
7079   if (java_error_count)
7080     return body;
7081     
7082   if ((c = add_stmt_to_compound (body, type, stmt)) == body)
7083     return body;
7084
7085   BLOCK_EXPR_BODY (b) = c;
7086   TREE_SIDE_EFFECTS (c) = 1;
7087   return c;
7088 }
7089
7090 /* Add STMT to EXISTING if possible, otherwise create a new
7091    COMPOUND_EXPR and add STMT to it. */
7092
7093 static tree
7094 add_stmt_to_compound (existing, type, stmt)
7095      tree existing, type, stmt;
7096 {
7097   if (existing)
7098     return build (COMPOUND_EXPR, type, existing, stmt);
7099   else
7100     return stmt;
7101 }
7102
7103 /* Hold THIS for the scope of the current public method decl.  */
7104 static tree current_this;
7105
7106 void java_layout_seen_class_methods ()
7107 {
7108   tree previous_list = all_class_list;
7109   tree end = NULL_TREE;
7110   tree current;
7111
7112   while (1)
7113     {
7114       for (current = previous_list; 
7115            current != end; current = TREE_CHAIN (current))
7116         layout_class_methods (TREE_TYPE (TREE_VALUE (current)));
7117       
7118       if (previous_list != all_class_list)
7119         {
7120           end = previous_list;
7121           previous_list = all_class_list;
7122         }
7123       else
7124         break;
7125     }
7126 }
7127
7128 void
7129 java_reorder_fields ()
7130 {
7131   static tree stop_reordering = NULL_TREE;
7132
7133   tree current;
7134   for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
7135     {
7136       current_class = TREE_TYPE (TREE_VALUE (current));
7137
7138       if (current_class == stop_reordering)
7139         break;
7140
7141       /* Reverse the fields, but leave the dummy field in front.
7142          Fields are already ordered for Object and Class */
7143       if (TYPE_FIELDS (current_class) && current_class != object_type_node
7144           && current_class != class_type_node)
7145       {
7146         /* If the dummy field is there, reverse the right fields and
7147            just layout the type for proper fields offset */
7148         if (!DECL_NAME (TYPE_FIELDS (current_class)))
7149           {
7150             tree fields = TYPE_FIELDS (current_class);
7151             TREE_CHAIN (fields) = nreverse (TREE_CHAIN (fields));
7152             TYPE_SIZE (current_class) = NULL_TREE;
7153           }
7154         /* We don't have a dummy field, we need to layout the class,
7155            after having reversed the fields */
7156         else
7157           {
7158             TYPE_FIELDS (current_class) = 
7159               nreverse (TYPE_FIELDS (current_class));
7160             TYPE_SIZE (current_class) = NULL_TREE;
7161           }
7162       }
7163     }
7164   stop_reordering = TREE_TYPE (TREE_VALUE (ctxp->gclass_list));
7165 }
7166
7167 /* Layout the methods of all classes loaded in one way on an
7168    other. Check methods of source parsed classes. Then reorder the
7169    fields and layout the classes or the type of all source parsed
7170    classes */
7171
7172 void
7173 java_layout_classes ()
7174 {
7175   tree current;
7176   int save_error_count = java_error_count;
7177
7178   /* Layout the methods of all classes seen so far */
7179   java_layout_seen_class_methods ();
7180   java_parse_abort_on_error ();
7181   all_class_list = NULL_TREE;
7182
7183   /* Then check the methods of all parsed classes */
7184   for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
7185     if (CLASS_FROM_SOURCE_P (TREE_TYPE (TREE_VALUE (current))))
7186       CHECK_METHODS (TREE_VALUE (current));
7187   java_parse_abort_on_error ();
7188
7189   for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
7190     {
7191       current_class = TREE_TYPE (TREE_VALUE (current));
7192       layout_class (current_class);
7193
7194       /* From now on, the class is considered completely loaded */
7195       CLASS_LOADED_P (current_class) = 1;
7196
7197       /* Error reported by the caller */
7198       if (java_error_count)
7199         return;
7200     }
7201
7202   /* We might have reloaded classes durign the process of laying out
7203      classes for code generation. We must layout the methods of those
7204      late additions, as constructor checks might use them */
7205   java_layout_seen_class_methods ();
7206   java_parse_abort_on_error ();
7207 }
7208
7209 /* Expand methods in the current set of classes rememebered for
7210    generation.  */
7211
7212 static void
7213 java_complete_expand_classes ()
7214 {
7215   tree current;
7216
7217   do_not_fold = flag_emit_xref;
7218
7219   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
7220     if (!INNER_CLASS_DECL_P (current))
7221       java_complete_expand_class (current);
7222 }
7223
7224 /* Expand the methods found in OUTER, starting first by OUTER's inner
7225    classes, if any.  */
7226
7227 static void
7228 java_complete_expand_class (outer)
7229      tree outer;
7230 {
7231   tree inner_list;
7232
7233   set_nested_class_simple_name_value (outer, 1); /* Set */
7234
7235   /* We need to go after all inner classes and start expanding them,
7236      starting with most nested ones. We have to do that because nested
7237      classes might add functions to outer classes */
7238
7239   for (inner_list = DECL_INNER_CLASS_LIST (outer);
7240        inner_list; inner_list = TREE_CHAIN (inner_list))
7241     java_complete_expand_class (TREE_PURPOSE (inner_list));
7242
7243   java_complete_expand_methods (outer);
7244   set_nested_class_simple_name_value (outer, 0); /* Reset */
7245 }
7246
7247 /* Expand methods registered in CLASS_DECL. The general idea is that
7248    we expand regular methods first. This allows us get an estimate on
7249    how outer context local alias fields are really used so we can add
7250    to the constructor just enough code to initialize them properly (it
7251    also lets us generate $finit$ correctly.) Then we expand the
7252    constructors and then <clinit>.  */
7253
7254 static void
7255 java_complete_expand_methods (class_decl)
7256      tree class_decl;
7257 {
7258   tree clinit, finit, decl, first_decl;
7259
7260   current_class = TREE_TYPE (class_decl);
7261
7262   /* Initialize a new constant pool */
7263   init_outgoing_cpool ();
7264
7265   /* Pre-expand <clinit> to figure whether we really need it or
7266      not. If we do need it, we pre-expand the static fields so they're
7267      ready to be used somewhere else. <clinit> will be fully expanded
7268      after we processed the constructors. */
7269   first_decl = TYPE_METHODS (current_class);
7270   clinit = maybe_generate_pre_expand_clinit (current_class);
7271
7272   /* Then generate $finit$ (if we need to) because constructor will
7273    try to use it.*/
7274   if (TYPE_FINIT_STMT_LIST (current_class))
7275     {
7276       finit = generate_finit (current_class);
7277       java_complete_expand_method (finit);
7278     }
7279
7280   /* Now do the constructors */
7281   for (decl = first_decl ; !java_error_count && decl; decl = TREE_CHAIN (decl))
7282     {
7283       int no_body;
7284
7285       if (!DECL_CONSTRUCTOR_P (decl))
7286         continue;
7287       
7288       no_body = !DECL_FUNCTION_BODY (decl);
7289       /* Don't generate debug info on line zero when expanding a
7290          generated constructor. */
7291       if (no_body)
7292         restore_line_number_status (1);
7293
7294       java_complete_expand_method (decl);
7295       
7296       if (no_body)
7297         restore_line_number_status (0);
7298     }
7299
7300   /* First, do the ordinary methods. */
7301   for (decl = first_decl; decl; decl = TREE_CHAIN (decl))
7302     {
7303       /* Skip abstract or native methods */
7304       if (METHOD_ABSTRACT (decl) || METHOD_NATIVE (decl) 
7305           || DECL_CONSTRUCTOR_P (decl) || DECL_CLINIT_P (decl))
7306         continue;
7307       java_complete_expand_method (decl);
7308     }
7309
7310   /* If there is indeed a <clinit>, fully expand it now */
7311   if (clinit)
7312     {
7313       /* Prevent the use of `this' inside <clinit> */
7314       ctxp->explicit_constructor_p = 1;
7315       java_complete_expand_method (clinit);
7316       ctxp->explicit_constructor_p = 0;
7317     }
7318   
7319   /* We might have generated a class$ that we now want to expand */
7320   if (TYPE_DOT_CLASS (current_class))
7321     java_complete_expand_method (TYPE_DOT_CLASS (current_class));
7322
7323   /* Now verify constructor circularity (stop after the first one we
7324      prove wrong.) */
7325   if (!CLASS_INTERFACE (class_decl))
7326     for (decl = TYPE_METHODS (current_class); decl; decl = TREE_CHAIN (decl))
7327       if (DECL_CONSTRUCTOR_P (decl) 
7328           && verify_constructor_circularity (decl, decl))
7329         break;
7330
7331   /* Save the constant pool. We'll need to restore it later. */
7332   TYPE_CPOOL (current_class) = outgoing_cpool;
7333 }
7334
7335 /* Hold a list of catch clauses list. The first element of this list is
7336    the list of the catch clauses of the currently analysed try block. */
7337 static tree currently_caught_type_list;
7338
7339 /* Attempt to create <clinit>. Pre-expand static fields so they can be
7340    safely used in some other methods/constructors.  */
7341
7342 static tree
7343 maybe_generate_pre_expand_clinit (class_type)
7344      tree class_type;
7345 {
7346   tree current, mdecl;
7347
7348   if (!TYPE_CLINIT_STMT_LIST (class_type))
7349     return NULL_TREE;
7350
7351   /* Go through all static fields and pre expand them */
7352   for (current = TYPE_FIELDS (class_type); current; 
7353        current = TREE_CHAIN (current))
7354     if (FIELD_STATIC (current))
7355       build_field_ref (NULL_TREE, class_type, DECL_NAME (current));
7356
7357   /* Then build the <clinit> method */
7358   mdecl = create_artificial_method (class_type, ACC_STATIC, void_type_node,
7359                                     clinit_identifier_node, end_params_node);
7360   layout_class_method (class_type, CLASSTYPE_SUPER (class_type),
7361                        mdecl, NULL_TREE);
7362   start_artificial_method_body (mdecl);
7363
7364   /* We process the list of assignment we produced as the result of
7365      the declaration of initialized static field and add them as
7366      statement to the <clinit> method. */
7367   for (current = TYPE_CLINIT_STMT_LIST (class_type); current;
7368        current = TREE_CHAIN (current))
7369     {
7370       /* We build the assignment expression that will initialize the
7371          field to its value. There are strict rules on static
7372          initializers (8.5). FIXME */
7373       tree stmt = build_debugable_stmt (EXPR_WFL_LINECOL (current), current);
7374       java_method_add_stmt (mdecl, stmt);
7375     }
7376
7377   end_artificial_method_body (mdecl);
7378
7379   /* Now we want to place <clinit> as the last method for interface so
7380      that it doesn't interfere with the dispatch table based
7381      lookup. */
7382   if (CLASS_INTERFACE (TYPE_NAME (class_type))
7383       && TREE_CHAIN (TYPE_METHODS (class_type)))
7384     {
7385       tree current = 
7386         TYPE_METHODS (class_type) = TREE_CHAIN (TYPE_METHODS (class_type));
7387
7388       while (TREE_CHAIN (current))
7389         current = TREE_CHAIN (current);
7390       TREE_CHAIN (current) = mdecl;
7391       TREE_CHAIN (mdecl) = NULL_TREE;
7392     }
7393
7394   return mdecl;
7395 }
7396
7397 /* Complete and expand a method.  */
7398
7399 static void
7400 java_complete_expand_method (mdecl)
7401      tree mdecl;
7402 {
7403   current_function_decl = mdecl;
7404   /* Fix constructors before expanding them */
7405   if (DECL_CONSTRUCTOR_P (mdecl))
7406     fix_constructors (mdecl);
7407   
7408   /* Expand functions that have a body */
7409   if (DECL_FUNCTION_BODY (mdecl))
7410     {
7411       tree fbody = DECL_FUNCTION_BODY (mdecl);
7412       tree block_body = BLOCK_EXPR_BODY (fbody);
7413       tree exception_copy = NULL_TREE;
7414       expand_start_java_method (mdecl);
7415       build_result_decl (mdecl);
7416
7417       current_this 
7418         = (!METHOD_STATIC (mdecl) ? 
7419            BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl)) : NULL_TREE);
7420
7421       /* Purge the `throws' list of unchecked exceptions. If we're
7422          doing xref, save a copy of the list and re-install it
7423          later. */
7424       if (flag_emit_xref)
7425         exception_copy = copy_list (DECL_FUNCTION_THROWS (mdecl));
7426
7427       purge_unchecked_exceptions (mdecl);
7428
7429       /* Install exceptions thrown with `throws' */
7430       PUSH_EXCEPTIONS (DECL_FUNCTION_THROWS (mdecl));
7431
7432       if (block_body != NULL_TREE)
7433         {
7434           block_body = java_complete_tree (block_body);
7435
7436           if (!flag_emit_xref)
7437             check_for_initialization (block_body);
7438           ctxp->explicit_constructor_p = 0;
7439         }
7440       BLOCK_EXPR_BODY (fbody) = block_body;
7441
7442       /* If we saw a return but couldn't evaluate it properly, we'll
7443          have an error_mark_node here. */
7444       if (block_body != error_mark_node
7445           && (block_body == NULL_TREE || CAN_COMPLETE_NORMALLY (block_body))
7446           && TREE_CODE (TREE_TYPE (TREE_TYPE (mdecl))) != VOID_TYPE
7447           && !flag_emit_xref)
7448         missing_return_error (current_function_decl);
7449
7450       complete_start_java_method (mdecl); 
7451
7452       /* Don't go any further if we've found error(s) during the
7453          expansion */
7454       if (!java_error_count)
7455         source_end_java_method ();
7456       else
7457         {
7458           pushdecl_force_head (DECL_ARGUMENTS (mdecl));
7459           poplevel (1, 0, 1);
7460         }
7461
7462       /* Pop the exceptions and sanity check */
7463       POP_EXCEPTIONS();
7464       if (currently_caught_type_list)
7465         fatal ("Exception list non empty - java_complete_expand_method");
7466
7467       if (flag_emit_xref)
7468         DECL_FUNCTION_THROWS (mdecl) = exception_copy;
7469     }
7470 }
7471
7472 \f
7473
7474 /* This section of the code deals with accessing enclosing context
7475    fields either directly by using the relevant access to this$<n> or
7476    by invoking an access method crafted for that purpose.  */
7477
7478 /* Build the necessary access from an inner class to an outer
7479    class. This routine could be optimized to cache previous result
7480    (decl, current_class and returned access).  When an access method
7481    needs to be generated, it always takes the form of a read. It might
7482    be later turned into a write by calling outer_field_access_fix.  */
7483
7484 static tree
7485 build_outer_field_access (id, decl)
7486      tree id, decl;
7487 {
7488   tree access = NULL_TREE;
7489   tree ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class)));
7490
7491   /* If decl's class is the direct outer class of the current_class,
7492      build the access as `this$<n>.<field>'. Not that we will break
7493      the `private' barrier if we're not emitting bytecodes. */
7494   if (ctx == DECL_CONTEXT (decl) 
7495       && (!FIELD_PRIVATE (decl) || !flag_emit_class_files ))
7496     {
7497       tree thisn = build_current_thisn (current_class);
7498       access = make_qualified_primary (build_wfl_node (thisn), 
7499                                        id, EXPR_WFL_LINECOL (id));
7500     }
7501   /* Otherwise, generate access methods to outer this and access the
7502      field (either using an access method or by direct access.) */
7503   else
7504     {
7505       int lc = EXPR_WFL_LINECOL (id);
7506
7507       /* Now we chain the required number of calls to the access$0 to
7508          get a hold to the enclosing instance we need, and the we
7509          build the field access. */
7510       access = build_access_to_thisn (ctx, DECL_CONTEXT (decl), lc);
7511
7512       /* If the field is private and we're generating bytecode, then
7513          we generate an access method */
7514       if (FIELD_PRIVATE (decl) && flag_emit_class_files )
7515         {
7516           tree name = build_outer_field_access_methods (decl);
7517           access = build_outer_field_access_expr (lc, DECL_CONTEXT (decl),
7518                                                   name, access, NULL_TREE);
7519         }
7520       /* Otherwise we use `access$(this$<j>). ... access$(this$<i>).<field>'.
7521          Once again we break the `private' access rule from a foreign
7522          class. */
7523       else
7524         access = make_qualified_primary (access, id, lc);
7525     }
7526   return resolve_expression_name (access, NULL);
7527 }
7528
7529 /* Return a non zero value if NODE describes an outer field inner
7530    access.  */
7531
7532 static int
7533 outer_field_access_p (type, decl)
7534     tree type, decl;
7535 {
7536   if (!INNER_CLASS_TYPE_P (type) 
7537       || TREE_CODE (decl) != FIELD_DECL
7538       || DECL_CONTEXT (decl) == type)
7539     return 0;
7540
7541   for (type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))); ;
7542        type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))))
7543     {
7544       if (type == DECL_CONTEXT (decl))
7545         return 1;
7546       if (!DECL_CONTEXT (TYPE_NAME (type)))
7547         break;
7548     }
7549
7550   return 0;
7551 }
7552
7553 /* Return a non zero value if NODE represents an outer field inner
7554    access that was been already expanded. As a side effect, it returns
7555    the name of the field being accessed and the argument passed to the
7556    access function, suitable for a regeneration of the access method
7557    call if necessary. */
7558
7559 static int
7560 outer_field_expanded_access_p (node, name, arg_type, arg)
7561     tree node, *name, *arg_type, *arg;
7562 {
7563   int identified = 0;
7564
7565   if (TREE_CODE (node) != CALL_EXPR)
7566     return 0;
7567
7568   /* Well, gcj generates slightly different tree nodes when compiling
7569      to native or bytecodes. It's the case for function calls. */
7570
7571   if (flag_emit_class_files 
7572       && TREE_CODE (node) == CALL_EXPR
7573       && OUTER_FIELD_ACCESS_IDENTIFIER_P (DECL_NAME (TREE_OPERAND (node, 0))))
7574     identified = 1;
7575   else if (!flag_emit_class_files)
7576     {
7577       node = TREE_OPERAND (node, 0);
7578       
7579       if (node && TREE_OPERAND (node, 0)
7580           && TREE_CODE (TREE_OPERAND (node, 0)) == ADDR_EXPR)
7581         {
7582           node = TREE_OPERAND (node, 0);
7583           if (TREE_OPERAND (node, 0)
7584               && TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL
7585               && (OUTER_FIELD_ACCESS_IDENTIFIER_P 
7586                   (DECL_NAME (TREE_OPERAND (node, 0)))))
7587             identified = 1;
7588         }
7589     }
7590
7591   if (identified && name && arg_type && arg)
7592     {
7593       tree argument = TREE_OPERAND (node, 1);
7594       *name = DECL_NAME (TREE_OPERAND (node, 0));
7595       *arg_type = TREE_TYPE (TREE_TYPE (TREE_VALUE (argument)));
7596       *arg = TREE_VALUE (argument);
7597     }
7598   return identified;
7599 }
7600
7601 /* Detect in NODE an outer field read access from an inner class and
7602    transform it into a write with RHS as an argument. This function is
7603    called from the java_complete_lhs when an assignment to a LHS can
7604    be identified. */
7605
7606 static tree
7607 outer_field_access_fix (wfl, node, rhs)
7608     tree wfl, node, rhs;
7609 {
7610   tree name, arg_type, arg;
7611   
7612   if (outer_field_expanded_access_p (node, &name, &arg_type, &arg))
7613     {
7614       /* At any rate, check whether we're trying to assign a value to
7615          a final. */
7616       tree accessed = (JDECL_P (node) ? node : 
7617                        (TREE_CODE (node) == COMPONENT_REF ? 
7618                         TREE_OPERAND (node, 1) : node));
7619       if (check_final_assignment (accessed, wfl))
7620         return error_mark_node;
7621   
7622       node = build_outer_field_access_expr (EXPR_WFL_LINECOL (wfl), 
7623                                             arg_type, name, arg, rhs);
7624       return java_complete_tree (node);
7625     }
7626   return NULL_TREE;
7627 }
7628
7629 /* Construct the expression that calls an access method:
7630      <type>.access$<n>(<arg1> [, <arg2>]); 
7631
7632    ARG2 can be NULL and will be omitted in that case. It will denote a
7633    read access.  */
7634
7635 static tree
7636 build_outer_field_access_expr (lc, type, access_method_name, arg1, arg2)
7637     int lc;
7638     tree type, access_method_name, arg1, arg2;
7639 {
7640   tree args, cn, access;
7641
7642   args = arg1 ? arg1 : 
7643     build_wfl_node (build_current_thisn (current_class));
7644   args = build_tree_list (NULL_TREE, args);
7645
7646   if (arg2)
7647     args = tree_cons (NULL_TREE, arg2, args);
7648
7649   access = build_method_invocation (build_wfl_node (access_method_name), args);
7650   cn = build_wfl_node (DECL_NAME (TYPE_NAME (type)));
7651   return make_qualified_primary (cn, access, lc);
7652 }
7653
7654 static tree
7655 build_new_access_id ()
7656 {
7657   static int access_n_counter = 1;
7658   char buffer [128];
7659
7660   sprintf (buffer, "access$%d", access_n_counter++);
7661   return get_identifier (buffer);
7662 }
7663
7664 /* Create the static access functions for the outer field DECL. We define a
7665    read:
7666      TREE_TYPE (<field>) access$<n> (DECL_CONTEXT (<field>) inst$) {
7667        return inst$.field;
7668      }
7669    and a write access:
7670      TREE_TYPE (<field>) access$<n> (DECL_CONTEXT (<field>) inst$,
7671                                      TREE_TYPE (<field>) value$) {
7672        return inst$.field = value$;
7673      }
7674    We should have a usage flags on the DECL so we can lazily turn the ones
7675    we're using for code generation. FIXME.
7676 */
7677
7678 static tree
7679 build_outer_field_access_methods (decl)
7680     tree decl;
7681 {
7682   tree id, args, stmt, mdecl;
7683   
7684   /* Check point, to be removed. FIXME */
7685   if (FIELD_INNER_ACCESS (decl) 
7686       && TREE_CODE (FIELD_INNER_ACCESS (decl)) != IDENTIFIER_NODE)
7687     abort ();
7688
7689   if (FIELD_INNER_ACCESS (decl))
7690     return FIELD_INNER_ACCESS (decl);
7691
7692   push_obstacks (&permanent_obstack, &permanent_obstack);
7693
7694   /* Create the identifier and a function named after it. */
7695   id = build_new_access_id ();
7696
7697   /* The identifier is marked as bearing the name of a generated write
7698      access function for outer field accessed from inner classes. */
7699   OUTER_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
7700
7701   /* Create the read access */
7702   args = build_tree_list (inst_id, build_pointer_type (DECL_CONTEXT (decl)));
7703   TREE_CHAIN (args) = end_params_node;
7704   stmt = make_qualified_primary (build_wfl_node (inst_id),
7705                                  build_wfl_node (DECL_NAME (decl)), 0);
7706   stmt = build_return (0, stmt);
7707   mdecl = build_outer_field_access_method (DECL_CONTEXT (decl), 
7708                                            TREE_TYPE (decl), id, args, stmt);
7709   DECL_FUNCTION_ACCESS_DECL (mdecl) = decl;
7710
7711   /* Create the write access method */
7712   args = build_tree_list (inst_id, build_pointer_type (DECL_CONTEXT (decl)));
7713   TREE_CHAIN (args) = build_tree_list (wpv_id, TREE_TYPE (decl));
7714   TREE_CHAIN (TREE_CHAIN (args)) = end_params_node;
7715   stmt = make_qualified_primary (build_wfl_node (inst_id),
7716                                  build_wfl_node (DECL_NAME (decl)), 0);
7717   stmt = build_return (0, build_assignment (ASSIGN_TK, 0, stmt,
7718                                             build_wfl_node (wpv_id)));
7719
7720   mdecl = build_outer_field_access_method (DECL_CONTEXT (decl), 
7721                                            TREE_TYPE (decl), id, args, stmt);
7722   DECL_FUNCTION_ACCESS_DECL (mdecl) = decl;
7723   pop_obstacks ();
7724
7725   /* Return the access name */
7726   return FIELD_INNER_ACCESS (decl) = id;
7727 }
7728
7729 /* Build an field access method NAME.  */
7730
7731 static tree 
7732 build_outer_field_access_method (class, type, name, args, body)
7733     tree class, type, name, args, body;
7734 {
7735   tree saved_current_function_decl, mdecl;
7736
7737   /* Create the method */
7738   mdecl = create_artificial_method (class, ACC_STATIC, type, name, args);
7739   fix_method_argument_names (args, mdecl);
7740   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
7741
7742   /* Attach the method body. */
7743   saved_current_function_decl = current_function_decl;
7744   start_artificial_method_body (mdecl);
7745   java_method_add_stmt (mdecl, body);
7746   end_artificial_method_body (mdecl);
7747   current_function_decl = saved_current_function_decl;
7748
7749   return mdecl;
7750 }
7751
7752 \f
7753 /* This section deals with building access function necessary for
7754    certain kinds of method invocation from inner classes.  */
7755
7756 static tree
7757 build_outer_method_access_method (decl)
7758     tree decl;
7759 {
7760   tree saved_current_function_decl, mdecl;
7761   tree args = NULL_TREE, call_args = NULL_TREE;
7762   tree carg, id, body, class;
7763   char buffer [80];
7764   int parm_id_count = 0;
7765
7766   /* Test this abort with an access to a private field */
7767   if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), "access$"))
7768     abort ();
7769
7770   /* Check the cache first */
7771   if (DECL_FUNCTION_INNER_ACCESS (decl))
7772     return DECL_FUNCTION_INNER_ACCESS (decl);
7773
7774   class = DECL_CONTEXT (decl);
7775
7776   /* Obtain an access identifier and mark it */
7777   id = build_new_access_id ();
7778   OUTER_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
7779
7780   push_obstacks (&permanent_obstack, &permanent_obstack);
7781
7782   carg = TYPE_ARG_TYPES (TREE_TYPE (decl));
7783   /* Create the arguments, as much as the original */
7784   for (; carg && carg != end_params_node; 
7785        carg = TREE_CHAIN (carg))
7786     {
7787       sprintf (buffer, "write_parm_value$%d", parm_id_count++);
7788       args = chainon (args, build_tree_list (get_identifier (buffer), 
7789                                              TREE_VALUE (carg)));
7790     }
7791   args = chainon (args, end_params_node);
7792
7793   /* Create the method */
7794   mdecl = create_artificial_method (class, ACC_STATIC, 
7795                                     TREE_TYPE (TREE_TYPE (decl)), id, args);
7796   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
7797   /* There is a potential bug here. We should be able to use
7798      fix_method_argument_names, but then arg names get mixed up and
7799      eventually a constructor will have its this$0 altered and the
7800      outer context won't be assignment properly. The test case is
7801      stub.java FIXME */
7802   TYPE_ARG_TYPES (TREE_TYPE (mdecl)) = args;
7803
7804   /* Attach the method body. */
7805   saved_current_function_decl = current_function_decl;
7806   start_artificial_method_body (mdecl);
7807
7808   /* The actual method invocation uses the same args. When invoking a
7809      static methods that way, we don't want to skip the first
7810      argument. */
7811   carg = args;
7812   if (!METHOD_STATIC (decl))
7813     carg = TREE_CHAIN (carg);
7814   for (; carg && carg != end_params_node; carg = TREE_CHAIN (carg))
7815     call_args = tree_cons (NULL_TREE, build_wfl_node (TREE_PURPOSE (carg)),
7816                            call_args);
7817
7818   body = build_method_invocation (build_wfl_node (DECL_NAME (decl)), 
7819                                   call_args);
7820   if (!METHOD_STATIC (decl))
7821     body = make_qualified_primary (build_wfl_node (TREE_PURPOSE (args)), 
7822                                    body, 0);
7823   if (TREE_TYPE (TREE_TYPE (decl)) != void_type_node)
7824     body = build_return (0, body);
7825   java_method_add_stmt (mdecl,body);
7826   end_artificial_method_body (mdecl);
7827   current_function_decl = saved_current_function_decl;
7828   pop_obstacks ();
7829
7830   /* Back tag the access function so it know what it accesses */
7831   DECL_FUNCTION_ACCESS_DECL (decl) = mdecl;
7832
7833   /* Tag the current method so it knows it has an access generated */
7834   return DECL_FUNCTION_INNER_ACCESS (decl) = mdecl;
7835 }
7836
7837 \f
7838 /* This section of the code deals with building expressions to access
7839    the enclosing instance of an inner class. The enclosing instance is
7840    kept in a generated field called this$<n>, with <n> being the
7841    inner class nesting level (starting from 0.)  */
7842     
7843 /* Build an access to a given this$<n>, possibly by chaining access
7844    call to others. Access methods to this$<n> are build on the fly if
7845    necessary */
7846
7847 static tree
7848 build_access_to_thisn (from, to, lc)
7849      tree from, to;
7850      int lc;
7851 {
7852   tree access = NULL_TREE;
7853
7854   while (from != to)
7855     {
7856       tree access0_wfl, cn;
7857
7858       maybe_build_thisn_access_method (from);
7859       access0_wfl = build_wfl_node (access0_identifier_node);
7860       cn = build_wfl_node (DECL_NAME (TYPE_NAME (from)));
7861       EXPR_WFL_LINECOL (access0_wfl) = lc;
7862       
7863       if (!access)
7864         {
7865           access = build_current_thisn (current_class);
7866           access = build_wfl_node (access);
7867         }
7868       access = build_tree_list (NULL_TREE, access);
7869       access = build_method_invocation (access0_wfl, access);
7870       access = make_qualified_primary (cn, access, lc);
7871       
7872       from = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (from)));
7873     }
7874   return access;
7875 }
7876
7877 /* Build an access function to the this$<n> local to TYPE. NULL_TREE
7878    is returned if nothing needs to be generated. Otherwise, the method
7879    generated, fully walked and a method decl is returned.  
7880
7881    NOTE: These generated methods should be declared in a class file
7882    attribute so that they can't be referred to directly.  */
7883
7884 static tree
7885 maybe_build_thisn_access_method (type)
7886     tree type;
7887 {
7888   tree mdecl, args, stmt, rtype;
7889   tree saved_current_function_decl;
7890
7891   /* If TYPE is a top-level class, no access method is required.
7892      If there already is such an access method, bail out. */
7893   if (CLASS_ACCESS0_GENERATED_P (type) || !INNER_CLASS_TYPE_P (type))
7894     return NULL_TREE;
7895
7896   /* We generate the method. The method looks like:
7897      static <outer_of_type> access$0 (<type> inst$) { return inst$.this$<n>; }
7898   */
7899   push_obstacks (&permanent_obstack, &permanent_obstack);
7900   args = build_tree_list (inst_id, build_pointer_type (type));
7901   TREE_CHAIN (args) = end_params_node;
7902   rtype = build_pointer_type (TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))));
7903   mdecl = create_artificial_method (type, ACC_STATIC, rtype,
7904                                     access0_identifier_node, args);
7905   fix_method_argument_names (args, mdecl);
7906   layout_class_method (type, NULL_TREE, mdecl, NULL_TREE);
7907   stmt = build_current_thisn (type);
7908   stmt = make_qualified_primary (build_wfl_node (inst_id), 
7909                                  build_wfl_node (stmt), 0);
7910   stmt = build_return (0, stmt);
7911
7912   saved_current_function_decl = current_function_decl;
7913   start_artificial_method_body (mdecl);
7914   java_method_add_stmt (mdecl, stmt);
7915   end_artificial_method_body (mdecl);
7916   current_function_decl = saved_current_function_decl;
7917   pop_obstacks ();
7918
7919   CLASS_ACCESS0_GENERATED_P (type) = 1;
7920
7921   return mdecl;
7922 }
7923
7924 /* Craft an correctly numbered `this$<n>'string. this$0 is used for
7925    the first level of innerclassing. this$1 for the next one, etc...
7926    This function can be invoked with TYPE to NULL, available and then
7927    has to count the parser context.  */
7928
7929 static tree
7930 build_current_thisn (type)
7931     tree type;
7932 {
7933   static int saved_i = -1;
7934   static tree saved_thisn = NULL_TREE;
7935
7936   tree decl;
7937   char buffer [80];
7938   int i = 0;
7939
7940   if (type)
7941     {
7942       static tree saved_type = NULL_TREE;
7943       static int saved_type_i = 0;
7944
7945       if (type == saved_type)
7946         i = saved_type_i;
7947       else
7948         {
7949           for (i = -1, decl = DECL_CONTEXT (TYPE_NAME (type)); 
7950                decl; decl = DECL_CONTEXT (decl), i++)
7951             ;
7952       
7953           saved_type = type;
7954           saved_type_i = i;
7955         }
7956     }
7957   else
7958     i = list_length (GET_CPC_LIST ())-2;
7959
7960   if (i == saved_i)
7961     return saved_thisn;
7962     
7963   sprintf (buffer, "this$%d", i);
7964   saved_i = i;
7965   saved_thisn = get_identifier (buffer);
7966   return saved_thisn;
7967 }
7968
7969 /* Return the assignement to the hidden enclosing context `this$<n>'
7970    by the second incoming parameter to the innerclass constructor. The
7971    form used is `this.this$<n> = this$<n>;'.  */
7972
7973 static tree
7974 build_thisn_assign ()
7975 {
7976   if (current_class && PURE_INNER_CLASS_TYPE_P (current_class))
7977     {
7978       tree thisn = build_current_thisn (current_class);
7979       tree lhs = make_qualified_primary (build_wfl_node (this_identifier_node),
7980                                          build_wfl_node (thisn), 0);
7981       tree rhs = build_wfl_node (thisn);
7982       EXPR_WFL_SET_LINECOL (lhs, lineno, 0);
7983       return build_assignment (ASSIGN_TK, EXPR_WFL_LINECOL (lhs), lhs, rhs);
7984     }
7985   return NULL_TREE;
7986 }
7987
7988 \f
7989 /* Building the synthetic `class$' used to implement the `.class' 1.1
7990    extension for non primitive types. This method looks like:
7991
7992     static Class class$(String type) throws NoClassDefFoundError
7993     {
7994       try {return (java.lang.Class.forName (String));}
7995       catch (ClassNotFoundException e) {
7996         throw new NoClassDefFoundError(e.getMessage());}
7997     } */
7998
7999 static tree
8000 build_dot_class_method (class)
8001      tree class;
8002 {
8003 #define BWF(S) build_wfl_node (get_identifier ((S)))
8004 #define MQN(X,Y) make_qualified_name ((X), (Y), 0)
8005   tree args, tmp, saved_current_function_decl, mdecl;
8006   tree stmt, throw_stmt, catch, catch_block, try_block;
8007   tree catch_clause_param;
8008   tree class_not_found_exception, no_class_def_found_error;
8009
8010   static tree get_message_wfl, type_parm_wfl;
8011
8012   if (!get_message_wfl)
8013     {
8014       get_message_wfl = build_wfl_node (get_identifier ("getMessage"));
8015       type_parm_wfl = build_wfl_node (get_identifier ("type$"));
8016     }
8017
8018   /* Build the arguments */
8019   args = build_tree_list (get_identifier ("type$"),
8020                           build_pointer_type (string_type_node));
8021   TREE_CHAIN (args) = end_params_node;
8022
8023   /* Build the qualified name java.lang.Class.forName */
8024   tmp = MQN (MQN (MQN (BWF ("java"), 
8025                        BWF ("lang")), BWF ("Class")), BWF ("forName"));
8026
8027   /* For things we have to catch and throw */
8028   class_not_found_exception = 
8029     lookup_class (get_identifier ("java.lang.ClassNotFoundException"));
8030   no_class_def_found_error = 
8031     lookup_class (get_identifier ("java.lang.NoClassDefFoundError"));
8032   load_class (class_not_found_exception, 1);
8033   load_class (no_class_def_found_error, 1);
8034
8035   /* Create the "class$" function */
8036   mdecl = create_artificial_method (class, ACC_STATIC, 
8037                                     build_pointer_type (class_type_node),
8038                                     get_identifier ("class$"), args);
8039   DECL_FUNCTION_THROWS (mdecl) = build_tree_list (NULL_TREE,
8040                                                   no_class_def_found_error);
8041   
8042   /* We start by building the try block. We need to build:
8043        return (java.lang.Class.forName (type)); */
8044   stmt = build_method_invocation (tmp, 
8045                                   build_tree_list (NULL_TREE, type_parm_wfl));
8046   stmt = build_return (0, stmt);
8047   /* Put it in a block. That's the try block */
8048   try_block = build_expr_block (stmt, NULL_TREE);
8049
8050   /* Now onto the catch block. We start by building the expression
8051      throwing a new exception: 
8052        throw new NoClassDefFoundError (_.getMessage); */
8053   throw_stmt = make_qualified_name (build_wfl_node (wpv_id), 
8054                                     get_message_wfl, 0);
8055   throw_stmt = build_method_invocation (throw_stmt, NULL_TREE);
8056   
8057   /* Build new NoClassDefFoundError (_.getMessage) */
8058   throw_stmt = build_new_invocation 
8059     (build_wfl_node (get_identifier ("NoClassDefFoundError")),
8060      build_tree_list (build_pointer_type (string_type_node), throw_stmt));
8061
8062   /* Build the throw, (it's too early to use BUILD_THROW) */
8063   throw_stmt = build1 (THROW_EXPR, NULL_TREE, throw_stmt);
8064
8065   /* Build the catch block to encapsulate all this. We begin by
8066      building an decl for the catch clause parameter and link it to
8067      newly created block, the catch block. */
8068   catch_clause_param = 
8069     build_decl (VAR_DECL, wpv_id, 
8070                 build_pointer_type (class_not_found_exception));
8071   catch_block = build_expr_block (NULL_TREE, catch_clause_param);
8072   
8073   /* We initialize the variable with the exception handler. */
8074   catch = build (MODIFY_EXPR, NULL_TREE, catch_clause_param,
8075                  soft_exceptioninfo_call_node);
8076   add_stmt_to_block (catch_block, NULL_TREE, catch);
8077
8078   /* We add the statement throwing the new exception */
8079   add_stmt_to_block (catch_block, NULL_TREE, throw_stmt);
8080
8081   /* Build a catch expression for all this */
8082   catch_block = build1 (CATCH_EXPR, NULL_TREE, catch_block);
8083
8084   /* Build the try/catch sequence */
8085   stmt = build_try_statement (0, try_block, catch_block);
8086
8087   fix_method_argument_names (args, mdecl);
8088   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
8089   saved_current_function_decl = current_function_decl;
8090   start_artificial_method_body (mdecl);
8091   java_method_add_stmt (mdecl, stmt);
8092   end_artificial_method_body (mdecl);
8093   current_function_decl = saved_current_function_decl;
8094   TYPE_DOT_CLASS (class) = mdecl;
8095
8096   return mdecl;
8097 }
8098
8099 static tree
8100 build_dot_class_method_invocation (name)
8101      tree name;
8102 {
8103   tree s = make_node (STRING_CST);
8104   TREE_STRING_LENGTH (s) = IDENTIFIER_LENGTH (name);
8105   TREE_STRING_POINTER (s) = obstack_alloc (expression_obstack,
8106                                            TREE_STRING_LENGTH (s)+1);
8107   strcpy (TREE_STRING_POINTER (s), IDENTIFIER_POINTER (name));
8108   return build_method_invocation (build_wfl_node (get_identifier ("class$")),
8109                                   build_tree_list (NULL_TREE, s));
8110 }
8111
8112 /* This section of the code deals with constructor.  */
8113
8114 /* Craft a body for default constructor. Patch existing constructor
8115    bodies with call to super() and field initialization statements if
8116    necessary.  */
8117
8118 static void
8119 fix_constructors (mdecl)
8120      tree mdecl;
8121 {
8122   tree body = DECL_FUNCTION_BODY (mdecl);
8123   tree thisn_assign, compound = NULL_TREE;
8124   tree class_type = DECL_CONTEXT (mdecl);
8125
8126   if (!body)
8127     {
8128       /* It is an error for the compiler to generate a default
8129          constructor if the superclass doesn't have a constructor that
8130          takes no argument, or the same args for an anonymous class */
8131       if (verify_constructor_super (mdecl))
8132         {
8133           tree sclass_decl = TYPE_NAME (CLASSTYPE_SUPER (class_type));
8134           tree save = DECL_NAME (mdecl);
8135           const char *n = IDENTIFIER_POINTER (DECL_NAME (sclass_decl));
8136           DECL_NAME (mdecl) = DECL_NAME (sclass_decl);
8137           parse_error_context
8138             (lookup_cl (TYPE_NAME (class_type)), 
8139              "No constructor matching `%s' found in class `%s'",
8140              lang_printable_name (mdecl, 0), n);
8141           DECL_NAME (mdecl) = save;
8142         }
8143       
8144       /* The constructor body must be crafted by hand. It's the
8145          constructor we defined when we realize we didn't have the
8146          CLASSNAME() constructor */
8147       start_artificial_method_body (mdecl);
8148       
8149       /* We don't generate a super constructor invocation if we're
8150          compiling java.lang.Object. build_super_invocation takes care
8151          of that. */
8152       compound = java_method_add_stmt (mdecl, build_super_invocation (mdecl));
8153
8154       /* Insert the instance initializer block right here, after the
8155          super invocation. */
8156       add_instance_initializer (mdecl);
8157
8158       /* Insert an assignment to the this$<n> hidden field, if
8159          necessary */
8160       if ((thisn_assign = build_thisn_assign ()))
8161         java_method_add_stmt (mdecl, thisn_assign);
8162
8163       end_artificial_method_body (mdecl);
8164     }
8165   /* Search for an explicit constructor invocation */
8166   else 
8167     {
8168       int found = 0;
8169       tree main_block = BLOCK_EXPR_BODY (body);
8170       
8171       while (body)
8172         switch (TREE_CODE (body))
8173           {
8174           case CALL_EXPR:
8175             found = CALL_EXPLICIT_CONSTRUCTOR_P (body);
8176             body = NULL_TREE;
8177             break;
8178           case COMPOUND_EXPR:
8179           case EXPR_WITH_FILE_LOCATION:
8180             body = TREE_OPERAND (body, 0);
8181             break;
8182           case BLOCK:
8183             body = BLOCK_EXPR_BODY (body);
8184             break;
8185           default:
8186             found = 0;
8187             body = NULL_TREE;
8188           }
8189       /* The constructor is missing an invocation of super() */
8190       if (!found)
8191         compound = add_stmt_to_compound (compound, NULL_TREE,
8192                                          build_super_invocation (mdecl));
8193       
8194       /* Insert the instance initializer block right here, after the
8195          super invocation. */
8196       add_instance_initializer (mdecl);
8197
8198       /* Generate the assignment to this$<n>, if necessary */
8199       if ((thisn_assign = build_thisn_assign ()))
8200         compound = add_stmt_to_compound (compound, NULL_TREE, thisn_assign);
8201
8202       /* Fix the constructor main block if we're adding extra stmts */
8203       if (compound)
8204         {
8205           compound = add_stmt_to_compound (compound, NULL_TREE,
8206                                            BLOCK_EXPR_BODY (main_block));
8207           BLOCK_EXPR_BODY (main_block) = compound;
8208         }
8209     }
8210 }
8211
8212 /* Browse constructors in the super class, searching for a constructor
8213    that doesn't take any argument. Return 0 if one is found, 1
8214    otherwise.  If the current class is an anonymous inner class, look
8215    for something that has the same signature. */
8216
8217 static int
8218 verify_constructor_super (mdecl)
8219      tree mdecl;
8220 {
8221   tree class = CLASSTYPE_SUPER (current_class);
8222   tree sdecl;
8223
8224   if (!class)
8225     return 0;
8226
8227   if (ANONYMOUS_CLASS_P (current_class))
8228     {
8229       tree mdecl_arg_type;
8230       SKIP_THIS_AND_ARTIFICIAL_PARMS (mdecl_arg_type, mdecl);
8231       for (sdecl = TYPE_METHODS (class); sdecl; sdecl = TREE_CHAIN (sdecl))
8232         if (DECL_CONSTRUCTOR_P (sdecl))
8233           {
8234             tree arg_type;
8235             for (arg_type = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (sdecl)));
8236                  arg_type != end_params_node && 
8237                    mdecl_arg_type != end_params_node;
8238                  arg_type = TREE_CHAIN (arg_type), 
8239                  mdecl_arg_type = TREE_CHAIN (mdecl_arg_type))
8240               if (TREE_VALUE (arg_type) != TREE_VALUE (mdecl_arg_type))
8241                 break;
8242
8243             if (arg_type == end_params_node && 
8244                 mdecl_arg_type == end_params_node)
8245               return 0;
8246           }
8247     }
8248   else
8249     {
8250       for (sdecl = TYPE_METHODS (class); sdecl; sdecl = TREE_CHAIN (sdecl))
8251         {
8252           if (DECL_CONSTRUCTOR_P (sdecl)
8253               && TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (sdecl))) 
8254                  == end_params_node)
8255             return 0;
8256         }
8257     }
8258   return 1;
8259 }
8260
8261 /* Generate code for all context remembered for code generation.  */
8262
8263 void
8264 java_expand_classes ()
8265 {
8266   int save_error_count = 0;
8267   static struct parser_ctxt *saved_ctxp = NULL;
8268
8269   java_parse_abort_on_error ();
8270   if (!(ctxp = ctxp_for_generation))
8271     return;
8272   java_layout_classes ();
8273   java_parse_abort_on_error ();
8274
8275   /* The list of packages declaration seen so far needs to be
8276      reversed, so that package declared in a file being compiled gets
8277      priority over packages declared as a side effect of parsing other
8278      files.*/
8279   package_list = nreverse (package_list);
8280
8281   saved_ctxp = ctxp_for_generation;
8282   for (; ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
8283     {
8284       ctxp = ctxp_for_generation;
8285       lang_init_source (2);            /* Error msgs have method prototypes */
8286       java_complete_expand_classes (); /* Complete and expand classes */
8287       java_parse_abort_on_error ();
8288     }
8289
8290   /* Find anonymous classes and expand their constructor, now they
8291      have been fixed. */
8292   for (ctxp_for_generation = saved_ctxp;
8293        ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
8294     {
8295       tree current;
8296       ctxp = ctxp_for_generation;
8297       for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
8298         {
8299           current_class = TREE_TYPE (current);
8300           if (ANONYMOUS_CLASS_P (current_class))
8301             {
8302               tree d;
8303               for (d = TYPE_METHODS (current_class); d; d = TREE_CHAIN (d))
8304                 {
8305                   if (DECL_CONSTRUCTOR_P (d))
8306                     {
8307                       restore_line_number_status (1);
8308                       reset_method_name (d);
8309                       java_complete_expand_method (d);
8310                       restore_line_number_status (0);
8311                       break;    /* We now there are no other ones */
8312                     }
8313                 }
8314             }
8315         }
8316     }
8317
8318   /* If we've found error at that stage, don't try to generate
8319      anything, unless we're emitting xrefs or checking the syntax only
8320      (but not using -fsyntax-only for the purpose of generating
8321      bytecode. */
8322   if (java_error_count && !flag_emit_xref 
8323       && (!flag_syntax_only && !flag_emit_class_files))
8324     return;
8325
8326   /* Now things are stable, go for generation of the class data. */
8327   for (ctxp_for_generation = saved_ctxp;
8328        ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
8329     {
8330       tree current;
8331       ctxp = ctxp_for_generation;
8332       for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
8333         {
8334           current_class = TREE_TYPE (current);
8335           outgoing_cpool = TYPE_CPOOL (current_class);
8336           if (flag_emit_class_files)
8337             write_classfile (current_class);
8338           if (flag_emit_xref)
8339             expand_xref (current_class);
8340           else if (! flag_syntax_only)
8341             finish_class ();
8342         }
8343     }
8344 }
8345
8346 /* Wrap non WFL PRIMARY around a WFL and set EXPR_WFL_QUALIFICATION to
8347    a tree list node containing RIGHT. Fore coming RIGHTs will be
8348    chained to this hook. LOCATION contains the location of the
8349    separating `.' operator.  */
8350
8351 static tree
8352 make_qualified_primary (primary, right, location)
8353      tree primary, right;
8354      int location;
8355 {
8356   tree wfl;
8357
8358   if (TREE_CODE (primary) != EXPR_WITH_FILE_LOCATION)
8359     wfl = build_wfl_wrap (primary);
8360   else
8361     {
8362       wfl = primary;
8363       /* If wfl wasn't qualified, we build a first anchor */
8364       if (!EXPR_WFL_QUALIFICATION (wfl))
8365         EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (wfl, NULL_TREE);
8366     }
8367
8368   /* And chain them */
8369   EXPR_WFL_LINECOL (right) = location;
8370   chainon (EXPR_WFL_QUALIFICATION (wfl), build_tree_list (right, NULL_TREE));
8371   PRIMARY_P (wfl) =  1;
8372   return wfl;
8373 }
8374
8375 /* Simple merge of two name separated by a `.' */
8376
8377 static tree
8378 merge_qualified_name (left, right)
8379      tree left, right;
8380 {
8381   tree node;
8382   if (!left && !right)
8383     return NULL_TREE;
8384
8385   if (!left)
8386     return right;
8387
8388   if (!right)
8389     return left;
8390
8391   obstack_grow (&temporary_obstack, IDENTIFIER_POINTER (left),
8392                 IDENTIFIER_LENGTH (left));
8393   obstack_1grow (&temporary_obstack, '.');
8394   obstack_grow0 (&temporary_obstack, IDENTIFIER_POINTER (right),
8395                  IDENTIFIER_LENGTH (right));
8396   node =  get_identifier (obstack_base (&temporary_obstack));
8397   obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
8398   QUALIFIED_P (node) = 1;
8399   return node;
8400 }
8401
8402 /* Merge the two parts of a qualified name into LEFT.  Set the
8403    location information of the resulting node to LOCATION, usually
8404    inherited from the location information of the `.' operator. */
8405
8406 static tree
8407 make_qualified_name (left, right, location)
8408      tree left, right;
8409      int location;
8410 {
8411 #ifdef USE_COMPONENT_REF
8412   tree node = build (COMPONENT_REF, NULL_TREE, left, right);
8413   EXPR_WFL_LINECOL (node) = location;
8414   return node;
8415 #else
8416   tree left_id = EXPR_WFL_NODE (left);
8417   tree right_id = EXPR_WFL_NODE (right);
8418   tree wfl, merge;
8419
8420   merge = merge_qualified_name (left_id, right_id);
8421
8422   /* Left wasn't qualified and is now qualified */
8423   if (!QUALIFIED_P (left_id))
8424     {
8425       tree wfl = build_expr_wfl (left_id, ctxp->filename, 0, 0);
8426       EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (left);
8427       EXPR_WFL_QUALIFICATION (left) = build_tree_list (wfl, NULL_TREE);
8428     }
8429   
8430   wfl = build_expr_wfl (right_id, ctxp->filename, 0, 0);
8431   EXPR_WFL_LINECOL (wfl) = location;
8432   chainon (EXPR_WFL_QUALIFICATION (left), build_tree_list (wfl, NULL_TREE));
8433
8434   EXPR_WFL_NODE (left) = merge;
8435   return left;
8436 #endif
8437 }
8438
8439 /* Extract the last identifier component of the qualified in WFL. The
8440    last identifier is removed from the linked list */
8441
8442 static tree
8443 cut_identifier_in_qualified (wfl)
8444      tree wfl;
8445 {
8446   tree q;
8447   tree previous = NULL_TREE;
8448   for (q = EXPR_WFL_QUALIFICATION (wfl); ; previous = q, q = TREE_CHAIN (q))
8449     if (!TREE_CHAIN (q))
8450       {
8451         if (!previous)
8452           fatal ("Operating on a non qualified qualified WFL - cut_identifier_in_qualified");
8453         TREE_CHAIN (previous) = NULL_TREE;
8454         return TREE_PURPOSE (q);
8455       }
8456 }
8457
8458 /* Resolve the expression name NAME. Return its decl.  */
8459
8460 static tree
8461 resolve_expression_name (id, orig)
8462      tree id;
8463      tree *orig;
8464 {
8465   tree name = EXPR_WFL_NODE (id);
8466   tree decl;
8467
8468   /* 6.5.5.1: Simple expression names */
8469   if (!PRIMARY_P (id) && !QUALIFIED_P (name))
8470     {
8471       /* 15.13.1: NAME can appear within the scope of a local variable
8472          declaration */
8473       if ((decl = IDENTIFIER_LOCAL_VALUE (name)))
8474         return decl;
8475
8476       /* 15.13.1: NAME can appear within a class declaration */
8477       else 
8478         {
8479           decl = lookup_field_wrapper (current_class, name);
8480
8481           /* Last chance: if we're within the context of an inner
8482              class, we might be trying to access a local variable
8483              defined in an outer context. We try to look for it
8484              now. */
8485           if (!decl && INNER_CLASS_TYPE_P (current_class))
8486             {
8487               char *alias_buffer;
8488               MANGLE_OUTER_LOCAL_VARIABLE_NAME (alias_buffer, name);
8489               name = get_identifier (alias_buffer);
8490               decl = lookup_field_wrapper (current_class, name);
8491               if (decl)
8492                 FIELD_LOCAL_ALIAS_USED (decl) = 1;
8493             }
8494
8495           if (decl)
8496             {
8497               tree access = NULL_TREE;
8498               int fs = FIELD_STATIC (decl);
8499               /* Instance variable (8.3.1.1) can't appear within
8500                  static method, static initializer or initializer for
8501                  a static variable. */
8502               if (!fs && METHOD_STATIC (current_function_decl))
8503                 {
8504                   static_ref_err (id, name, current_class);
8505                   return error_mark_node;
8506                 }
8507               /* Instance variables can't appear as an argument of
8508                  an explicit constructor invocation */
8509               if (!fs && ctxp->explicit_constructor_p)
8510                 {
8511                   parse_error_context
8512                     (id, "Can't reference `%s' before the superclass constructor has been called", IDENTIFIER_POINTER (name));
8513                   return error_mark_node;
8514                 }
8515
8516               /* If we're processing an inner class and we're trying
8517                  to access a field belonging to an outer class, build
8518                  the access to the field */
8519               if (!fs && outer_field_access_p (current_class, decl))
8520                 return build_outer_field_access (id, decl);
8521
8522               /* Otherwise build what it takes to access the field */
8523               access = build_field_ref ((fs ? NULL_TREE : current_this),
8524                                         DECL_CONTEXT (decl), name);
8525               if (fs && !flag_emit_class_files && !flag_emit_xref)
8526                 access = build_class_init (DECL_CONTEXT (access), access);
8527               /* We may be asked to save the real field access node */
8528               if (orig)
8529                 *orig = access;
8530               /* And we return what we got */
8531               return access;
8532             }
8533           /* Fall down to error report on undefined variable */
8534         }
8535     }
8536   /* 6.5.5.2 Qualified Expression Names */
8537   else
8538     {
8539       if (orig)
8540         *orig = NULL_TREE;
8541       qualify_ambiguous_name (id);
8542       /* 15.10.1 Field Access Using a Primary and/or Expression Name */
8543       /* 15.10.2: Accessing Superclass Members using super */
8544       return resolve_field_access (id, orig, NULL);
8545     }
8546
8547   /* We've got an error here */
8548   parse_error_context (id, "Undefined variable `%s'", 
8549                        IDENTIFIER_POINTER (name));
8550
8551   return error_mark_node;
8552 }
8553
8554 static void
8555 static_ref_err (wfl, field_id, class_type)
8556     tree wfl, field_id, class_type;
8557 {
8558   parse_error_context 
8559     (wfl, 
8560      "Can't make a static reference to nonstatic variable `%s' in class `%s'",
8561      IDENTIFIER_POINTER (field_id), 
8562      IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class_type))));
8563 }
8564
8565 /* 15.10.1 Field Acess Using a Primary and/or Expression Name.
8566    We return something suitable to generate the field access. We also
8567    return the field decl in FIELD_DECL and its type in FIELD_TYPE.  If
8568    recipient's address can be null. */
8569
8570 static tree
8571 resolve_field_access (qual_wfl, field_decl, field_type)
8572      tree qual_wfl;
8573      tree *field_decl, *field_type;
8574 {
8575   int is_static = 0;
8576   tree field_ref;
8577   tree decl, where_found, type_found;
8578
8579   if (resolve_qualified_expression_name (qual_wfl, &decl,
8580                                          &where_found, &type_found))
8581     return error_mark_node;
8582
8583   /* Resolve the LENGTH field of an array here */
8584   if (DECL_NAME (decl) == length_identifier_node && TYPE_ARRAY_P (type_found)
8585       && ! flag_emit_class_files && ! flag_emit_xref)
8586     {
8587       tree length = build_java_array_length_access (where_found);
8588       field_ref =
8589         build_java_arraynull_check (type_found, length, int_type_node);
8590     }
8591   /* We might have been trying to resolve field.method(). In which
8592      case, the resolution is over and decl is the answer */
8593   else if (JDECL_P (decl) && IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)) == decl)
8594     field_ref = decl;
8595   else if (JDECL_P (decl))
8596     {
8597       int static_final_found = 0;
8598       if (!type_found)
8599         type_found = DECL_CONTEXT (decl);
8600       is_static = JDECL_P (decl) && FIELD_STATIC (decl);
8601       if (FIELD_FINAL (decl) 
8602           && JPRIMITIVE_TYPE_P (TREE_TYPE (decl))
8603           && DECL_LANG_SPECIFIC (decl)
8604           && DECL_INITIAL (decl))
8605         {
8606           field_ref = DECL_INITIAL (decl);
8607           static_final_found = 1;
8608         }
8609       else
8610         field_ref = build_field_ref ((is_static && !flag_emit_xref? 
8611                                       NULL_TREE : where_found), 
8612                                      type_found, DECL_NAME (decl));
8613       if (field_ref == error_mark_node)
8614         return error_mark_node;
8615       if (is_static && !static_final_found 
8616           && !flag_emit_class_files && !flag_emit_xref)
8617         field_ref = build_class_init (type_found, field_ref);
8618     }
8619   else
8620     field_ref = decl;
8621
8622   if (field_decl)
8623     *field_decl = decl;
8624   if (field_type)
8625     *field_type = (QUAL_DECL_TYPE (decl) ? 
8626                    QUAL_DECL_TYPE (decl) : TREE_TYPE (decl));
8627   return field_ref;
8628 }
8629
8630 /* If NODE is an access to f static field, strip out the class
8631    initialization part and return the field decl, otherwise, return
8632    NODE. */
8633
8634 static tree
8635 strip_out_static_field_access_decl (node)
8636     tree node;
8637 {
8638   if (TREE_CODE (node) == COMPOUND_EXPR)
8639     {
8640       tree op1 = TREE_OPERAND (node, 1);
8641       if (TREE_CODE (op1) == COMPOUND_EXPR)
8642          {
8643            tree call = TREE_OPERAND (op1, 0);
8644            if (TREE_CODE (call) == CALL_EXPR
8645                && TREE_CODE (TREE_OPERAND (call, 0)) == ADDR_EXPR
8646                && TREE_OPERAND (TREE_OPERAND (call, 0), 0)
8647                == soft_initclass_node)
8648              return TREE_OPERAND (op1, 1);
8649          }
8650       else if (JDECL_P (op1))
8651         return op1;
8652     }
8653   return node;
8654 }
8655
8656 /* 6.5.5.2: Qualified Expression Names */
8657
8658 static int
8659 resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
8660      tree wfl;
8661      tree *found_decl, *type_found, *where_found;
8662 {
8663   int from_type = 0;            /* Field search initiated from a type */
8664   int from_super = 0, from_cast = 0, from_qualified_this = 0;
8665   int previous_call_static = 0;
8666   int is_static;
8667   tree decl = NULL_TREE, type = NULL_TREE, q;
8668   /* For certain for of inner class instantiation */
8669   tree saved_current, saved_this;               
8670 #define RESTORE_THIS_AND_CURRENT_CLASS                          \
8671   { current_class = saved_current; current_this = saved_this;}
8672
8673   *type_found = *where_found = NULL_TREE;
8674
8675   for (q = EXPR_WFL_QUALIFICATION (wfl); q; q = TREE_CHAIN (q))
8676     {
8677       tree qual_wfl = QUAL_WFL (q);
8678       tree ret_decl;            /* for EH checking */
8679       int location;             /* for EH checking */
8680
8681       /* 15.10.1 Field Access Using a Primary */
8682       switch (TREE_CODE (qual_wfl))
8683         {
8684         case CALL_EXPR:
8685         case NEW_CLASS_EXPR:
8686           /* If the access to the function call is a non static field,
8687              build the code to access it. */
8688           if (JDECL_P (decl) && !FIELD_STATIC (decl))
8689             {
8690               decl = maybe_access_field (decl, *where_found, 
8691                                          DECL_CONTEXT (decl));
8692               if (decl == error_mark_node)
8693                 return 1;
8694             }
8695
8696           /* And code for the function call */
8697           if (complete_function_arguments (qual_wfl))
8698             return 1;
8699
8700           /* We might have to setup a new current class and a new this
8701              for the search of an inner class, relative to the type of
8702              a expression resolved as `decl'. The current values are
8703              saved and restored shortly after */
8704           saved_current = current_class;
8705           saved_this = current_this;
8706           if (decl && TREE_CODE (qual_wfl) == NEW_CLASS_EXPR)
8707             {
8708               current_class = type;
8709               current_this = decl;
8710             }
8711
8712           if (from_super && TREE_CODE (qual_wfl) == CALL_EXPR)
8713             CALL_USING_SUPER (qual_wfl) = 1;
8714           location = (TREE_CODE (qual_wfl) == CALL_EXPR ?
8715                       EXPR_WFL_LINECOL (TREE_OPERAND (qual_wfl, 0)) : 0);
8716           *where_found = patch_method_invocation (qual_wfl, decl, type, 
8717                                                   &is_static, &ret_decl);
8718           if (*where_found == error_mark_node)
8719             {
8720               RESTORE_THIS_AND_CURRENT_CLASS;
8721               return 1;
8722             }
8723           *type_found = type = QUAL_DECL_TYPE (*where_found);
8724
8725           /* If we're creating an inner class instance, check for that
8726              an enclosing instance is in scope */
8727           if (TREE_CODE (qual_wfl) == NEW_CLASS_EXPR
8728               && INNER_ENCLOSING_SCOPE_CHECK (type))
8729             {
8730               parse_error_context 
8731                 (qual_wfl, "No enclosing instance for inner class `%s' is in scope%s",
8732                  lang_printable_name (type, 0),
8733                  (!current_this ? "" :
8734                   "; an explicit one must be provided when creating this inner class"));
8735               RESTORE_THIS_AND_CURRENT_CLASS;
8736               return 1;
8737             }
8738
8739           /* In case we had to change then to resolve a inner class
8740              instantiation using a primary qualified by a `new' */
8741           RESTORE_THIS_AND_CURRENT_CLASS;
8742
8743           /* EH check */
8744           if (location)
8745             check_thrown_exceptions (location, ret_decl);
8746
8747           /* If the previous call was static and this one is too,
8748              build a compound expression to hold the two (because in
8749              that case, previous function calls aren't transported as
8750              forcoming function's argument. */
8751           if (previous_call_static && is_static)
8752             {
8753               decl = build (COMPOUND_EXPR, type, decl, *where_found);
8754               TREE_SIDE_EFFECTS (decl) = 1;
8755             }
8756           else
8757             {
8758               previous_call_static = is_static;
8759               decl = *where_found;
8760             }
8761           from_type = 0;
8762           continue;
8763
8764         case NEW_ARRAY_EXPR:
8765         case NEW_ANONYMOUS_ARRAY_EXPR:
8766           *where_found = decl = java_complete_tree (qual_wfl);
8767           if (decl == error_mark_node)
8768             return 1;
8769           *type_found = type = QUAL_DECL_TYPE (decl);
8770           CLASS_LOADED_P (type) = 1;
8771           continue;
8772
8773         case CONVERT_EXPR:
8774           *where_found = decl = java_complete_tree (qual_wfl);
8775           if (decl == error_mark_node)
8776             return 1;
8777           *type_found = type = QUAL_DECL_TYPE (decl);
8778           from_cast = 1;
8779           continue;
8780
8781         case CONDITIONAL_EXPR:
8782         case STRING_CST:
8783         case MODIFY_EXPR:
8784           *where_found = decl = java_complete_tree (qual_wfl);
8785           if (decl == error_mark_node)
8786             return 1;
8787           *type_found = type = QUAL_DECL_TYPE (decl);
8788           continue;
8789
8790         case ARRAY_REF:
8791           /* If the access to the function call is a non static field,
8792              build the code to access it. */
8793           if (JDECL_P (decl) && !FIELD_STATIC (decl))
8794             {
8795               decl = maybe_access_field (decl, *where_found, type);
8796               if (decl == error_mark_node)
8797                 return 1;
8798             }
8799           /* And code for the array reference expression */
8800           decl = java_complete_tree (qual_wfl);
8801           if (decl == error_mark_node)
8802             return 1;
8803           type = QUAL_DECL_TYPE (decl);
8804           continue;
8805
8806         case PLUS_EXPR:
8807           if ((decl = java_complete_tree (qual_wfl)) == error_mark_node)
8808             return 1;
8809           if ((type = patch_string (decl)))
8810             decl = type;
8811           *where_found = QUAL_RESOLUTION (q) = decl;
8812           *type_found = type = TREE_TYPE (decl);
8813           break;
8814
8815         case CLASS_LITERAL:
8816           if ((decl = java_complete_tree (qual_wfl)) == error_mark_node)
8817             return 1;
8818           *where_found = QUAL_RESOLUTION (q) = decl;
8819           *type_found = type = TREE_TYPE (decl);
8820           break;
8821
8822         default:
8823           /* Fix for -Wall Just go to the next statement. Don't
8824              continue */
8825           break;
8826         }
8827
8828       /* If we fall here, we weren't processing a (static) function call. */
8829       previous_call_static = 0;
8830
8831       /* It can be the keyword THIS */
8832       if (EXPR_WFL_NODE (qual_wfl) == this_identifier_node)
8833         {
8834           if (!current_this)
8835             {
8836               parse_error_context 
8837                 (wfl, "Keyword `this' used outside allowed context");
8838               return 1;
8839             }
8840           if (ctxp->explicit_constructor_p)
8841             {
8842               parse_error_context (wfl, "Can't reference `this' before the superclass constructor has been called");
8843               return 1;
8844             }
8845           /* We have to generate code for intermediate acess */
8846           if (!from_type || TREE_TYPE (TREE_TYPE (current_this)) == type)
8847             {
8848               *where_found = decl = current_this;
8849               *type_found = type = QUAL_DECL_TYPE (decl);
8850             }
8851           /* We're trying to access the this from somewhere else... */
8852           else
8853             {
8854               *where_found = decl = build_current_thisn (type);
8855               from_qualified_this = 1;
8856             }
8857
8858           from_type = 0;
8859           continue;
8860         }
8861
8862       /* 15.10.2 Accessing Superclass Members using SUPER */
8863       if (EXPR_WFL_NODE (qual_wfl) == super_identifier_node)
8864         {
8865           tree node;
8866           /* Check on the restricted use of SUPER */
8867           if (METHOD_STATIC (current_function_decl)
8868               || current_class == object_type_node)
8869             {
8870               parse_error_context 
8871                 (wfl, "Keyword `super' used outside allowed context");
8872               return 1;
8873             }
8874           /* Otherwise, treat SUPER as (SUPER_CLASS)THIS */
8875           node = build_cast (EXPR_WFL_LINECOL (qual_wfl), 
8876                              CLASSTYPE_SUPER (current_class),
8877                              build_this (EXPR_WFL_LINECOL (qual_wfl)));
8878           *where_found = decl = java_complete_tree (node);
8879           if (decl == error_mark_node)
8880             return 1;
8881           *type_found = type = QUAL_DECL_TYPE (decl);
8882           from_super = from_type = 1;
8883           continue;
8884         }
8885
8886       /* 15.13.1: Can't search for field name in packages, so we
8887          assume a variable/class name was meant. */
8888       if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
8889         {
8890           tree name = resolve_package (wfl, &q);
8891           if (name)
8892             {
8893               tree list;
8894               *where_found = decl = resolve_no_layout (name, qual_wfl);
8895               /* We wan't to be absolutely that the class is laid
8896                  out. We're going to search something inside it. */
8897               *type_found = type = TREE_TYPE (decl);
8898               layout_class (type);
8899               from_type = 1;
8900
8901               /* Fix them all the way down, if any are left. */
8902               if (q)
8903                 {
8904                   list = TREE_CHAIN (q);
8905                   while (list)
8906                     {
8907                       RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (list)) = 1;
8908                       RESOLVE_PACKAGE_NAME_P (QUAL_WFL (list)) = 0;
8909                       list = TREE_CHAIN (list);
8910                     }
8911                 }
8912             }
8913           else
8914             {
8915               if (from_super || from_cast)
8916                 parse_error_context 
8917                   ((from_cast ? qual_wfl : wfl),
8918                    "No variable `%s' defined in class `%s'",
8919                    IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
8920                    lang_printable_name (type, 0));
8921               else
8922                 parse_error_context
8923                   (qual_wfl, "Undefined variable or class name: `%s'",
8924                    IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)));
8925               return 1;
8926             }
8927         }
8928
8929       /* We have a type name. It's been already resolved when the
8930          expression was qualified. */
8931       else if (RESOLVE_TYPE_NAME_P (qual_wfl))
8932         {
8933           if (!(decl = QUAL_RESOLUTION (q)))
8934             return 1;           /* Error reported already */
8935
8936           /* Sneak preview. If next we see a `new', we're facing a
8937              qualification with resulted in a type being selected
8938              instead of a field.  Report the error */
8939           if(TREE_CHAIN (q) 
8940              && TREE_CODE (TREE_PURPOSE (TREE_CHAIN (q))) == NEW_CLASS_EXPR)
8941             {
8942               parse_error_context (qual_wfl, "Undefined variable `%s'",
8943                                    IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
8944               return 1;
8945             }
8946
8947           if (not_accessible_p (TREE_TYPE (decl), decl, 0))
8948             {
8949               parse_error_context 
8950                 (qual_wfl, "Can't access %s field `%s.%s' from `%s'",
8951                  java_accstring_lookup (get_access_flags_from_decl (decl)),
8952                  GET_TYPE_NAME (type),
8953                  IDENTIFIER_POINTER (DECL_NAME (decl)),
8954                  IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
8955               return 1;
8956             }
8957           check_deprecation (qual_wfl, decl);
8958
8959           type = TREE_TYPE (decl);
8960           from_type = 1;
8961         }
8962       /* We resolve and expression name */
8963       else 
8964         {
8965           tree field_decl = NULL_TREE;
8966
8967           /* If there exists an early resolution, use it. That occurs
8968              only once and we know that there are more things to
8969              come. Don't do that when processing something after SUPER
8970              (we need more thing to be put in place below */
8971           if (!from_super && QUAL_RESOLUTION (q))
8972             {
8973               decl = QUAL_RESOLUTION (q);
8974               if (!type)
8975                 {
8976                   if (TREE_CODE (decl) == FIELD_DECL && !FIELD_STATIC (decl))
8977                     {
8978                       if (current_this)
8979                         *where_found = current_this;
8980                       else
8981                         {
8982                           static_ref_err (qual_wfl, DECL_NAME (decl),
8983                                           current_class);
8984                           return 1;
8985                         }
8986                     }
8987                   else
8988                     {
8989                       *where_found = TREE_TYPE (decl);
8990                       if (TREE_CODE (*where_found) == POINTER_TYPE)
8991                         *where_found = TREE_TYPE (*where_found);
8992                     }
8993                 }
8994             }
8995
8996           /* We have to search for a field, knowing the type of its
8997              container. The flag FROM_TYPE indicates that we resolved
8998              the last member of the expression as a type name, which
8999              means that for the resolution of this field, we'll look
9000              for other errors than if it was resolved as a member of
9001              an other field. */
9002           else
9003             {
9004               int is_static;
9005               tree field_decl_type; /* For layout */
9006
9007               if (!from_type && !JREFERENCE_TYPE_P (type))
9008                 {
9009                   parse_error_context 
9010                     (qual_wfl, "Attempt to reference field `%s' in `%s %s'",
9011                      IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
9012                      lang_printable_name (type, 0),
9013                      IDENTIFIER_POINTER (DECL_NAME (field_decl)));
9014                   return 1;
9015                 }
9016               
9017               field_decl = lookup_field_wrapper (type,
9018                                                  EXPR_WFL_NODE (qual_wfl));
9019               if (field_decl == NULL_TREE)
9020                 {
9021                   parse_error_context 
9022                     (qual_wfl, "No variable `%s' defined in type `%s'",
9023                      IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)), 
9024                      GET_TYPE_NAME (type));
9025                   return 1;
9026                 }
9027               if (field_decl == error_mark_node)
9028                 return 1;
9029
9030               /* Layout the type of field_decl, since we may need
9031                  it. Don't do primitive types or loaded classes. The
9032                  situation of non primitive arrays may not handled
9033                  properly here. FIXME */
9034               if (TREE_CODE (TREE_TYPE (field_decl)) == POINTER_TYPE)
9035                 field_decl_type = TREE_TYPE (TREE_TYPE (field_decl));
9036               else
9037                 field_decl_type = TREE_TYPE (field_decl);
9038               if (!JPRIMITIVE_TYPE_P (field_decl_type) 
9039                   && !CLASS_LOADED_P (field_decl_type)
9040                   && !TYPE_ARRAY_P (field_decl_type))
9041                 resolve_and_layout (field_decl_type, NULL_TREE);
9042               if (TYPE_ARRAY_P (field_decl_type))
9043                 CLASS_LOADED_P (field_decl_type) = 1;
9044               
9045               /* Check on accessibility here */
9046               if (not_accessible_p (type, field_decl, from_super))
9047                 {
9048                   parse_error_context 
9049                     (qual_wfl,
9050                      "Can't access %s field `%s.%s' from `%s'",
9051                      java_accstring_lookup 
9052                        (get_access_flags_from_decl (field_decl)),
9053                      GET_TYPE_NAME (type),
9054                      IDENTIFIER_POINTER (DECL_NAME (field_decl)),
9055                      IDENTIFIER_POINTER 
9056                        (DECL_NAME (TYPE_NAME (current_class))));
9057                   return 1;
9058                 }
9059               check_deprecation (qual_wfl, field_decl);
9060               
9061               /* There are things to check when fields are accessed
9062                  from type. There are no restrictions on a static
9063                  declaration of the field when it is accessed from an
9064                  interface */
9065               is_static = FIELD_STATIC (field_decl);
9066               if (!from_super && from_type 
9067                   && !TYPE_INTERFACE_P (type) 
9068                   && !is_static 
9069                   && (current_function_decl 
9070                       && METHOD_STATIC (current_function_decl)))
9071                 {
9072                   static_ref_err (qual_wfl, EXPR_WFL_NODE (qual_wfl), type);
9073                   return 1;
9074                 }
9075               from_cast = from_super = 0;
9076
9077               /* It's an access from a type but it isn't static, we
9078                  make it relative to `this'. */
9079               if (!is_static && from_type)
9080                 decl = current_this;
9081
9082               /* If we need to generate something to get a proper
9083                  handle on what this field is accessed from, do it
9084                  now. */
9085               if (!is_static)
9086                 {
9087                   decl = maybe_access_field (decl, *where_found, *type_found);
9088                   if (decl == error_mark_node)
9089                     return 1;
9090                 }
9091
9092               /* We want to keep the location were found it, and the type
9093                  we found. */
9094               *where_found = decl;
9095               *type_found = type;
9096
9097               /* Generate the correct expression for field access from
9098                  qualified this */
9099               if (from_qualified_this)
9100                 {
9101                   field_decl = build_outer_field_access (qual_wfl, field_decl);
9102                   from_qualified_this = 0;
9103                 }
9104
9105               /* This is the decl found and eventually the next one to
9106                  search from */
9107               decl = field_decl;
9108             }
9109           from_type = 0;
9110           type = QUAL_DECL_TYPE (decl);
9111
9112           /* Sneak preview. If decl is qualified by a `new', report
9113              the error here to be accurate on the peculiar construct */
9114           if (TREE_CHAIN (q) 
9115               && TREE_CODE (TREE_PURPOSE (TREE_CHAIN (q))) == NEW_CLASS_EXPR
9116               && !JREFERENCE_TYPE_P (type))
9117             {
9118               parse_error_context (qual_wfl, "Attempt to reference field `new' in a `%s'", 
9119                                    lang_printable_name (type, 0));
9120               return 1;
9121             }
9122         }
9123       /* `q' might have changed due to a after package resolution
9124          re-qualification */
9125       if (!q)
9126         break;
9127     }
9128   *found_decl = decl;
9129   return 0;
9130 }
9131
9132 /* 6.6 Qualified name and access control. Returns 1 if MEMBER (a decl)
9133    can't be accessed from REFERENCE (a record type). */
9134
9135 static int
9136 not_accessible_p (reference, member, from_super)
9137      tree reference, member;
9138      int from_super;
9139 {
9140   int access_flag = get_access_flags_from_decl (member);
9141
9142   /* Access always granted for members declared public */
9143   if (access_flag & ACC_PUBLIC)
9144     return 0;
9145   
9146   /* Check access on protected members */
9147   if (access_flag & ACC_PROTECTED)
9148     {
9149       /* Access granted if it occurs from within the package
9150          containing the class in which the protected member is
9151          declared */
9152       if (class_in_current_package (DECL_CONTEXT (member)))
9153         return 0;
9154
9155       /* If accessed with the form `super.member', then access is granted */
9156       if (from_super)
9157         return 0;
9158
9159       /* Otherwise, access is granted if occuring from the class where
9160          member is declared or a subclass of it */
9161       if (inherits_from_p (reference, DECL_CONTEXT (member)))
9162         return 0;
9163       return 1;
9164     }
9165
9166   /* Check access on private members. Access is granted only if it
9167      occurs from within the class in which it is declared. Exceptions
9168      are accesses from inner-classes. This section is probably not
9169      complete. FIXME */
9170   if (access_flag & ACC_PRIVATE)
9171     return (current_class == DECL_CONTEXT (member) ? 0 : 
9172             (INNER_CLASS_TYPE_P (current_class) ? 0 : 1));
9173
9174   /* Default access are permitted only when occuring within the
9175      package in which the type (REFERENCE) is declared. In other words,
9176      REFERENCE is defined in the current package */
9177   if (ctxp->package)
9178     return !class_in_current_package (reference);
9179
9180   /* Otherwise, access is granted */
9181   return 0;
9182 }
9183
9184 /* Test deprecated decl access.  */
9185 static void
9186 check_deprecation (wfl, decl)
9187      tree wfl, decl;
9188 {
9189   const char *file = DECL_SOURCE_FILE (decl);
9190   /* Complain if the field is deprecated and the file it was defined
9191      in isn't compiled at the same time the file which contains its
9192      use is */
9193   if (DECL_DEPRECATED (decl) 
9194       && !IS_A_COMMAND_LINE_FILENAME_P (get_identifier (file)))
9195     {
9196       char the [20];
9197       switch (TREE_CODE (decl))
9198         {
9199         case FUNCTION_DECL:
9200           strcpy (the, "method");
9201           break;
9202         case FIELD_DECL:
9203           strcpy (the, "field");
9204           break;
9205         case TYPE_DECL:
9206           strcpy (the, "class");
9207           break;
9208         default:
9209           fatal ("unexpected DECL code - check_deprecation");
9210         }
9211       parse_warning_context 
9212         (wfl, "The %s `%s' in class `%s' has been deprecated", 
9213          the, lang_printable_name (decl, 0),
9214          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)))));
9215     }
9216 }
9217
9218 /* Returns 1 if class was declared in the current package, 0 otherwise */
9219
9220 static int
9221 class_in_current_package (class)
9222      tree class;
9223 {
9224   static tree cache = NULL_TREE;
9225   int qualified_flag;
9226   tree left;
9227
9228   if (cache == class)
9229     return 1;
9230
9231   qualified_flag = QUALIFIED_P (DECL_NAME (TYPE_NAME (class)));
9232
9233   /* If the current package is empty and the name of CLASS is
9234      qualified, class isn't in the current package.  If there is a
9235      current package and the name of the CLASS is not qualified, class
9236      isn't in the current package */
9237   if ((!ctxp->package && qualified_flag) || (ctxp->package && !qualified_flag))
9238     return 0;
9239
9240   /* If there is not package and the name of CLASS isn't qualified,
9241      they belong to the same unnamed package */
9242   if (!ctxp->package && !qualified_flag)
9243     return 1;
9244
9245   /* Compare the left part of the name of CLASS with the package name */
9246   breakdown_qualified (&left, NULL, DECL_NAME (TYPE_NAME (class)));
9247   if (ctxp->package == left)
9248     {
9249       cache = class;
9250       return 1;
9251     }
9252   return 0;
9253 }
9254
9255 /* This function may generate code to access DECL from WHERE. This is
9256    done only if certain conditions meet.  */
9257
9258 static tree
9259 maybe_access_field (decl, where, type)
9260   tree decl, where, type;
9261 {
9262   if (TREE_CODE (decl) == FIELD_DECL && decl != current_this
9263       && !FIELD_STATIC (decl))
9264     decl = build_field_ref (where ? where : current_this, 
9265                             (type ? type : DECL_CONTEXT (decl)),
9266                             DECL_NAME (decl));
9267   return decl;
9268 }
9269
9270 /* Build a method invocation, by patching PATCH. If non NULL
9271    and according to the situation, PRIMARY and WHERE may be
9272    used. IS_STATIC is set to 1 if the invoked function is static. */
9273
9274 static tree
9275 patch_method_invocation (patch, primary, where, is_static, ret_decl)
9276      tree patch, primary, where;
9277      int *is_static;
9278      tree *ret_decl;
9279 {
9280   tree wfl = TREE_OPERAND (patch, 0);
9281   tree args = TREE_OPERAND (patch, 1);
9282   tree name = EXPR_WFL_NODE (wfl);
9283   tree list;
9284   int is_static_flag = 0;
9285   int is_super_init = 0;
9286   tree this_arg = NULL_TREE;
9287   
9288   /* Should be overriden if everything goes well. Otherwise, if
9289      something fails, it should keep this value. It stop the
9290      evaluation of a bogus assignment. See java_complete_tree,
9291      MODIFY_EXPR: for the reasons why we sometimes want to keep on
9292      evaluating an assignment */
9293   TREE_TYPE (patch) = error_mark_node;
9294
9295   /* Since lookup functions are messing with line numbers, save the
9296      context now.  */
9297   java_parser_context_save_global ();
9298
9299   /* 15.11.1: Compile-Time Step 1: Determine Class or Interface to Search */
9300
9301   /* Resolution of qualified name, excluding constructors */
9302   if (QUALIFIED_P (name) && !CALL_CONSTRUCTOR_P (patch))
9303     {
9304       tree identifier, identifier_wfl, type, resolved;
9305       /* Extract the last IDENTIFIER of the qualified
9306          expression. This is a wfl and we will use it's location
9307          data during error report. */
9308       identifier_wfl = cut_identifier_in_qualified (wfl);
9309       identifier = EXPR_WFL_NODE (identifier_wfl);
9310       
9311       /* Given the context, IDENTIFIER is syntactically qualified
9312          as a MethodName. We need to qualify what's before */
9313       qualify_ambiguous_name (wfl);
9314       resolved = resolve_field_access (wfl, NULL, NULL);
9315
9316       if (resolved == error_mark_node)
9317         PATCH_METHOD_RETURN_ERROR ();
9318
9319       type = GET_SKIP_TYPE (resolved);
9320       resolve_and_layout (type, NULL_TREE);
9321       list = lookup_method_invoke (0, identifier_wfl, type, identifier, args);
9322       args = nreverse (args);
9323
9324       /* We're resolving a call from a type */
9325       if (TREE_CODE (resolved) == TYPE_DECL)
9326         {
9327           if (CLASS_INTERFACE (resolved))
9328             {
9329               parse_error_context
9330                 (identifier_wfl,
9331                 "Can't make static reference to method `%s' in interface `%s'",
9332                  IDENTIFIER_POINTER (identifier), 
9333                  IDENTIFIER_POINTER (name));
9334               PATCH_METHOD_RETURN_ERROR ();
9335             }
9336           if (list && !METHOD_STATIC (list))
9337             {
9338               char *fct_name = xstrdup (lang_printable_name (list, 0));
9339               parse_error_context 
9340                 (identifier_wfl,
9341                  "Can't make static reference to method `%s %s' in class `%s'",
9342                  lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0), 
9343                  fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
9344               free (fct_name);
9345               PATCH_METHOD_RETURN_ERROR ();
9346             }
9347         }
9348       else
9349         this_arg = primary = resolved;
9350       
9351       /* IDENTIFIER_WFL will be used to report any problem further */
9352       wfl = identifier_wfl;
9353     }
9354   /* Resolution of simple names, names generated after a primary: or
9355      constructors */
9356   else
9357     {
9358       tree class_to_search = NULL_TREE;
9359       int lc;                   /* Looking for Constructor */
9360       
9361       /* We search constructor in their target class */
9362       if (CALL_CONSTRUCTOR_P (patch))
9363         {
9364           if (TREE_CODE (patch) == NEW_CLASS_EXPR)
9365             class_to_search = EXPR_WFL_NODE (wfl);
9366           else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) == 
9367                    this_identifier_node)
9368             class_to_search = NULL_TREE;
9369           else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) ==
9370                    super_identifier_node)
9371             {
9372               is_super_init = 1;
9373               if (CLASSTYPE_SUPER (current_class))
9374                 class_to_search = 
9375                   DECL_NAME (TYPE_NAME (CLASSTYPE_SUPER (current_class)));
9376               else
9377                 {
9378                   parse_error_context (wfl, "Can't invoke super constructor on java.lang.Object");
9379                   PATCH_METHOD_RETURN_ERROR ();
9380                 }
9381             }
9382
9383           /* Class to search is NULL if we're searching the current one */
9384           if (class_to_search)
9385             {
9386               class_to_search = resolve_and_layout (class_to_search, wfl);
9387
9388               if (!class_to_search)
9389                 {
9390                   parse_error_context 
9391                     (wfl, "Class `%s' not found in type declaration",
9392                      IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
9393                   PATCH_METHOD_RETURN_ERROR ();
9394                 }
9395               
9396               /* Can't instantiate an abstract class, but we can
9397                  invoke it's constructor. It's use within the `new'
9398                  context is denied here. */
9399               if (CLASS_ABSTRACT (class_to_search) 
9400                   && TREE_CODE (patch) == NEW_CLASS_EXPR)
9401                 {
9402                   parse_error_context 
9403                     (wfl, "Class `%s' is an abstract class. It can't be instantiated",
9404                      IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
9405                   PATCH_METHOD_RETURN_ERROR ();
9406                 }
9407
9408               class_to_search = TREE_TYPE (class_to_search);
9409             }
9410           else
9411             class_to_search = current_class;
9412           lc = 1;
9413         }
9414       /* This is a regular search in the local class, unless an
9415          alternate class is specified. */
9416       else
9417         {
9418           class_to_search = (where ? where : current_class);
9419           lc = 0;
9420         }
9421
9422       /* NAME is a simple identifier or comes from a primary. Search
9423          in the class whose declaration contain the method being
9424          invoked. */
9425       resolve_and_layout (class_to_search, NULL_TREE);
9426
9427       list = lookup_method_invoke (lc, wfl, class_to_search, name, args);
9428       /* Don't continue if no method were found, as the next statement
9429          can't be executed then. */
9430       if (!list)
9431         PATCH_METHOD_RETURN_ERROR ();
9432
9433       /* Check for static reference if non static methods */
9434       if (check_for_static_method_reference (wfl, patch, list, 
9435                                              class_to_search, primary))
9436         PATCH_METHOD_RETURN_ERROR ();
9437
9438       /* Check for inner classes creation from illegal contexts */
9439       if (lc && (INNER_CLASS_TYPE_P (class_to_search)
9440                  && !CLASS_STATIC (TYPE_NAME (class_to_search)))
9441           && INNER_ENCLOSING_SCOPE_CHECK (class_to_search))
9442         {
9443           parse_error_context 
9444             (wfl, "No enclosing instance for inner class `%s' is in scope%s",
9445              lang_printable_name (class_to_search, 0),
9446              (!current_this ? "" :
9447               "; an explicit one must be provided when creating this inner class"));
9448           PATCH_METHOD_RETURN_ERROR ();
9449         }
9450
9451       /* Non static methods are called with the current object extra
9452          argument. If patch a `new TYPE()', the argument is the value
9453          returned by the object allocator. If method is resolved as a
9454          primary, use the primary otherwise use the current THIS. */
9455       args = nreverse (args);
9456       if (TREE_CODE (patch) != NEW_CLASS_EXPR)
9457         {
9458           this_arg = primary ? primary : current_this;
9459
9460           /* If we're using an access method, things are different.
9461              There are two familly of cases:
9462
9463              1) We're not generating bytecodes:
9464
9465              - LIST is non static. It's invocation is transformed from
9466                x(a1,...,an) into this$<n>.x(a1,....an).
9467              - LIST is static. It's invocation is transformed from
9468                x(a1,...,an) into TYPE_OF(this$<n>).x(a1,....an)
9469
9470              2) We're generating bytecodes:
9471              
9472              - LIST is non static. It's invocation is transformed from
9473                x(a1,....,an) into access$<n>(this$<n>,a1,...,an).
9474              - LIST is static. It's invocation is transformed from
9475                x(a1,....,an) into TYPEOF(this$<n>).x(a1,....an).
9476
9477              Of course, this$<n> can be abitrary complex, ranging from
9478              this$0 (the immediate outer context) to 
9479              access$0(access$0(...(this$0))). 
9480              
9481              maybe_use_access_method returns a non zero value if the
9482              this_arg has to be deplaced into the (then generated)
9483              stub argument list. In the mean time, the selected
9484              function might have be replaced by a generated stub. */
9485           if (maybe_use_access_method (is_super_init, &list, &this_arg))
9486             args = tree_cons (NULL_TREE, this_arg, args);
9487         }
9488     }
9489
9490   /* Merge point of all resolution schemes. If we have nothing, this
9491      is an error, already signaled */
9492   if (!list) 
9493     PATCH_METHOD_RETURN_ERROR ();
9494
9495   /* Check accessibility, position the is_static flag, build and
9496      return the call */
9497   if (not_accessible_p (DECL_CONTEXT (current_function_decl), list, 0))
9498     {
9499       char *fct_name = xstrdup (lang_printable_name (list, 0));
9500       parse_error_context 
9501         (wfl, "Can't access %s method `%s %s.%s' from `%s'",
9502          java_accstring_lookup (get_access_flags_from_decl (list)),
9503          lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0), 
9504          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (list)))), 
9505          fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
9506       free (fct_name);
9507       PATCH_METHOD_RETURN_ERROR ();
9508     }
9509   check_deprecation (wfl, list);
9510
9511   /* If invoking a innerclass constructor, there are hidden parameters
9512      to pass */
9513   if (TREE_CODE (patch) == NEW_CLASS_EXPR 
9514       && PURE_INNER_CLASS_TYPE_P (DECL_CONTEXT (list)))
9515     {
9516       /* And make sure we add the accessed local variables to be saved
9517          in field aliases. */
9518       args = build_alias_initializer_parameter_list
9519         (AIPL_FUNCTION_CTOR_INVOCATION, DECL_CONTEXT (list), args, NULL);
9520
9521       /* We have to reverse things. Find out why. FIXME */
9522       if (ANONYMOUS_CLASS_P (DECL_CONTEXT (list)))
9523         args = nreverse (args);
9524       
9525       /* Secretely pass the current_this/primary as a second argument */
9526       if (primary || current_this)
9527         args = tree_cons (NULL_TREE, (primary ? primary : current_this), args);
9528       else
9529         args = tree_cons (NULL_TREE, integer_zero_node, args);
9530     }
9531
9532   is_static_flag = METHOD_STATIC (list);
9533   if (! METHOD_STATIC (list) && this_arg != NULL_TREE)
9534     args = tree_cons (NULL_TREE, this_arg, args);
9535
9536   /* In the context of an explicit constructor invocation, we can't
9537      invoke any method relying on `this'. Exceptions are: we're
9538      invoking a static function, primary exists and is not the current
9539      this, we're creating a new object. */
9540   if (ctxp->explicit_constructor_p 
9541       && !is_static_flag 
9542       && (!primary || primary == current_this)
9543       && (TREE_CODE (patch) != NEW_CLASS_EXPR))
9544     {
9545       parse_error_context (wfl, "Can't reference `this' before the superclass constructor has been called");
9546       PATCH_METHOD_RETURN_ERROR ();
9547     }
9548   java_parser_context_restore_global ();
9549   if (is_static) 
9550     *is_static = is_static_flag;
9551   /* Sometimes, we want the decl of the selected method. Such as for
9552      EH checking */
9553   if (ret_decl)
9554     *ret_decl = list;
9555   patch = patch_invoke (patch, list, args);
9556   if (is_super_init && CLASS_HAS_FINIT_P (current_class))
9557     {
9558       tree finit_parms, finit_call;
9559       
9560       /* Prepare to pass hidden parameters to $finit$, if any. */
9561       finit_parms = build_alias_initializer_parameter_list 
9562         (AIPL_FUNCTION_FINIT_INVOCATION, current_class, NULL_TREE, NULL);
9563
9564       finit_call = 
9565         build_method_invocation (build_wfl_node (finit_identifier_node),
9566                                  finit_parms);
9567
9568       /* Generate the code used to initialize fields declared with an
9569          initialization statement and build a compound statement along
9570          with the super constructor invocation. */
9571       patch = build (COMPOUND_EXPR, void_type_node, patch,
9572                      java_complete_tree (finit_call));
9573       CAN_COMPLETE_NORMALLY (patch) = 1;
9574     }
9575   return patch;
9576 }
9577
9578 /* Check that we're not trying to do a static reference to a method in
9579    non static method. Return 1 if it's the case, 0 otherwise. */
9580
9581 static int
9582 check_for_static_method_reference (wfl, node, method, where, primary)
9583      tree wfl, node, method, where, primary;
9584 {
9585   if (METHOD_STATIC (current_function_decl) 
9586       && !METHOD_STATIC (method) && !primary && !CALL_CONSTRUCTOR_P (node))
9587     {
9588       char *fct_name = xstrdup (lang_printable_name (method, 0));
9589       parse_error_context 
9590         (wfl, "Can't make static reference to method `%s %s' in class `%s'", 
9591          lang_printable_name (TREE_TYPE (TREE_TYPE (method)), 0), fct_name,
9592          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (where))));
9593       free (fct_name);
9594       return 1;
9595     }
9596   return 0;
9597 }
9598
9599 /* Fix the invocation of *MDECL if necessary in the case of a
9600    invocation from an inner class. *THIS_ARG might be modified
9601    appropriately and an alternative access to *MDECL might be
9602    returned.  */
9603
9604 static int
9605 maybe_use_access_method (is_super_init, mdecl, this_arg)
9606      int is_super_init;
9607      tree *mdecl, *this_arg;
9608 {
9609   tree ctx;
9610   tree md = *mdecl, ta = *this_arg;
9611   int to_return = 0;
9612   int non_static_context = !METHOD_STATIC (md);
9613
9614   if (is_super_init 
9615       || DECL_CONTEXT (md) == current_class
9616       || !PURE_INNER_CLASS_TYPE_P (current_class) 
9617       || DECL_FINIT_P (md))
9618     return 0;
9619   
9620   /* If we're calling a method found in an enclosing class, generate
9621      what it takes to retrieve the right this. Don't do that if we're
9622      invoking a static method. */
9623
9624   if (non_static_context)
9625     {
9626       ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class)));
9627       if (ctx == DECL_CONTEXT (md))
9628         {
9629           ta = build_current_thisn (current_class);
9630           ta = build_wfl_node (ta);
9631         }
9632       else
9633         {
9634           tree type = ctx;
9635           while (type)
9636             {
9637               maybe_build_thisn_access_method (type);
9638               if (type == DECL_CONTEXT (md))
9639                 {
9640                   ta = build_access_to_thisn (ctx, type, 0);
9641                   break;
9642                 }
9643               type = (DECL_CONTEXT (TYPE_NAME (type)) ? 
9644                       TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))) : NULL_TREE);
9645             }
9646         }
9647       ta = java_complete_tree (ta);
9648     }
9649
9650   /* We might have to use an access method to get to MD. We can
9651      break the method access rule as far as we're not generating
9652      bytecode */
9653   if (METHOD_PRIVATE (md) && flag_emit_class_files)
9654     {
9655       md = build_outer_method_access_method (md);
9656       to_return = 1;
9657     }
9658
9659   *mdecl = md;
9660   *this_arg = ta;
9661
9662   /* Returnin a non zero value indicates we were doing a non static
9663      method invokation that is now a static invocation. It will have
9664      callee displace `this' to insert it in the regular argument
9665      list. */
9666   return (non_static_context && to_return);
9667 }
9668
9669 /* Patch an invoke expression METHOD and ARGS, based on its invocation
9670    mode.  */
9671
9672 static tree
9673 patch_invoke (patch, method, args)
9674      tree patch, method, args;
9675 {
9676   tree dtable, func;
9677   tree original_call, t, ta;
9678
9679   /* Last step for args: convert build-in types. If we're dealing with
9680      a new TYPE() type call, the first argument to the constructor
9681      isn't found in the incomming argument list, but delivered by
9682      `new' */
9683   t = TYPE_ARG_TYPES (TREE_TYPE (method));
9684   if (TREE_CODE (patch) == NEW_CLASS_EXPR)
9685     t = TREE_CHAIN (t);
9686   for (ta = args; t != end_params_node && ta; 
9687        t = TREE_CHAIN (t), ta = TREE_CHAIN (ta))
9688     if (JPRIMITIVE_TYPE_P (TREE_TYPE (TREE_VALUE (ta))) &&
9689         TREE_TYPE (TREE_VALUE (ta)) != TREE_VALUE (t))
9690       TREE_VALUE (ta) = convert (TREE_VALUE (t), TREE_VALUE (ta));
9691
9692   /* Resolve unresolved returned type isses */
9693   t = TREE_TYPE (TREE_TYPE (method));
9694   if (TREE_CODE (t) == POINTER_TYPE && !CLASS_LOADED_P (TREE_TYPE (t)))
9695     resolve_and_layout (TREE_TYPE (t), NULL);
9696
9697   if (flag_emit_class_files || flag_emit_xref)
9698     func = method;
9699   else
9700     {
9701       tree signature = build_java_signature (TREE_TYPE (method));
9702       switch (invocation_mode (method, CALL_USING_SUPER (patch)))
9703         {
9704         case INVOKE_VIRTUAL:
9705           dtable = invoke_build_dtable (0, args);
9706           func = build_invokevirtual (dtable, method);
9707           break;
9708
9709         case INVOKE_SUPER:
9710         case INVOKE_STATIC:
9711           func = build_known_method_ref (method, TREE_TYPE (method),
9712                                          DECL_CONTEXT (method),
9713                                          signature, args);
9714           break;
9715
9716         case INVOKE_INTERFACE:
9717           dtable = invoke_build_dtable (1, args);
9718           func = build_invokeinterface (dtable, method);
9719           break;
9720
9721         default:
9722           fatal ("internal error - unknown invocation_mode result");
9723         }
9724
9725       /* Ensure self_type is initialized, (invokestatic). FIXME */
9726       func = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (method)), func);
9727     }
9728
9729   TREE_TYPE (patch) = TREE_TYPE (TREE_TYPE (method));
9730   TREE_OPERAND (patch, 0) = func;
9731   TREE_OPERAND (patch, 1) = args;
9732   original_call = patch;
9733
9734   /* We're processing a `new TYPE ()' form. New is called an its
9735      returned value is the first argument to the constructor. We build
9736      a COMPOUND_EXPR and use saved expression so that the overall NEW
9737      expression value is a pointer to a newly created and initialized
9738      class. */
9739   if (TREE_CODE (original_call) == NEW_CLASS_EXPR)
9740     {
9741       tree class = DECL_CONTEXT (method);
9742       tree c1, saved_new, size, new;
9743       if (flag_emit_class_files || flag_emit_xref)
9744         {
9745           TREE_TYPE (patch) = build_pointer_type (class);
9746           return patch;
9747         }
9748       if (!TYPE_SIZE (class))
9749         safe_layout_class (class);
9750       size = size_in_bytes (class);
9751       new = build (CALL_EXPR, promote_type (class),
9752                    build_address_of (alloc_object_node),
9753                    tree_cons (NULL_TREE, build_class_ref (class),
9754                               build_tree_list (NULL_TREE, 
9755                                                size_in_bytes (class))),
9756                    NULL_TREE);
9757       saved_new = save_expr (new);
9758       c1 = build_tree_list (NULL_TREE, saved_new);
9759       TREE_CHAIN (c1) = TREE_OPERAND (original_call, 1);
9760       TREE_OPERAND (original_call, 1) = c1;
9761       TREE_SET_CODE (original_call, CALL_EXPR);
9762       patch = build (COMPOUND_EXPR, TREE_TYPE (new), patch, saved_new);
9763     }
9764   return patch;
9765 }
9766
9767 static int
9768 invocation_mode (method, super)
9769      tree method;
9770      int super;
9771 {
9772   int access = get_access_flags_from_decl (method);
9773
9774   if (super)
9775     return INVOKE_SUPER;
9776
9777   if (access & ACC_STATIC || access & ACC_FINAL || access & ACC_PRIVATE)
9778     return INVOKE_STATIC;
9779
9780   if (CLASS_FINAL (TYPE_NAME (DECL_CONTEXT (method))))
9781     return INVOKE_STATIC;
9782   
9783   if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))))
9784     return INVOKE_INTERFACE;
9785   
9786   if (DECL_CONSTRUCTOR_P (method))
9787     return INVOKE_STATIC;
9788
9789   return INVOKE_VIRTUAL;
9790 }
9791
9792 /* Retrieve a refined list of matching methods. It covers the step
9793    15.11.2 (Compile-Time Step 2) */
9794
9795 static tree
9796 lookup_method_invoke (lc, cl, class, name, arg_list)
9797      int lc;
9798      tree cl;
9799      tree class, name, arg_list;
9800 {
9801   tree atl = end_params_node;           /* Arg Type List */
9802   tree method, signature, list, node;
9803   const char *candidates;               /* Used for error report */
9804   char *dup;
9805
9806   /* Fix the arguments */
9807   for (node = arg_list; node; node = TREE_CHAIN (node))
9808     {
9809       tree current_arg = TREE_TYPE (TREE_VALUE (node));
9810       /* Non primitive type may have to be resolved */
9811       if (!JPRIMITIVE_TYPE_P (current_arg))
9812         resolve_and_layout (current_arg, NULL_TREE);
9813       /* And promoted */
9814       if (TREE_CODE (current_arg) == RECORD_TYPE)
9815         current_arg = promote_type (current_arg);
9816       atl = tree_cons (NULL_TREE, current_arg, atl);
9817     }
9818
9819   /* Presto. If we're dealing with an anonymous class and a
9820      constructor call, generate the right constructor now, since we
9821      know the arguments' types. */
9822
9823   if (lc && ANONYMOUS_CLASS_P (class))
9824     craft_constructor (TYPE_NAME (class), atl);
9825
9826   /* Find all candidates and then refine the list, searching for the
9827      most specific method. */
9828   list = find_applicable_accessible_methods_list (lc, class, name, atl);
9829   list = find_most_specific_methods_list (list);
9830   if (list && !TREE_CHAIN (list))
9831     return TREE_VALUE (list);
9832
9833   /* Issue an error. List candidates if any. Candidates are listed
9834      only if accessible (non accessible methods may end-up here for
9835      the sake of a better error report). */
9836   candidates = NULL;
9837   if (list)
9838     {
9839       tree current;
9840       obstack_grow (&temporary_obstack, ". Candidates are:\n", 18);
9841       for (current = list; current; current = TREE_CHAIN (current))
9842         {
9843           tree cm = TREE_VALUE (current);
9844           char string [4096];
9845           if (!cm || not_accessible_p (class, cm, 0))
9846             continue;
9847           sprintf 
9848             (string, "  `%s' in `%s'%s",
9849              get_printable_method_name (cm),
9850              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (cm)))),
9851              (TREE_CHAIN (current) ? "\n" : ""));
9852           obstack_grow (&temporary_obstack, string, strlen (string));
9853         }
9854       obstack_1grow (&temporary_obstack, '\0');
9855       candidates = obstack_finish (&temporary_obstack);
9856     }
9857   /* Issue the error message */
9858   method = make_node (FUNCTION_TYPE);
9859   TYPE_ARG_TYPES (method) = atl;
9860   signature = build_java_argument_signature (method);
9861   dup = xstrdup (lang_printable_name (class, 0));
9862   parse_error_context (cl, "Can't find %s `%s(%s)' in type `%s'%s",
9863                        (lc ? "constructor" : "method"),
9864                        (lc ? dup : IDENTIFIER_POINTER (name)),
9865                        IDENTIFIER_POINTER (signature), dup,
9866                        (candidates ? candidates : ""));
9867   free (dup);
9868   return NULL_TREE;
9869 }
9870
9871 /* 15.11.2.1: Find Methods that are Applicable and Accessible. LC is 1
9872    when we're looking for a constructor. */
9873
9874 static tree
9875 find_applicable_accessible_methods_list (lc, class, name, arglist)
9876      int lc;
9877      tree class, name, arglist;
9878 {
9879   static int object_done = 0;
9880   tree list = NULL_TREE, all_list = NULL_TREE;
9881
9882   if (!CLASS_LOADED_P (class) && !CLASS_FROM_SOURCE_P (class))
9883     {
9884       load_class (class, 1);
9885       safe_layout_class (class);
9886     }
9887
9888   /* Search interfaces */
9889   if (CLASS_INTERFACE (TYPE_NAME (class)))
9890     {
9891       static struct hash_table t, *searched_interfaces = NULL;
9892       static int search_not_done = 0;
9893       int i, n;
9894       tree basetype_vec = TYPE_BINFO_BASETYPES (class);
9895
9896       /* Search in the hash table, otherwise create a new one if
9897          necessary and insert the new entry. */
9898
9899       if (searched_interfaces)
9900         {
9901           if (hash_lookup (searched_interfaces, 
9902                            (const hash_table_key) class, FALSE, NULL))
9903             return NULL;
9904         }
9905       else
9906         {
9907           hash_table_init (&t, hash_newfunc, java_hash_hash_tree_node,
9908                            java_hash_compare_tree_node);
9909           searched_interfaces = &t;
9910         }
9911
9912       hash_lookup (searched_interfaces, 
9913                    (const hash_table_key) class, TRUE, NULL);
9914
9915       search_applicable_methods_list (lc, TYPE_METHODS (class), 
9916                                       name, arglist, &list, &all_list);
9917       n = TREE_VEC_LENGTH (basetype_vec);
9918       for (i = 1; i < n; i++)
9919         {
9920           tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
9921           tree rlist;
9922
9923           search_not_done++;
9924           rlist = find_applicable_accessible_methods_list (lc,  t, name, 
9925                                                            arglist);
9926           list = chainon (rlist, list);
9927           search_not_done--;
9928         }
9929
9930       /* We're done. Reset the searched interfaces list and finally search
9931          java.lang.Object */
9932       if (!search_not_done)
9933         {  
9934           if (!object_done)
9935             search_applicable_methods_list (lc, 
9936                                             TYPE_METHODS (object_type_node),
9937                                             name, arglist, &list, &all_list);
9938           hash_table_free (searched_interfaces);
9939           searched_interfaces = NULL;  
9940         }
9941     }
9942   /* Search classes */
9943   else
9944     {
9945       tree sc = class;
9946       int seen_inner_class = 0;
9947       search_applicable_methods_list (lc, TYPE_METHODS (class), 
9948                                       name, arglist, &list, &all_list);
9949
9950       /* We must search all interfaces of this class */
9951       if (!lc)
9952       {
9953         tree basetype_vec = TYPE_BINFO_BASETYPES (sc);
9954         int n = TREE_VEC_LENGTH (basetype_vec), i;
9955         object_done = 1;
9956         for (i = 1; i < n; i++)
9957           {
9958             tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
9959             tree rlist;
9960             if (t != object_type_node)
9961               rlist = find_applicable_accessible_methods_list (lc, t,
9962                                                                name, arglist);
9963             list = chainon (rlist, list);
9964           }
9965         object_done = 0;
9966       }
9967
9968       /* Search enclosing context of inner classes before looking
9969          ancestors up. */
9970       while (!lc && INNER_CLASS_TYPE_P (class))
9971         {
9972           tree rlist;
9973           seen_inner_class = 1;
9974           class = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class)));
9975           rlist = find_applicable_accessible_methods_list (lc, class, 
9976                                                            name, arglist);
9977           list = chainon (rlist, list);
9978         }
9979
9980       if (!lc && seen_inner_class 
9981           && TREE_TYPE (DECL_CONTEXT (TYPE_NAME (sc))) == CLASSTYPE_SUPER (sc))
9982         class = CLASSTYPE_SUPER (sc);
9983       else
9984         class = sc;
9985
9986       for (class = (lc ? NULL_TREE : CLASSTYPE_SUPER (class)); 
9987         class; class = CLASSTYPE_SUPER (class))
9988        search_applicable_methods_list (lc, TYPE_METHODS (class), 
9989                                        name, arglist, &list, &all_list);
9990     }
9991
9992   /* Either return the list obtained or all selected (but
9993      inaccessible) methods for better error report. */
9994   return (!list ? all_list : list);
9995 }
9996
9997 /* Effectively search for the approriate method in method */
9998
9999 static void 
10000 search_applicable_methods_list (lc, method, name, arglist, list, all_list)
10001      int lc;
10002      tree method, name, arglist;
10003      tree *list, *all_list;
10004 {
10005   for (; method; method = TREE_CHAIN (method))
10006     {
10007       /* When dealing with constructor, stop here, otherwise search
10008          other classes */
10009       if (lc && !DECL_CONSTRUCTOR_P (method))
10010         continue;
10011       else if (!lc && (DECL_CONSTRUCTOR_P (method) 
10012                        || (GET_METHOD_NAME (method) != name)))
10013         continue;
10014           
10015       if (argument_types_convertible (method, arglist))
10016         {
10017           /* Retain accessible methods only */
10018           if (!not_accessible_p (DECL_CONTEXT (current_function_decl), 
10019                                  method, 0))
10020             *list = tree_cons (NULL_TREE, method, *list);
10021           else
10022             /* Also retain all selected method here */
10023             *all_list = tree_cons (NULL_TREE, method, *list);
10024         }
10025     }
10026 }    
10027
10028 /* 15.11.2.2 Choose the Most Specific Method */
10029
10030 static tree
10031 find_most_specific_methods_list (list)
10032      tree list;
10033 {
10034   int max = 0;
10035   tree current, new_list = NULL_TREE;
10036   for (current = list; current; current = TREE_CHAIN (current))
10037     {
10038       tree method;
10039       DECL_SPECIFIC_COUNT (TREE_VALUE (current)) = 0;
10040
10041       for (method = list; method; method = TREE_CHAIN (method))
10042         {
10043           /* Don't test a method against itself */
10044           if (method == current)
10045             continue;
10046
10047           /* Compare arguments and location where method where declared */
10048           if (argument_types_convertible (TREE_VALUE (method), 
10049                                           TREE_VALUE (current))
10050               && valid_method_invocation_conversion_p 
10051                    (DECL_CONTEXT (TREE_VALUE (method)), 
10052                     DECL_CONTEXT (TREE_VALUE (current))))
10053             {
10054               int v = ++DECL_SPECIFIC_COUNT (TREE_VALUE (current));
10055               max = (v > max ? v : max);
10056             }
10057         }
10058     }
10059
10060   /* Review the list and select the maximally specific methods */
10061   for (current = list; current; current = TREE_CHAIN (current))
10062     if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
10063       new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
10064
10065   /* If we have several and they're all abstract, just pick the
10066      closest one. */
10067
10068   if (new_list && TREE_CHAIN (new_list))
10069     {
10070       tree c;
10071       for (c = new_list; c && METHOD_ABSTRACT (TREE_VALUE (c)); 
10072            c = TREE_CHAIN (c))
10073         ;
10074       if (!c)
10075         {
10076           new_list = nreverse (new_list);
10077           TREE_CHAIN (new_list) = NULL_TREE;
10078         }
10079     }
10080
10081   /* If we can't find one, lower expectations and try to gather multiple
10082      maximally specific methods */
10083   while (!new_list && max)
10084     {
10085       while (--max > 0)
10086         {
10087           if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
10088             new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
10089         }
10090     }
10091
10092   return new_list;
10093 }
10094
10095 /* Make sure that the type of each M2_OR_ARGLIST arguments can be
10096    converted by method invocation conversion (5.3) to the type of the
10097    corresponding parameter of M1. Implementation expects M2_OR_ARGLIST
10098    to change less often than M1. */
10099
10100 static int
10101 argument_types_convertible (m1, m2_or_arglist)
10102     tree m1, m2_or_arglist;
10103 {
10104   static tree m2_arg_value = NULL_TREE;
10105   static tree m2_arg_cache = NULL_TREE;
10106
10107   register tree m1_arg, m2_arg;
10108
10109   SKIP_THIS_AND_ARTIFICIAL_PARMS (m1_arg, m1)
10110
10111   if (m2_arg_value == m2_or_arglist)
10112     m2_arg = m2_arg_cache;
10113   else
10114     {
10115       /* M2_OR_ARGLIST can be a function DECL or a raw list of
10116          argument types */
10117       if (m2_or_arglist && TREE_CODE (m2_or_arglist) == FUNCTION_DECL)
10118         {
10119           m2_arg = TYPE_ARG_TYPES (TREE_TYPE (m2_or_arglist));
10120           if (!METHOD_STATIC (m2_or_arglist))
10121             m2_arg = TREE_CHAIN (m2_arg);
10122         }
10123       else
10124         m2_arg = m2_or_arglist;
10125
10126       m2_arg_value = m2_or_arglist;
10127       m2_arg_cache = m2_arg;
10128     }
10129
10130   while (m1_arg != end_params_node && m2_arg != end_params_node)
10131     {
10132       resolve_and_layout (TREE_VALUE (m1_arg), NULL_TREE);
10133       if (!valid_method_invocation_conversion_p (TREE_VALUE (m1_arg),
10134                                                  TREE_VALUE (m2_arg)))
10135         break;
10136       m1_arg = TREE_CHAIN (m1_arg);
10137       m2_arg = TREE_CHAIN (m2_arg);
10138     }
10139   return m1_arg == end_params_node && m2_arg == end_params_node;
10140 }
10141
10142 /* Qualification routines */
10143
10144 static void
10145 qualify_ambiguous_name (id)
10146      tree id;
10147 {
10148   tree qual, qual_wfl, name = NULL_TREE, decl, ptr_type = NULL_TREE,
10149     saved_current_class;
10150   int again, super_found = 0, this_found = 0, new_array_found = 0;
10151   int code;
10152
10153   /* We first qualify the first element, then derive qualification of
10154      others based on the first one. If the first element is qualified
10155      by a resolution (field or type), this resolution is stored in the
10156      QUAL_RESOLUTION of the qual element being examined. We need to
10157      save the current_class since the use of SUPER might change the
10158      its value. */
10159   saved_current_class = current_class;
10160   qual = EXPR_WFL_QUALIFICATION (id);
10161   do {
10162
10163     /* Simple qualified expression feature a qual_wfl that is a
10164        WFL. Expression derived from a primary feature more complicated
10165        things like a CALL_EXPR. Expression from primary need to be
10166        worked out to extract the part on which the qualification will
10167        take place. */
10168     qual_wfl = QUAL_WFL (qual);
10169     switch (TREE_CODE (qual_wfl))
10170       {
10171       case CALL_EXPR:
10172         qual_wfl = TREE_OPERAND (qual_wfl, 0);
10173         if (TREE_CODE (qual_wfl) != EXPR_WITH_FILE_LOCATION)
10174           {
10175             qual = EXPR_WFL_QUALIFICATION (qual_wfl);
10176             qual_wfl = QUAL_WFL (qual);
10177           }
10178         break;
10179       case NEW_ARRAY_EXPR:
10180       case NEW_ANONYMOUS_ARRAY_EXPR:
10181         qual = TREE_CHAIN (qual);
10182         again = new_array_found = 1;
10183         continue;
10184       case NEW_CLASS_EXPR:
10185       case CONVERT_EXPR:
10186         qual_wfl = TREE_OPERAND (qual_wfl, 0);
10187         break;
10188       case ARRAY_REF:
10189         while (TREE_CODE (qual_wfl) == ARRAY_REF)
10190           qual_wfl = TREE_OPERAND (qual_wfl, 0);
10191         break;
10192       case STRING_CST:
10193         qual = TREE_CHAIN (qual);
10194         qual_wfl = QUAL_WFL (qual);
10195         break;
10196       case CLASS_LITERAL:
10197         qual = TREE_CHAIN (qual);
10198         qual_wfl = QUAL_WFL (qual);
10199       break;
10200       default:
10201         /* Fix for -Wall. Just break doing nothing */
10202         break;
10203       }
10204
10205     ptr_type = current_class;
10206     again = 0;
10207     code = TREE_CODE (qual_wfl);
10208
10209     /* Pos evaluation: non WFL leading expression nodes */
10210     if (code == CONVERT_EXPR
10211         && TREE_CODE (TREE_TYPE (qual_wfl)) == EXPR_WITH_FILE_LOCATION)
10212       name = EXPR_WFL_NODE (TREE_TYPE (qual_wfl));
10213
10214     else if (code == INTEGER_CST)
10215       name = qual_wfl;
10216     
10217     else if ((code == ARRAY_REF || code == CALL_EXPR || code == MODIFY_EXPR) &&
10218              TREE_CODE (TREE_OPERAND (qual_wfl, 0)) == EXPR_WITH_FILE_LOCATION)
10219       name = EXPR_WFL_NODE (TREE_OPERAND (qual_wfl, 0));
10220
10221     else if (code == TREE_LIST)
10222       name = EXPR_WFL_NODE (TREE_PURPOSE (qual_wfl));
10223
10224     else if (code == STRING_CST || code == CONDITIONAL_EXPR 
10225              || code == PLUS_EXPR)
10226       {
10227         qual = TREE_CHAIN (qual);
10228         qual_wfl = QUAL_WFL (qual);
10229         again = 1;
10230       }
10231     else 
10232       {
10233         name = EXPR_WFL_NODE (qual_wfl);
10234         if (!name)
10235           {
10236             qual = EXPR_WFL_QUALIFICATION (qual_wfl);
10237             again = 1;
10238           }
10239       }
10240
10241     /* If we have a THIS (from a primary), we set the context accordingly */
10242     if (name == this_identifier_node)
10243       {
10244         qual = TREE_CHAIN (qual);
10245         qual_wfl = QUAL_WFL (qual);
10246         if (TREE_CODE (qual_wfl) == CALL_EXPR)
10247           again = 1;
10248         else
10249           name = EXPR_WFL_NODE (qual_wfl);
10250         this_found = 1;
10251       }
10252     /* If we have a SUPER, we set the context accordingly */
10253     if (name == super_identifier_node)
10254       {
10255         current_class = CLASSTYPE_SUPER (ptr_type);
10256         /* Check that there is such a thing as a super class. If not,
10257            return.  The error will be caught later on, during the
10258            resolution */
10259         if (!current_class)
10260           {
10261             current_class = saved_current_class;
10262             return;
10263           }
10264         qual = TREE_CHAIN (qual);
10265         /* Do one more interation to set things up */
10266         super_found = again = 1;
10267       }
10268   } while (again);
10269   
10270   /* If name appears within the scope of a location variable
10271      declaration or parameter declaration, then it is an expression
10272      name. We don't carry this test out if we're in the context of the
10273      use of SUPER or THIS */
10274   if (!this_found && !super_found 
10275       && TREE_CODE (name) != STRING_CST && TREE_CODE (name) != INTEGER_CST
10276       && (decl = IDENTIFIER_LOCAL_VALUE (name)))
10277     {
10278       RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
10279       QUAL_RESOLUTION (qual) = decl;
10280     }
10281
10282   /* If within the class/interface NAME was found to be used there
10283      exists a (possibly inherited) field named NAME, then this is an
10284      expression name. If we saw a NEW_ARRAY_EXPR before and want to
10285      address length, it is OK. */
10286   else if ((decl = lookup_field_wrapper (ptr_type, name))
10287            || (new_array_found && name == length_identifier_node))
10288     {
10289       RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
10290       QUAL_RESOLUTION (qual) = (new_array_found ? NULL_TREE : decl);
10291     }
10292
10293   /* We reclassify NAME as yielding to a type name resolution if:
10294      - NAME is a class/interface declared within the compilation
10295        unit containing NAME,
10296      - NAME is imported via a single-type-import declaration,
10297      - NAME is declared in an another compilation unit of the package
10298        of the compilation unit containing NAME,
10299      - NAME is declared by exactly on type-import-on-demand declaration
10300      of the compilation unit containing NAME. 
10301      - NAME is actually a STRING_CST. */
10302   else if (TREE_CODE (name) == STRING_CST || TREE_CODE (name) == INTEGER_CST
10303            || (decl = resolve_and_layout (name, NULL_TREE)))
10304     {
10305       RESOLVE_TYPE_NAME_P (qual_wfl) = 1;
10306       QUAL_RESOLUTION (qual) = decl;
10307     }
10308
10309   /* Method call are expression name */
10310   else if (TREE_CODE (QUAL_WFL (qual)) == CALL_EXPR
10311            || TREE_CODE (QUAL_WFL (qual)) == ARRAY_REF
10312            || TREE_CODE (QUAL_WFL (qual)) == CONVERT_EXPR)
10313     RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
10314
10315   /* Check here that NAME isn't declared by more than one
10316      type-import-on-demand declaration of the compilation unit
10317      containing NAME. FIXME */
10318
10319   /* Otherwise, NAME is reclassified as a package name */
10320   else 
10321     RESOLVE_PACKAGE_NAME_P (qual_wfl) = 1;
10322
10323   /* Propagate the qualification accross other components of the
10324      qualified name */
10325   for (qual = TREE_CHAIN (qual); qual;
10326        qual_wfl = QUAL_WFL (qual), qual = TREE_CHAIN (qual))
10327     {
10328       if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
10329         RESOLVE_PACKAGE_NAME_P (QUAL_WFL (qual)) = 1;
10330       else 
10331         RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (qual)) = 1;
10332     }
10333
10334   /* Store the global qualification for the ambiguous part of ID back
10335      into ID fields */
10336   if (RESOLVE_EXPRESSION_NAME_P (qual_wfl))
10337     RESOLVE_EXPRESSION_NAME_P (id) = 1;
10338   else if (RESOLVE_TYPE_NAME_P (qual_wfl))
10339     RESOLVE_TYPE_NAME_P (id) = 1;
10340   else if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
10341     RESOLVE_PACKAGE_NAME_P (id) = 1;
10342
10343   /* Restore the current class */
10344   current_class = saved_current_class;
10345 }
10346
10347 static int
10348 breakdown_qualified (left, right, source)
10349     tree *left, *right, source;
10350 {
10351   char *p = IDENTIFIER_POINTER (source), *base;
10352   int   l = IDENTIFIER_LENGTH (source);
10353
10354   /* Breakdown NAME into REMAINDER . IDENTIFIER */
10355   base = p;
10356   p += (l-1);
10357   while (*p != '.' && p != base)
10358     p--;
10359
10360   /* We didn't find a '.'. Return an error */
10361   if (p == base)
10362     return 1;
10363
10364   *p = '\0';
10365   if (right)
10366     *right = get_identifier (p+1);
10367   *left = get_identifier (IDENTIFIER_POINTER (source));
10368   *p = '.';
10369   
10370   return 0;
10371 }
10372
10373 /* Patch tree nodes in a function body. When a BLOCK is found, push
10374    local variable decls if present.
10375    Same as java_complete_lhs, but does resolve static finals to values. */
10376
10377 static tree
10378 java_complete_tree (node)
10379      tree node;
10380 {
10381   node = java_complete_lhs (node);
10382   if (TREE_CODE (node) == VAR_DECL && FIELD_STATIC (node)
10383       && FIELD_FINAL (node) && DECL_INITIAL (node) != NULL_TREE
10384       && !flag_emit_xref)
10385     {
10386       tree value = DECL_INITIAL (node);
10387       DECL_INITIAL (node) = NULL_TREE;
10388       push_obstacks (&permanent_obstack, &permanent_obstack);
10389       value = fold_constant_for_init (value, node);
10390       pop_obstacks ();
10391       DECL_INITIAL (node) = value;
10392       if (value != NULL_TREE)
10393         {
10394           /* fold_constant_for_init sometimes widen the original type
10395              of the constant (i.e. byte to int.) It's not desirable,
10396              especially if NODE is a function argument. */
10397           if (TREE_CODE (value) == INTEGER_CST
10398               && TREE_TYPE (node) != TREE_TYPE (value))
10399             return convert (TREE_TYPE (node), value);
10400           else
10401             return value;
10402         }
10403     }
10404   return node;
10405 }
10406
10407 static tree
10408 java_stabilize_reference (node)
10409      tree node;
10410 {
10411   if (TREE_CODE (node) == COMPOUND_EXPR)
10412     {
10413       tree op0 = TREE_OPERAND (node, 0);
10414       tree op1 = TREE_OPERAND (node, 1);
10415       TREE_OPERAND (node, 0) = save_expr (op0);
10416       TREE_OPERAND (node, 1) = java_stabilize_reference (op1);
10417       return node;
10418     }
10419   return stabilize_reference (node);
10420 }
10421
10422 /* Patch tree nodes in a function body. When a BLOCK is found, push
10423    local variable decls if present.
10424    Same as java_complete_tree, but does not resolve static finals to values. */
10425
10426 static tree
10427 java_complete_lhs (node)
10428      tree node;
10429 {
10430   tree nn, cn, wfl_op1, wfl_op2, wfl_op3;
10431   int flag;
10432
10433   /* CONVERT_EXPR always has its type set, even though it needs to be
10434      worked out. */
10435   if (TREE_TYPE (node) && TREE_CODE (node) != CONVERT_EXPR)
10436     return node;
10437
10438   /* The switch block implements cases processing container nodes
10439      first.  Contained nodes are always written back. Leaves come
10440      next and return a value. */
10441   switch (TREE_CODE (node))
10442     {
10443     case BLOCK:
10444
10445       /* 1- Block section.
10446          Set the local values on decl names so we can identify them
10447          faster when they're referenced. At that stage, identifiers
10448          are legal so we don't check for declaration errors. */
10449       for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
10450         {
10451           DECL_CONTEXT (cn) = current_function_decl;
10452           IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = cn;
10453         }
10454       if (BLOCK_EXPR_BODY (node) == NULL_TREE)
10455           CAN_COMPLETE_NORMALLY (node) = 1;
10456       else
10457         {
10458           tree stmt = BLOCK_EXPR_BODY (node);
10459           tree *ptr;
10460           int error_seen = 0;
10461           if (TREE_CODE (stmt) == COMPOUND_EXPR)
10462             {
10463               /* Re-order from (((A; B); C); ...; Z) to 
10464                  (A; (B; (C ; (...; Z)))).
10465                  This makes it easier to scan the statements left-to-right
10466                  without using recursion (which might overflow the stack
10467                  if the block has many statements. */
10468               for (;;)
10469                 {
10470                   tree left = TREE_OPERAND (stmt, 0);
10471                   if (TREE_CODE (left) != COMPOUND_EXPR)
10472                     break;
10473                   TREE_OPERAND (stmt, 0) = TREE_OPERAND (left, 1);
10474                   TREE_OPERAND (left, 1) = stmt;
10475                   stmt = left;
10476                 }
10477               BLOCK_EXPR_BODY (node) = stmt;
10478             }
10479
10480           /* Now do the actual complete, without deep recursion for
10481              long blocks. */
10482           ptr = &BLOCK_EXPR_BODY (node);
10483           while (TREE_CODE (*ptr) == COMPOUND_EXPR
10484                  && TREE_OPERAND (*ptr, 1) != empty_stmt_node)
10485             {
10486               tree cur = java_complete_tree (TREE_OPERAND (*ptr, 0));
10487               tree *next = &TREE_OPERAND (*ptr, 1);
10488               TREE_OPERAND (*ptr, 0) = cur;
10489               if (cur == empty_stmt_node)
10490                 {
10491                   /* Optimization;  makes it easier to detect empty bodies.
10492                      Most useful for <clinit> with all-constant initializer. */
10493                   *ptr = *next;
10494                   continue;
10495                 }
10496               if (TREE_CODE (cur) == ERROR_MARK)
10497                 error_seen++;
10498               else if (! CAN_COMPLETE_NORMALLY (cur))
10499                 {
10500                   wfl_op2 = *next;
10501                   for (;;)
10502                     {
10503                       if (TREE_CODE (wfl_op2) == BLOCK)
10504                         wfl_op2 = BLOCK_EXPR_BODY (wfl_op2);
10505                       else if (TREE_CODE (wfl_op2) == COMPOUND_EXPR)
10506                         wfl_op2 = TREE_OPERAND (wfl_op2, 0);
10507                       else
10508                         break;
10509                     }
10510                   if (TREE_CODE (wfl_op2) != CASE_EXPR
10511                       && TREE_CODE (wfl_op2) != DEFAULT_EXPR)
10512                     unreachable_stmt_error (*ptr);
10513                 }
10514               ptr = next;
10515             }
10516           *ptr = java_complete_tree (*ptr);
10517
10518           if (TREE_CODE (*ptr) == ERROR_MARK || error_seen > 0)
10519             return error_mark_node;
10520           CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (*ptr);
10521         }
10522       /* Turn local bindings to null */
10523       for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
10524         IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = NULL_TREE;
10525
10526       TREE_TYPE (node) = void_type_node;
10527       break;
10528
10529       /* 2- They are expressions but ultimately deal with statements */
10530
10531     case THROW_EXPR:
10532       wfl_op1 = TREE_OPERAND (node, 0);
10533       COMPLETE_CHECK_OP_0 (node);
10534       /* 14.19 A throw statement cannot complete normally. */
10535       CAN_COMPLETE_NORMALLY (node) = 0;
10536       return patch_throw_statement (node, wfl_op1);
10537
10538     case SYNCHRONIZED_EXPR:
10539       wfl_op1 = TREE_OPERAND (node, 0);
10540       return patch_synchronized_statement (node, wfl_op1);
10541
10542     case TRY_EXPR:
10543       return patch_try_statement (node);
10544
10545     case TRY_FINALLY_EXPR:
10546       COMPLETE_CHECK_OP_0 (node);
10547       COMPLETE_CHECK_OP_1 (node);
10548       CAN_COMPLETE_NORMALLY (node)
10549         = (CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0))
10550            && CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)));
10551       TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 0));
10552       return node;
10553
10554     case CLEANUP_POINT_EXPR:
10555       COMPLETE_CHECK_OP_0 (node);
10556       TREE_TYPE (node) = void_type_node;
10557       CAN_COMPLETE_NORMALLY (node) = 
10558         CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
10559       return node;
10560
10561     case WITH_CLEANUP_EXPR:
10562       COMPLETE_CHECK_OP_0 (node);
10563       COMPLETE_CHECK_OP_2 (node);
10564       CAN_COMPLETE_NORMALLY (node) = 
10565         CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
10566       TREE_TYPE (node) = void_type_node;
10567       return node;
10568
10569     case LABELED_BLOCK_EXPR:
10570       PUSH_LABELED_BLOCK (node);
10571       if (LABELED_BLOCK_BODY (node))
10572         COMPLETE_CHECK_OP_1 (node);
10573       TREE_TYPE (node) = void_type_node;
10574       POP_LABELED_BLOCK ();
10575
10576       if (LABELED_BLOCK_BODY (node) == empty_stmt_node)
10577         {
10578           LABELED_BLOCK_BODY (node) = NULL_TREE;
10579           CAN_COMPLETE_NORMALLY (node) = 1;
10580         }
10581       else if (CAN_COMPLETE_NORMALLY (LABELED_BLOCK_BODY (node)))
10582         CAN_COMPLETE_NORMALLY (node) = 1;
10583       return node;
10584
10585     case EXIT_BLOCK_EXPR:
10586       /* We don't complete operand 1, because it's the return value of
10587          the EXIT_BLOCK_EXPR which doesn't exist it Java */
10588       return patch_bc_statement (node);
10589
10590     case CASE_EXPR:
10591       cn = java_complete_tree (TREE_OPERAND (node, 0));
10592       if (cn == error_mark_node)
10593         return cn;
10594
10595       /* First, the case expression must be constant. Values of final
10596          fields are accepted. */
10597       cn = fold (cn);
10598       if ((TREE_CODE (cn) == COMPOUND_EXPR || TREE_CODE (cn) == COMPONENT_REF)
10599           && JDECL_P (TREE_OPERAND (cn, 1))
10600           && FIELD_FINAL (TREE_OPERAND (cn, 1))
10601           && DECL_INITIAL (TREE_OPERAND (cn, 1)))
10602         {
10603           push_obstacks (&permanent_obstack, &permanent_obstack);
10604           cn = fold_constant_for_init (DECL_INITIAL (TREE_OPERAND (cn, 1)),
10605                                        TREE_OPERAND (cn, 1));
10606           pop_obstacks ();
10607         }
10608
10609       if (!TREE_CONSTANT (cn) && !flag_emit_xref)
10610         {
10611           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10612           parse_error_context (node, "Constant expression required");
10613           return error_mark_node;
10614         }
10615
10616       nn = ctxp->current_loop;
10617
10618       /* It must be assignable to the type of the switch expression. */
10619       if (!try_builtin_assignconv (NULL_TREE, 
10620                                    TREE_TYPE (TREE_OPERAND (nn, 0)), cn))
10621         {
10622           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10623           parse_error_context 
10624             (wfl_operator,
10625              "Incompatible type for case. Can't convert `%s' to `int'",
10626              lang_printable_name (TREE_TYPE (cn), 0));
10627           return error_mark_node;
10628         }
10629
10630       cn = fold (convert (int_type_node, cn));
10631
10632       /* Multiple instance of a case label bearing the same
10633          value is checked during code generation. The case
10634          expression is allright so far. */
10635       TREE_OPERAND (node, 0) = cn;
10636       TREE_TYPE (node) = void_type_node;
10637       CAN_COMPLETE_NORMALLY (node) = 1;
10638       TREE_SIDE_EFFECTS (node) = 1;
10639       break;
10640
10641     case DEFAULT_EXPR:
10642       nn = ctxp->current_loop;
10643       /* Only one default label is allowed per switch statement */
10644       if (SWITCH_HAS_DEFAULT (nn))
10645         {
10646           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10647           parse_error_context (wfl_operator, 
10648                                "Duplicate case label: `default'");
10649           return error_mark_node;
10650         }
10651       else
10652         SWITCH_HAS_DEFAULT (nn) = 1;
10653       TREE_TYPE (node) = void_type_node;
10654       TREE_SIDE_EFFECTS (node) = 1;
10655       CAN_COMPLETE_NORMALLY (node) = 1;
10656       break;
10657
10658     case SWITCH_EXPR:
10659     case LOOP_EXPR:
10660       PUSH_LOOP (node);
10661       /* Check whether the loop was enclosed in a labeled
10662          statement. If not, create one, insert the loop in it and
10663          return the node */
10664       nn = patch_loop_statement (node);
10665
10666       /* Anyways, walk the body of the loop */
10667       if (TREE_CODE (node) == LOOP_EXPR)
10668         TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
10669       /* Switch statement: walk the switch expression and the cases */
10670       else
10671         node = patch_switch_statement (node);
10672
10673       if (TREE_OPERAND (node, 0) == error_mark_node)
10674         nn = error_mark_node;
10675       else
10676         {
10677           TREE_TYPE (nn) = TREE_TYPE (node) = void_type_node;
10678           /* If we returned something different, that's because we
10679              inserted a label. Pop the label too. */
10680           if (nn != node)
10681             {
10682               if (CAN_COMPLETE_NORMALLY (node))
10683                 CAN_COMPLETE_NORMALLY (nn) = 1;
10684               POP_LABELED_BLOCK ();
10685             }
10686         }
10687       POP_LOOP ();
10688       return nn;
10689
10690     case EXIT_EXPR:
10691       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
10692       return patch_exit_expr (node);
10693
10694     case COND_EXPR:
10695       /* Condition */
10696       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
10697       if (TREE_OPERAND (node, 0) == error_mark_node)
10698         return error_mark_node;
10699       /* then-else branches */
10700       TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
10701       if (TREE_OPERAND (node, 1) == error_mark_node)
10702         return error_mark_node;
10703       TREE_OPERAND (node, 2) = java_complete_tree (TREE_OPERAND (node, 2));
10704       if (TREE_OPERAND (node, 2) == error_mark_node)
10705         return error_mark_node;
10706       return patch_if_else_statement (node);
10707       break;
10708
10709     case CONDITIONAL_EXPR:
10710       /* Condition */
10711       wfl_op1 = TREE_OPERAND (node, 0);
10712       COMPLETE_CHECK_OP_0 (node);
10713       wfl_op2 = TREE_OPERAND (node, 1);
10714       COMPLETE_CHECK_OP_1 (node);
10715       wfl_op3 = TREE_OPERAND (node, 2);
10716       COMPLETE_CHECK_OP_2 (node);
10717       return patch_conditional_expr (node, wfl_op1, wfl_op2);
10718
10719       /* 3- Expression section */
10720     case COMPOUND_EXPR:
10721       wfl_op2 = TREE_OPERAND (node, 1);
10722       TREE_OPERAND (node, 0) = nn = 
10723         java_complete_tree (TREE_OPERAND (node, 0));
10724       if (wfl_op2 == empty_stmt_node)
10725         CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (nn);
10726       else
10727         {
10728           if (! CAN_COMPLETE_NORMALLY (nn) && TREE_CODE (nn) != ERROR_MARK)
10729             {
10730               /* An unreachable condition in a do-while statement
10731                  is *not* (technically) an unreachable statement. */
10732               nn = wfl_op2;
10733               if (TREE_CODE (nn) == EXPR_WITH_FILE_LOCATION)
10734                 nn = EXPR_WFL_NODE (nn);
10735               if (TREE_CODE (nn) != EXIT_EXPR)
10736                 {
10737                   SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
10738                   parse_error_context (wfl_operator, "Unreachable statement");
10739                 }
10740             }
10741           TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
10742           if (TREE_OPERAND (node, 1) == error_mark_node)
10743             return error_mark_node;
10744           CAN_COMPLETE_NORMALLY (node)
10745             = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1));
10746         }
10747       TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 1));
10748       break;
10749
10750     case RETURN_EXPR:
10751       /* CAN_COMPLETE_NORMALLY (node) = 0; */
10752       return patch_return (node);
10753
10754     case EXPR_WITH_FILE_LOCATION:
10755       if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
10756           || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
10757         {
10758           tree wfl = node;
10759           node = resolve_expression_name (node, NULL);
10760           if (node == error_mark_node)
10761             return node;
10762           /* Keep line number information somewhere were it doesn't
10763              disrupt the completion process. */
10764           if (flag_emit_xref && TREE_CODE (node) != CALL_EXPR)
10765             {
10766               EXPR_WFL_NODE (wfl) = TREE_OPERAND (node, 1);
10767               TREE_OPERAND (node, 1) = wfl;
10768             }
10769           CAN_COMPLETE_NORMALLY (node) = 1;
10770         }
10771       else
10772         {
10773           tree body;
10774           int save_lineno = lineno;
10775           lineno = EXPR_WFL_LINENO (node);
10776           body = java_complete_tree (EXPR_WFL_NODE (node));
10777           lineno = save_lineno;
10778           EXPR_WFL_NODE (node) = body;
10779           TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (body);
10780           CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (body);
10781           if (body == empty_stmt_node)
10782             {
10783               /* Optimization;  makes it easier to detect empty bodies. */
10784               return body;
10785             }
10786           if (body == error_mark_node)
10787             {
10788               /* Its important for the evaluation of assignment that
10789                  this mark on the TREE_TYPE is propagated. */
10790               TREE_TYPE (node) = error_mark_node;
10791               return error_mark_node;
10792             }
10793           else
10794             TREE_TYPE (node) = TREE_TYPE (EXPR_WFL_NODE (node));
10795           
10796         }
10797       break;
10798
10799     case NEW_ARRAY_EXPR:
10800       /* Patch all the dimensions */
10801       flag = 0;
10802       for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
10803         {
10804           int location = EXPR_WFL_LINECOL (TREE_VALUE (cn));
10805           tree dim = convert (int_type_node, 
10806                               java_complete_tree (TREE_VALUE (cn)));
10807           if (dim == error_mark_node)
10808             {
10809               flag = 1;
10810               continue;
10811             }
10812           else
10813             {
10814               TREE_VALUE (cn) = dim;
10815               /* Setup the location of the current dimension, for
10816                  later error report. */
10817               TREE_PURPOSE (cn) = 
10818                 build_expr_wfl (NULL_TREE, input_filename, 0, 0);
10819               EXPR_WFL_LINECOL (TREE_PURPOSE (cn)) = location;
10820             }
10821         }
10822       /* They complete the array creation expression, if no errors
10823          were found. */
10824       CAN_COMPLETE_NORMALLY (node) = 1;
10825       return (flag ? error_mark_node
10826               : force_evaluation_order (patch_newarray (node)));
10827
10828     case NEW_ANONYMOUS_ARRAY_EXPR:
10829       /* Create the array type if necessary. */
10830       if (ANONYMOUS_ARRAY_DIMS_SIG (node))
10831         {
10832           tree type = ANONYMOUS_ARRAY_BASE_TYPE (node);
10833           if (!(type = resolve_type_during_patch (type)))
10834             return error_mark_node;
10835           type = build_array_from_name (type, NULL_TREE,
10836                                         ANONYMOUS_ARRAY_DIMS_SIG (node), NULL);
10837           ANONYMOUS_ARRAY_BASE_TYPE (node) = build_pointer_type (type);
10838         }
10839       node = patch_new_array_init (ANONYMOUS_ARRAY_BASE_TYPE (node),
10840                                    ANONYMOUS_ARRAY_INITIALIZER (node));
10841       if (node == error_mark_node)
10842         return error_mark_node;
10843       CAN_COMPLETE_NORMALLY (node) = 1;
10844       return node;
10845
10846     case NEW_CLASS_EXPR:
10847     case CALL_EXPR:
10848       /* Complete function's argument(s) first */
10849       if (complete_function_arguments (node))
10850         return error_mark_node;
10851       else
10852         {
10853           tree decl, wfl = TREE_OPERAND (node, 0);
10854           int in_this = CALL_THIS_CONSTRUCTOR_P (node);
10855
10856           node = patch_method_invocation (node, NULL_TREE, 
10857                                           NULL_TREE, 0, &decl);
10858           if (node == error_mark_node)
10859             return error_mark_node;
10860
10861           check_thrown_exceptions (EXPR_WFL_LINECOL (node), decl);
10862           /* If we call this(...), register signature and positions */
10863           if (in_this)
10864             DECL_CONSTRUCTOR_CALLS (current_function_decl) = 
10865               tree_cons (wfl, decl, 
10866                          DECL_CONSTRUCTOR_CALLS (current_function_decl));
10867           CAN_COMPLETE_NORMALLY (node) = 1;
10868           return force_evaluation_order (node);
10869         }
10870
10871     case MODIFY_EXPR:
10872       /* Save potential wfls */
10873       wfl_op1 = TREE_OPERAND (node, 0);
10874       TREE_OPERAND (node, 0) = nn = java_complete_lhs (wfl_op1);
10875       
10876       if (MODIFY_EXPR_FROM_INITIALIZATION_P (node)
10877           && TREE_CODE (nn) == VAR_DECL && TREE_STATIC (nn)
10878           && DECL_INITIAL (nn) != NULL_TREE)
10879         {
10880           tree value;
10881           
10882           push_obstacks (&permanent_obstack, &permanent_obstack);
10883           value = fold_constant_for_init (nn, nn);
10884           pop_obstacks ();
10885
10886           if (value != NULL_TREE)
10887             {
10888               tree type = TREE_TYPE (value);
10889               if (JPRIMITIVE_TYPE_P (type) || 
10890                   (type == string_ptr_type_node && ! flag_emit_class_files))
10891                 return empty_stmt_node;
10892             }
10893           DECL_INITIAL (nn) = NULL_TREE;
10894         }
10895       wfl_op2 = TREE_OPERAND (node, 1);
10896
10897       if (TREE_OPERAND (node, 0) == error_mark_node)
10898         return error_mark_node;
10899
10900       flag = COMPOUND_ASSIGN_P (wfl_op2);
10901       if (flag)
10902         {
10903           /* This might break when accessing outer field from inner
10904              class. TESTME, FIXME */
10905           tree lvalue = java_stabilize_reference (TREE_OPERAND (node, 0)); 
10906
10907           /* Hand stablize the lhs on both places */
10908           TREE_OPERAND (node, 0) = lvalue;
10909           TREE_OPERAND (TREE_OPERAND (node, 1), 0) = 
10910             (flag_emit_class_files ? lvalue : save_expr (lvalue));
10911
10912           /* 15.25.2.a: Left hand is not an array access. FIXME */
10913           /* Now complete the RHS. We write it back later on. */
10914           nn = java_complete_tree (TREE_OPERAND (node, 1));
10915
10916           if ((cn = patch_string (nn)))
10917             nn = cn;
10918
10919           /* The last part of the rewrite for E1 op= E2 is to have 
10920              E1 = (T)(E1 op E2), with T being the type of E1. */
10921           nn = java_complete_tree (build_cast (EXPR_WFL_LINECOL (wfl_op2), 
10922                                                TREE_TYPE (lvalue), nn));
10923
10924           /* 15.25.2.b: Left hand is an array access. FIXME */
10925         }
10926
10927       /* If we're about to patch a NEW_ARRAY_INIT, we call a special
10928          function to complete this RHS. Note that a NEW_ARRAY_INIT
10929          might have been already fully expanded if created as a result
10930          of processing an anonymous array initializer. We avoid doing
10931          the operation twice by testing whether the node already bears
10932          a type. */
10933       else if (TREE_CODE (wfl_op2) == NEW_ARRAY_INIT && !TREE_TYPE (wfl_op2))
10934         nn = patch_new_array_init (TREE_TYPE (TREE_OPERAND (node, 0)),
10935                                    TREE_OPERAND (node, 1));
10936       /* Otherwise we simply complete the RHS */
10937       else
10938         nn = java_complete_tree (TREE_OPERAND (node, 1));
10939
10940       if (nn == error_mark_node)
10941         return error_mark_node;
10942
10943       /* Write back the RHS as we evaluated it. */
10944       TREE_OPERAND (node, 1) = nn;
10945
10946       /* In case we're handling = with a String as a RHS, we need to
10947          produce a String out of the RHS (it might still be a
10948          STRING_CST or a StringBuffer at this stage */
10949       if ((nn = patch_string (TREE_OPERAND (node, 1))))
10950         TREE_OPERAND (node, 1) = nn;
10951
10952       if ((nn = outer_field_access_fix (wfl_op1, TREE_OPERAND (node, 0),
10953                                         TREE_OPERAND (node, 1))))
10954         {
10955           /* We return error_mark_node if outer_field_access_fix
10956              detects we write into a final. */
10957           if (nn == error_mark_node)
10958             return error_mark_node;
10959           node = nn;
10960         }
10961       else
10962         {
10963           node = patch_assignment (node, wfl_op1, wfl_op2);
10964           /* Reorganize the tree if necessary. */
10965           if (flag && (!JREFERENCE_TYPE_P (TREE_TYPE (node)) 
10966                        || JSTRING_P (TREE_TYPE (node))))
10967             node = java_refold (node);
10968         }
10969       
10970       CAN_COMPLETE_NORMALLY (node) = 1;
10971       return node;
10972
10973     case MULT_EXPR:
10974     case PLUS_EXPR:
10975     case MINUS_EXPR:
10976     case LSHIFT_EXPR:
10977     case RSHIFT_EXPR:
10978     case URSHIFT_EXPR:
10979     case BIT_AND_EXPR:
10980     case BIT_XOR_EXPR:
10981     case BIT_IOR_EXPR:
10982     case TRUNC_MOD_EXPR:
10983     case TRUNC_DIV_EXPR:
10984     case RDIV_EXPR:
10985     case TRUTH_ANDIF_EXPR:
10986     case TRUTH_ORIF_EXPR:
10987     case EQ_EXPR: 
10988     case NE_EXPR:
10989     case GT_EXPR:
10990     case GE_EXPR:
10991     case LT_EXPR:
10992     case LE_EXPR:
10993       /* Operands 0 and 1 are WFL in certain cases only. patch_binop
10994          knows how to handle those cases. */
10995       wfl_op1 = TREE_OPERAND (node, 0);
10996       wfl_op2 = TREE_OPERAND (node, 1);
10997
10998       CAN_COMPLETE_NORMALLY (node) = 1;
10999       /* Don't complete string nodes if dealing with the PLUS operand. */
11000       if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op1))
11001         {
11002           nn = java_complete_tree (wfl_op1);
11003           if (nn == error_mark_node)
11004             return error_mark_node;
11005
11006           TREE_OPERAND (node, 0) = nn;
11007         }
11008       if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op2))
11009         {
11010           nn = java_complete_tree (wfl_op2);
11011           if (nn == error_mark_node)
11012             return error_mark_node;
11013
11014           TREE_OPERAND (node, 1) = nn;
11015         }
11016       return force_evaluation_order (patch_binop (node, wfl_op1, wfl_op2));
11017
11018     case INSTANCEOF_EXPR:
11019       wfl_op1 = TREE_OPERAND (node, 0);
11020       COMPLETE_CHECK_OP_0 (node);
11021       if (flag_emit_xref)
11022         {
11023           TREE_TYPE (node) = boolean_type_node;
11024           return node;
11025         }
11026       return patch_binop (node, wfl_op1, TREE_OPERAND (node, 1));
11027
11028     case UNARY_PLUS_EXPR:
11029     case NEGATE_EXPR:
11030     case TRUTH_NOT_EXPR:
11031     case BIT_NOT_EXPR:
11032     case PREDECREMENT_EXPR:
11033     case PREINCREMENT_EXPR:
11034     case POSTDECREMENT_EXPR:
11035     case POSTINCREMENT_EXPR:
11036     case CONVERT_EXPR:
11037       /* There are cases were wfl_op1 is a WFL. patch_unaryop knows
11038          how to handle those cases. */
11039       wfl_op1 = TREE_OPERAND (node, 0);
11040       CAN_COMPLETE_NORMALLY (node) = 1;
11041       TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
11042       if (TREE_OPERAND (node, 0) == error_mark_node)
11043         return error_mark_node;
11044       node = patch_unaryop (node, wfl_op1);
11045       CAN_COMPLETE_NORMALLY (node) = 1;
11046       break;
11047
11048     case ARRAY_REF:
11049       /* There are cases were wfl_op1 is a WFL. patch_array_ref knows
11050          how to handle those cases. */
11051       wfl_op1 = TREE_OPERAND (node, 0);
11052       TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
11053       if (TREE_OPERAND (node, 0) == error_mark_node)
11054         return error_mark_node;
11055       if (!flag_emit_class_files && !flag_emit_xref)
11056         TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
11057       /* The same applies to wfl_op2 */
11058       wfl_op2 = TREE_OPERAND (node, 1);
11059       TREE_OPERAND (node, 1) = java_complete_tree (wfl_op2);
11060       if (TREE_OPERAND (node, 1) == error_mark_node)
11061         return error_mark_node;
11062       if (!flag_emit_class_files && !flag_emit_xref)
11063         TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1));
11064       return patch_array_ref (node);
11065
11066     case RECORD_TYPE:
11067       return node;;
11068
11069     case COMPONENT_REF:
11070       /* The first step in the re-write of qualified name handling.  FIXME.
11071          So far, this is only to support PRIMTYPE.class -> PRIMCLASS.TYPE. */
11072       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
11073       if (TREE_CODE (TREE_OPERAND (node, 0)) == RECORD_TYPE)
11074         {
11075           tree name = TREE_OPERAND (node, 1);
11076           tree field = lookup_field_wrapper (TREE_OPERAND (node, 0), name);
11077           if (field == NULL_TREE)
11078             {
11079               error ("missing static field `%s'", IDENTIFIER_POINTER (name));
11080               return error_mark_node;
11081             }
11082           if (! FIELD_STATIC (field))
11083             {
11084               error ("not a static field `%s'", IDENTIFIER_POINTER (name));
11085               return error_mark_node;
11086             }
11087           return field;
11088         }
11089       else
11090         fatal ("unimplemented java_complete_tree for COMPONENT_REF");
11091       break;
11092
11093     case THIS_EXPR:
11094       /* Can't use THIS in a static environment */
11095       if (!current_this)
11096         {
11097           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11098           parse_error_context (wfl_operator,
11099                                "Keyword `this' used outside allowed context");
11100           TREE_TYPE (node) = error_mark_node;
11101           return error_mark_node;
11102         }
11103       if (ctxp->explicit_constructor_p)
11104         {
11105           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11106           parse_error_context 
11107             (wfl_operator, "Can't reference `this' or `super' before the superclass constructor has been called");
11108           TREE_TYPE (node) = error_mark_node;
11109           return error_mark_node;
11110         }
11111       return current_this;
11112       
11113     case CLASS_LITERAL:
11114       CAN_COMPLETE_NORMALLY (node) = 1;
11115       node = patch_incomplete_class_ref (node);
11116       if (node == error_mark_node)
11117         return error_mark_node;
11118       break;
11119
11120     case INSTANCE_INITIALIZERS_EXPR:
11121       in_instance_initializer++;
11122       node = java_complete_tree (TREE_OPERAND (node, 0));
11123       in_instance_initializer--;
11124       if (node != error_mark_node)
11125         TREE_TYPE (node) = void_type_node;
11126       else
11127         return error_mark_node;
11128       break;
11129
11130     default:
11131       CAN_COMPLETE_NORMALLY (node) = 1;
11132       /* Ok: may be we have a STRING_CST or a crafted `StringBuffer'
11133          and it's time to turn it into the appropriate String object */
11134       if ((nn = patch_string (node)))
11135         node = nn;
11136       else
11137         fatal ("No case for tree code `%s' - java_complete_tree\n",
11138                tree_code_name [TREE_CODE (node)]);
11139     }
11140   return node;
11141 }
11142
11143 /* Complete function call's argument. Return a non zero value is an
11144    error was found.  */
11145
11146 static int
11147 complete_function_arguments (node)
11148      tree node;
11149 {
11150   int flag = 0;
11151   tree cn;
11152
11153   ctxp->explicit_constructor_p += (CALL_EXPLICIT_CONSTRUCTOR_P (node) ? 1 : 0);
11154   for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
11155     {
11156       tree wfl = TREE_VALUE (cn), parm, temp;
11157       parm = java_complete_tree (wfl);
11158
11159       if (parm == error_mark_node)
11160         {
11161           flag = 1;
11162           continue;
11163         }
11164       /* If have a string literal that we haven't transformed yet or a
11165          crafted string buffer, as a result of use of the the String
11166          `+' operator. Build `parm.toString()' and expand it. */
11167       if ((temp = patch_string (parm)))
11168         parm = temp;
11169       /* Inline PRIMTYPE.TYPE read access */
11170       parm = maybe_build_primttype_type_ref (parm, wfl);
11171
11172       TREE_VALUE (cn) = parm;
11173     }
11174   ctxp->explicit_constructor_p -= (CALL_EXPLICIT_CONSTRUCTOR_P (node) ? 1 : 0);
11175   return flag;
11176 }
11177
11178 /* Sometimes (for loops and variable initialized during their
11179    declaration), we want to wrap a statement around a WFL and turn it
11180    debugable.  */
11181
11182 static tree
11183 build_debugable_stmt (location, stmt)
11184     int location;
11185     tree stmt;
11186 {
11187   if (TREE_CODE (stmt) != EXPR_WITH_FILE_LOCATION)
11188     {
11189       stmt = build_expr_wfl (stmt, input_filename, 0, 0);
11190       EXPR_WFL_LINECOL (stmt) = location;
11191     }
11192   JAVA_MAYBE_GENERATE_DEBUG_INFO (stmt);
11193   return stmt;
11194 }
11195
11196 static tree
11197 build_expr_block (body, decls)
11198      tree body, decls;
11199 {
11200   tree node = make_node (BLOCK);
11201   BLOCK_EXPR_DECLS (node) = decls;
11202   BLOCK_EXPR_BODY (node) = body;
11203   if (body)
11204     TREE_TYPE (node) = TREE_TYPE (body);
11205   TREE_SIDE_EFFECTS (node) = 1;
11206   return node;
11207 }
11208
11209 /* Create a new function block and link it approriately to current
11210    function block chain */
11211
11212 static tree
11213 enter_block ()
11214 {
11215   return (enter_a_block (build_expr_block (NULL_TREE, NULL_TREE)));
11216 }
11217
11218 /* Link block B supercontext to the previous block. The current
11219    function DECL is used as supercontext when enter_a_block is called
11220    for the first time for a given function. The current function body
11221    (DECL_FUNCTION_BODY) is set to be block B.  */
11222
11223 static tree
11224 enter_a_block (b)
11225      tree b;
11226 {
11227   tree fndecl = current_function_decl; 
11228
11229   if (!fndecl) {
11230     BLOCK_SUPERCONTEXT (b) = current_static_block;
11231     current_static_block = b;
11232   }
11233
11234   else if (!DECL_FUNCTION_BODY (fndecl))
11235     {
11236       BLOCK_SUPERCONTEXT (b) = fndecl;
11237       DECL_FUNCTION_BODY (fndecl) = b;
11238     }
11239   else
11240     {
11241       BLOCK_SUPERCONTEXT (b) = DECL_FUNCTION_BODY (fndecl);
11242       DECL_FUNCTION_BODY (fndecl) = b;
11243     }
11244   return b;
11245 }
11246
11247 /* Exit a block by changing the current function body
11248    (DECL_FUNCTION_BODY) to the current block super context, only if
11249    the block being exited isn't the method's top level one.  */
11250
11251 static tree
11252 exit_block ()
11253 {
11254   tree b;
11255   if (current_function_decl)
11256     {
11257       b = DECL_FUNCTION_BODY (current_function_decl);
11258       if (BLOCK_SUPERCONTEXT (b) != current_function_decl)
11259         DECL_FUNCTION_BODY (current_function_decl) = BLOCK_SUPERCONTEXT (b);
11260     }
11261   else
11262     {
11263       b = current_static_block;
11264
11265       if (BLOCK_SUPERCONTEXT (b))
11266         current_static_block = BLOCK_SUPERCONTEXT (b);
11267     }
11268   return b;
11269 }
11270
11271 /* Lookup for NAME in the nested function's blocks, all the way up to
11272    the current toplevel one. It complies with Java's local variable
11273    scoping rules.  */
11274
11275 static tree
11276 lookup_name_in_blocks (name)
11277      tree name;
11278 {
11279   tree b = GET_CURRENT_BLOCK (current_function_decl);
11280
11281   while (b != current_function_decl)
11282     {
11283       tree current;
11284
11285       /* Paranoid sanity check. To be removed */
11286       if (TREE_CODE (b) != BLOCK)
11287         fatal ("non block expr function body - lookup_name_in_blocks");
11288
11289       for (current = BLOCK_EXPR_DECLS (b); current; 
11290            current = TREE_CHAIN (current))
11291         if (DECL_NAME (current) == name)
11292           return current;
11293       b = BLOCK_SUPERCONTEXT (b);
11294     }
11295   return NULL_TREE;
11296 }
11297
11298 static void
11299 maybe_absorb_scoping_blocks ()
11300 {
11301   while (BLOCK_EXPR_ORIGIN (GET_CURRENT_BLOCK (current_function_decl)))
11302     {
11303       tree b = exit_block ();
11304       java_method_add_stmt (current_function_decl, b);
11305       SOURCE_FRONTEND_DEBUG (("Absorbing scoping block at line %d", lineno));
11306     }
11307 }
11308
11309 \f
11310 /* This section of the source is reserved to build_* functions that
11311    are building incomplete tree nodes and the patch_* functions that
11312    are completing them.  */
11313
11314 /* Wrap a non WFL node around a WFL.  */
11315 static tree
11316 build_wfl_wrap (node)
11317     tree node;
11318 {
11319   tree wfl, node_to_insert = node;
11320   
11321   /* We want to process THIS . xxx symbolicaly, to keep it consistent
11322      with the way we're processing SUPER. A THIS from a primary as a
11323      different form than a SUPER. Turn THIS into something symbolic */
11324   if (TREE_CODE (node) == THIS_EXPR)
11325     node_to_insert = wfl = build_wfl_node (this_identifier_node);
11326   else
11327     wfl = build_expr_wfl (NULL_TREE, ctxp->filename, 0, 0);
11328
11329   EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (node);
11330   EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (node_to_insert, NULL_TREE);
11331   return wfl;
11332 }
11333
11334
11335 /* Build a super() constructor invocation. Returns empty_stmt_node if
11336    we're currently dealing with the class java.lang.Object. */
11337
11338 static tree
11339 build_super_invocation (mdecl)
11340      tree mdecl;
11341 {
11342   if (DECL_CONTEXT (mdecl) == object_type_node)
11343     return empty_stmt_node;
11344   else
11345     {
11346       tree super_wfl = build_wfl_node (super_identifier_node);
11347       tree a = NULL_TREE, t;
11348       /* If we're dealing with an anonymous class, pass the arguments
11349          of the crafted constructor along. */
11350       if (ANONYMOUS_CLASS_P (DECL_CONTEXT (mdecl)))
11351         {
11352           SKIP_THIS_AND_ARTIFICIAL_PARMS (t, mdecl);
11353           for (; t != end_params_node; t = TREE_CHAIN (t))
11354             a = tree_cons (NULL_TREE, build_wfl_node (TREE_PURPOSE (t)), a);
11355         }
11356       return build_method_invocation (super_wfl, a);
11357     }
11358 }
11359
11360 /* Build a SUPER/THIS qualified method invocation.  */
11361
11362 static tree
11363 build_this_super_qualified_invocation (use_this, name, args, lloc, rloc)
11364      int use_this;
11365      tree name, args;
11366      int lloc, rloc;
11367 {
11368   tree invok;
11369   tree wfl = 
11370     build_wfl_node (use_this ? this_identifier_node : super_identifier_node);
11371   EXPR_WFL_LINECOL (wfl) = lloc;
11372   invok = build_method_invocation (name, args);
11373   return make_qualified_primary (wfl, invok, rloc);
11374 }
11375
11376 /* Build an incomplete CALL_EXPR node. */
11377
11378 static tree
11379 build_method_invocation (name, args)
11380     tree name;
11381     tree args;
11382 {
11383   tree call = build (CALL_EXPR, NULL_TREE, name, args, NULL_TREE);
11384   TREE_SIDE_EFFECTS (call) = 1;
11385   EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
11386   return call;
11387 }
11388
11389 /* Build an incomplete new xxx(...) node. */
11390
11391 static tree
11392 build_new_invocation (name, args)
11393     tree name, args;
11394 {
11395   tree call = build (NEW_CLASS_EXPR, NULL_TREE, name, args, NULL_TREE);
11396   TREE_SIDE_EFFECTS (call) = 1;
11397   EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
11398   return call;
11399 }
11400
11401 /* Build an incomplete assignment expression. */
11402
11403 static tree
11404 build_assignment (op, op_location, lhs, rhs)
11405      int op, op_location;
11406      tree lhs, rhs;
11407 {
11408   tree assignment;
11409   /* Build the corresponding binop if we deal with a Compound
11410      Assignment operator. Mark the binop sub-tree as part of a
11411      Compound Assignment expression */
11412   if (op != ASSIGN_TK)
11413     {
11414       rhs = build_binop (BINOP_LOOKUP (op), op_location, lhs, rhs);
11415       COMPOUND_ASSIGN_P (rhs) = 1;
11416     }
11417   assignment = build (MODIFY_EXPR, NULL_TREE, lhs, rhs);
11418   TREE_SIDE_EFFECTS (assignment) = 1;
11419   EXPR_WFL_LINECOL (assignment) = op_location;
11420   return assignment;
11421 }
11422
11423 /* Print an INTEGER_CST node in a static buffer, and return the buffer. */
11424
11425 char *
11426 print_int_node (node)
11427     tree node;
11428 {
11429   static char buffer [80];
11430   if (TREE_CONSTANT_OVERFLOW (node))
11431     sprintf (buffer, "<overflow>");
11432     
11433   if (TREE_INT_CST_HIGH (node) == 0)
11434     sprintf (buffer, HOST_WIDE_INT_PRINT_UNSIGNED,
11435              TREE_INT_CST_LOW (node));
11436   else if (TREE_INT_CST_HIGH (node) == -1
11437            && TREE_INT_CST_LOW (node) != 0)
11438     {
11439       buffer [0] = '-';
11440       sprintf (&buffer [1], HOST_WIDE_INT_PRINT_UNSIGNED,
11441                -TREE_INT_CST_LOW (node));
11442     }
11443   else
11444     sprintf (buffer, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
11445              TREE_INT_CST_HIGH (node), TREE_INT_CST_LOW (node));
11446
11447   return buffer;
11448 }
11449
11450 /* Return 1 if an assignment to a FINAL is attempted in a non suitable
11451    context.  */
11452
11453 static int
11454 check_final_assignment (lvalue, wfl)
11455      tree lvalue, wfl;
11456 {
11457   if (TREE_CODE (lvalue) == COMPOUND_EXPR 
11458       && JDECL_P (TREE_OPERAND (lvalue, 1)))
11459     lvalue = TREE_OPERAND (lvalue, 1);
11460
11461   /* When generating class files, references to the `length' field
11462      look a bit different.  */
11463   if ((flag_emit_class_files
11464        && TREE_CODE (lvalue) == COMPONENT_REF
11465        && TYPE_ARRAY_P (TREE_TYPE (TREE_OPERAND (lvalue, 0)))
11466        && FIELD_FINAL (TREE_OPERAND (lvalue, 1)))
11467       || (TREE_CODE (lvalue) == FIELD_DECL
11468           && FIELD_FINAL (lvalue)
11469           && !DECL_CLINIT_P (current_function_decl)
11470           && !DECL_FINIT_P (current_function_decl)))
11471     {
11472       parse_error_context 
11473         (wfl, "Can't assign a value to the final variable `%s'",
11474          IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
11475       return 1;
11476     }
11477   return 0;
11478 }
11479
11480 /* Inline references to java.lang.PRIMTYPE.TYPE when accessed in
11481    read. This is needed to avoid circularities in the implementation
11482    of these fields in libjava. */
11483
11484 static tree
11485 maybe_build_primttype_type_ref (rhs, wfl)
11486     tree rhs, wfl;
11487 {
11488   tree to_return = NULL_TREE;
11489   tree rhs_type = TREE_TYPE (rhs);
11490   if (TREE_CODE (rhs) == COMPOUND_EXPR)
11491     {
11492       tree n = TREE_OPERAND (rhs, 1);
11493       if (TREE_CODE (n) == VAR_DECL 
11494           && DECL_NAME (n) == TYPE_identifier_node
11495           && rhs_type == class_ptr_type)
11496         {
11497           const char *self_name = IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl));
11498           if (!strncmp (self_name, "java.lang.", 10))
11499             to_return = build_primtype_type_ref (self_name);
11500         }
11501     }
11502   return (to_return ? to_return : rhs );
11503 }
11504
11505 /* 15.25 Assignment operators. */
11506
11507 static tree
11508 patch_assignment (node, wfl_op1, wfl_op2)
11509      tree node;
11510      tree wfl_op1;
11511      tree wfl_op2;
11512 {
11513   tree rhs = TREE_OPERAND (node, 1);
11514   tree lvalue = TREE_OPERAND (node, 0), llvalue;
11515   tree lhs_type = NULL_TREE, rhs_type, new_rhs = NULL_TREE;
11516   int error_found = 0;
11517   int lvalue_from_array = 0;
11518
11519   /* Can't assign to a (blank) final. */
11520   if (check_final_assignment (lvalue, wfl_op1))
11521     error_found = 1;
11522
11523   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11524
11525   /* Lhs can be a named variable */
11526   if (JDECL_P (lvalue))
11527     {
11528       lhs_type = TREE_TYPE (lvalue);
11529     }
11530   /* Or Lhs can be a array acccess. Should that be lvalue ? FIXME +
11531      comment on reason why */
11532   else if (TREE_CODE (wfl_op1) == ARRAY_REF)
11533     {
11534       lhs_type = TREE_TYPE (lvalue);
11535       lvalue_from_array = 1;
11536     }
11537   /* Or a field access */
11538   else if (TREE_CODE (lvalue) == COMPONENT_REF)
11539     lhs_type = TREE_TYPE (lvalue);
11540   /* Or a function return slot */
11541   else if (TREE_CODE (lvalue) == RESULT_DECL)
11542     lhs_type = TREE_TYPE (lvalue);
11543   /* Otherwise, we might want to try to write into an optimized static
11544      final, this is an of a different nature, reported further on. */
11545   else if (TREE_CODE (wfl_op1) == EXPR_WITH_FILE_LOCATION
11546            && resolve_expression_name (wfl_op1, &llvalue))
11547     {
11548       if (!error_found && check_final_assignment (llvalue, wfl_op1))
11549         {
11550           /* What we should do instead is resetting the all the flags
11551              previously set, exchange lvalue for llvalue and continue. */
11552           error_found = 1;
11553           return error_mark_node;
11554         }
11555       else 
11556         lhs_type = TREE_TYPE (lvalue);
11557     }
11558   else 
11559     {
11560       parse_error_context (wfl_op1, "Invalid left hand side of assignment");
11561       error_found = 1;
11562     }
11563
11564   rhs_type = TREE_TYPE (rhs);
11565   /* 5.1 Try the assignment conversion for builtin type. */
11566   new_rhs = try_builtin_assignconv (wfl_op1, lhs_type, rhs);
11567
11568   /* 5.2 If it failed, try a reference conversion */
11569   if (!new_rhs && (new_rhs = try_reference_assignconv (lhs_type, rhs)))
11570     lhs_type = promote_type (rhs_type);
11571
11572   /* 15.25.2 If we have a compound assignment, convert RHS into the
11573      type of the LHS */
11574   else if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
11575     new_rhs = convert (lhs_type, rhs);
11576
11577   /* Explicit cast required. This is an error */
11578   if (!new_rhs)
11579     {
11580       char *t1 = xstrdup (lang_printable_name (TREE_TYPE (rhs), 0));
11581       char *t2 = xstrdup (lang_printable_name (lhs_type, 0));
11582       tree wfl;
11583       char operation [32];      /* Max size known */
11584
11585       /* If the assignment is part of a declaration, we use the WFL of
11586          the declared variable to point out the error and call it a
11587          declaration problem. If the assignment is a genuine =
11588          operator, we call is a operator `=' problem, otherwise we
11589          call it an assignment problem. In both of these last cases,
11590          we use the WFL of the operator to indicate the error. */
11591
11592       if (MODIFY_EXPR_FROM_INITIALIZATION_P (node))
11593         {
11594           wfl = wfl_op1;
11595           strcpy (operation, "declaration");
11596         }
11597       else
11598         {
11599           wfl = wfl_operator;
11600           if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
11601             strcpy (operation, "assignment");
11602           else if (TREE_CODE (TREE_OPERAND (node, 0)) == RESULT_DECL)
11603             strcpy (operation, "`return'");
11604           else
11605             strcpy (operation, "`='");
11606         }
11607
11608       if (!valid_cast_to_p (rhs_type, lhs_type))
11609         parse_error_context
11610           (wfl, "Incompatible type for %s. Can't convert `%s' to `%s'",
11611            operation, t1, t2);
11612       else
11613         parse_error_context (wfl, "Incompatible type for %s. Explicit cast needed to convert `%s' to `%s'",
11614                              operation, t1, t2);
11615       free (t1); free (t2);
11616       error_found = 1;
11617     }
11618
11619   /* Inline read access to java.lang.PRIMTYPE.TYPE */
11620   if (new_rhs)
11621     new_rhs = maybe_build_primttype_type_ref (new_rhs, wfl_op2);
11622
11623   if (error_found)
11624     return error_mark_node;
11625
11626   /* 10.10: Array Store Exception runtime check */
11627   if (!flag_emit_class_files
11628       && !flag_emit_xref
11629       && lvalue_from_array 
11630       && JREFERENCE_TYPE_P (TYPE_ARRAY_ELEMENT (lhs_type)))
11631     {
11632       tree check;
11633       tree base = lvalue;
11634
11635       /* We need to retrieve the right argument for _Jv_CheckArrayStore */
11636       if (TREE_CODE (lvalue) == COMPOUND_EXPR)
11637         base = TREE_OPERAND (lvalue, 0);
11638       else
11639         {
11640           if (flag_bounds_check)
11641             base = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (base, 0), 1), 0);
11642           else
11643             base = TREE_OPERAND (TREE_OPERAND (base, 0), 0);
11644         }
11645
11646       /* Build the invocation of _Jv_CheckArrayStore */
11647       new_rhs = save_expr (new_rhs);
11648       check = build (CALL_EXPR, void_type_node,
11649                      build_address_of (soft_checkarraystore_node),
11650                      tree_cons (NULL_TREE, base,
11651                                 build_tree_list (NULL_TREE, new_rhs)),
11652                      NULL_TREE);
11653       TREE_SIDE_EFFECTS (check) = 1;
11654
11655       /* We have to decide on an insertion point */
11656       if (TREE_CODE (lvalue) == COMPOUND_EXPR)
11657         {
11658           tree t;
11659           if (flag_bounds_check)
11660             {
11661               t = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (lvalue, 1), 0), 0);
11662               TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (lvalue, 1), 0), 0) =
11663                 build (COMPOUND_EXPR, void_type_node, t, check);
11664             }
11665           else
11666             TREE_OPERAND (lvalue, 1) = build (COMPOUND_EXPR, lhs_type,
11667                                               check, TREE_OPERAND (lvalue, 1));
11668         }
11669       else 
11670         {
11671           /* Make sure the bound check will happen before the store check */
11672           if (flag_bounds_check)
11673             TREE_OPERAND (TREE_OPERAND (lvalue, 0), 0) =
11674               build (COMPOUND_EXPR, void_type_node,
11675                      TREE_OPERAND (TREE_OPERAND (lvalue, 0), 0), check);
11676           else
11677             lvalue = build (COMPOUND_EXPR, lhs_type, check, lvalue);
11678         }
11679     }
11680
11681   TREE_OPERAND (node, 0) = lvalue;
11682   TREE_OPERAND (node, 1) = new_rhs;
11683   TREE_TYPE (node) = lhs_type;
11684   return node;
11685 }
11686
11687 /* Check that type SOURCE can be cast into type DEST. If the cast
11688    can't occur at all, return 0 otherwise 1. This function is used to
11689    produce accurate error messages on the reasons why an assignment
11690    failed. */
11691
11692 static tree
11693 try_reference_assignconv (lhs_type, rhs)
11694      tree lhs_type, rhs;
11695 {
11696   tree new_rhs = NULL_TREE;
11697   tree rhs_type = TREE_TYPE (rhs);
11698
11699   if (!JPRIMITIVE_TYPE_P (rhs_type) && JREFERENCE_TYPE_P (lhs_type))
11700     {
11701       /* `null' may be assigned to any reference type */
11702       if (rhs == null_pointer_node)
11703         new_rhs = null_pointer_node;
11704       /* Try the reference assignment conversion */
11705       else if (valid_ref_assignconv_cast_p (rhs_type, lhs_type, 0))
11706         new_rhs = rhs;
11707       /* This is a magic assignment that we process differently */
11708       else if (rhs == soft_exceptioninfo_call_node)
11709         new_rhs = rhs;
11710     }
11711   return new_rhs;
11712 }
11713
11714 /* Check that RHS can be converted into LHS_TYPE by the assignment
11715    conversion (5.2), for the cases of RHS being a builtin type. Return
11716    NULL_TREE if the conversion fails or if because RHS isn't of a
11717    builtin type. Return a converted RHS if the conversion is possible.  */
11718
11719 static tree
11720 try_builtin_assignconv (wfl_op1, lhs_type, rhs)
11721      tree wfl_op1, lhs_type, rhs;
11722 {
11723   tree new_rhs = NULL_TREE;
11724   tree rhs_type = TREE_TYPE (rhs);
11725
11726   /* Zero accepted everywhere */
11727   if (TREE_CODE (rhs) == INTEGER_CST 
11728       && TREE_INT_CST_HIGH (rhs) == 0 && TREE_INT_CST_LOW (rhs) == 0
11729       && JPRIMITIVE_TYPE_P (rhs_type))
11730     new_rhs = convert (lhs_type, rhs);
11731
11732   /* 5.1.1 Try Identity Conversion,
11733      5.1.2 Try Widening Primitive Conversion */
11734   else if (valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type))
11735     new_rhs = convert (lhs_type, rhs);
11736
11737   /* Try a narrowing primitive conversion (5.1.3): 
11738        - expression is a constant expression of type int AND
11739        - variable is byte, short or char AND
11740        - The value of the expression is representable in the type of the 
11741          variable */
11742   else if (rhs_type == int_type_node && TREE_CONSTANT (rhs)
11743            && (lhs_type == byte_type_node || lhs_type == char_type_node
11744                || lhs_type == short_type_node))
11745     {
11746       if (int_fits_type_p (rhs, lhs_type))
11747         new_rhs = convert (lhs_type, rhs);
11748       else if (wfl_op1)         /* Might be called with a NULL */
11749         parse_warning_context 
11750           (wfl_op1, "Constant expression `%s' to wide for narrowing primitive conversion to `%s'", 
11751            print_int_node (rhs), lang_printable_name (lhs_type, 0));
11752       /* Reported a warning that will turn into an error further
11753          down, so we don't return */
11754     }
11755
11756   return new_rhs;
11757 }
11758
11759 /* Return 1 if RHS_TYPE can be converted to LHS_TYPE by identity
11760    conversion (5.1.1) or widening primitve conversion (5.1.2).  Return
11761    0 is the conversion test fails.  This implements parts the method
11762    invocation convertion (5.3).  */
11763
11764 static int
11765 valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type)
11766      tree lhs_type, rhs_type;
11767 {
11768   /* 5.1.1: This is the identity conversion part. */
11769   if (lhs_type == rhs_type)
11770     return 1;
11771
11772   /* Reject non primitive types */
11773   if (!JPRIMITIVE_TYPE_P (lhs_type) || !JPRIMITIVE_TYPE_P (rhs_type))
11774     return 0;
11775
11776   /* 5.1.2: widening primitive conversion. byte, even if it's smaller
11777      than a char can't be converted into a char. Short can't too, but
11778      the < test below takes care of that */
11779   if (lhs_type == char_type_node && rhs_type == byte_type_node)
11780     return 0;
11781
11782   /* Accept all promoted type here. Note, we can't use <= in the test
11783      below, because we still need to bounce out assignments of short
11784      to char and the likes */
11785   if (lhs_type == int_type_node
11786       && (rhs_type == promoted_byte_type_node
11787           || rhs_type == promoted_short_type_node
11788           || rhs_type == promoted_char_type_node
11789           || rhs_type == promoted_boolean_type_node))
11790     return 1;
11791
11792   /* From here, an integral is widened if its precision is smaller
11793      than the precision of the LHS or if the LHS is a floating point
11794      type, or the RHS is a float and the RHS a double. */
11795   if ((JINTEGRAL_TYPE_P (rhs_type) && JINTEGRAL_TYPE_P (lhs_type) 
11796        && (TYPE_PRECISION (rhs_type) < TYPE_PRECISION (lhs_type)))
11797       || (JINTEGRAL_TYPE_P (rhs_type) && JFLOAT_TYPE_P (lhs_type))
11798       || (rhs_type == float_type_node && lhs_type == double_type_node))
11799     return 1;
11800
11801   return 0;
11802 }
11803
11804 /* Check that something of SOURCE type can be assigned or cast to
11805    something of DEST type at runtime. Return 1 if the operation is
11806    valid, 0 otherwise. If CAST is set to 1, we're treating the case
11807    were SOURCE is cast into DEST, which borrows a lot of the
11808    assignment check. */
11809
11810 static int
11811 valid_ref_assignconv_cast_p (source, dest, cast)
11812      tree source;
11813      tree dest;
11814      int cast;
11815 {
11816   /* SOURCE or DEST might be null if not from a declared entity. */
11817   if (!source || !dest)
11818     return 0;
11819   if (JNULLP_TYPE_P (source))
11820     return 1;
11821   if (TREE_CODE (source) == POINTER_TYPE)
11822     source = TREE_TYPE (source);
11823   if (TREE_CODE (dest) == POINTER_TYPE)
11824     dest = TREE_TYPE (dest);
11825   /* Case where SOURCE is a class type */
11826   if (TYPE_CLASS_P (source))
11827     {
11828       if (TYPE_CLASS_P (dest))
11829         return  (source == dest 
11830                  || inherits_from_p (source, dest)
11831                  || enclosing_context_p (dest, source /*source, dest*/)
11832                  || (cast && inherits_from_p (dest, source)));
11833       if (TYPE_INTERFACE_P (dest))
11834         {
11835           /* If doing a cast and SOURCE is final, the operation is
11836              always correct a compile time (because even if SOURCE
11837              does not implement DEST, a subclass of SOURCE might). */
11838           if (cast && !CLASS_FINAL (TYPE_NAME (source)))
11839             return 1;
11840           /* Otherwise, SOURCE must implement DEST */
11841           return interface_of_p (dest, source);
11842         }
11843       /* DEST is an array, cast permited if SOURCE is of Object type */
11844       return (cast && source == object_type_node ? 1 : 0);
11845     }
11846   if (TYPE_INTERFACE_P (source))
11847     {
11848       if (TYPE_CLASS_P (dest))
11849         {
11850           /* If not casting, DEST must be the Object type */
11851           if (!cast)
11852             return dest == object_type_node;
11853           /* We're doing a cast. The cast is always valid is class
11854              DEST is not final, otherwise, DEST must implement SOURCE */
11855           else if (!CLASS_FINAL (TYPE_NAME (dest)))
11856             return 1;
11857           else
11858             return interface_of_p (source, dest);
11859         }
11860       if (TYPE_INTERFACE_P (dest))
11861         {
11862           /* If doing a cast, then if SOURCE and DEST contain method
11863              with the same signature but different return type, then
11864              this is a (compile time) error */
11865           if (cast)
11866             {
11867               tree method_source, method_dest;
11868               tree source_type;
11869               tree source_sig;
11870               tree source_name;
11871               for (method_source = TYPE_METHODS (source); method_source; 
11872                    method_source = TREE_CHAIN (method_source))
11873                 {
11874                   source_sig = 
11875                     build_java_argument_signature (TREE_TYPE (method_source));
11876                   source_type = TREE_TYPE (TREE_TYPE (method_source));
11877                   source_name = DECL_NAME (method_source);
11878                   for (method_dest = TYPE_METHODS (dest);
11879                        method_dest; method_dest = TREE_CHAIN (method_dest))
11880                     if (source_sig == 
11881                         build_java_argument_signature (TREE_TYPE (method_dest))
11882                         && source_name == DECL_NAME (method_dest)
11883                         && source_type != TREE_TYPE (TREE_TYPE (method_dest)))
11884                       return 0;
11885                 }
11886               return 1;
11887             }
11888           else
11889             return source == dest || interface_of_p (dest, source);
11890         }
11891       else                      /* Array */
11892         return (cast ? 
11893                 (DECL_NAME (TYPE_NAME (source)) == java_lang_cloneable) : 0);
11894     }
11895   if (TYPE_ARRAY_P (source))
11896     {
11897       if (TYPE_CLASS_P (dest))
11898         return dest == object_type_node;
11899       /* Can't cast an array to an interface unless the interface is
11900          java.lang.Cloneable */
11901       if (TYPE_INTERFACE_P (dest))
11902         return (DECL_NAME (TYPE_NAME (dest)) == java_lang_cloneable ? 1 : 0);
11903       else                      /* Arrays */
11904         {
11905           tree source_element_type = TYPE_ARRAY_ELEMENT (source);
11906           tree dest_element_type = TYPE_ARRAY_ELEMENT (dest);
11907           
11908           /* In case of severe errors, they turn out null */
11909           if (!dest_element_type || !source_element_type)
11910             return 0;
11911           if (source_element_type == dest_element_type)
11912             return 1;
11913           return valid_ref_assignconv_cast_p (source_element_type,
11914                                               dest_element_type, cast);
11915         }
11916       return 0;
11917     }
11918   return 0;
11919 }
11920
11921 static int
11922 valid_cast_to_p (source, dest)
11923      tree source;
11924      tree dest;
11925 {
11926   if (TREE_CODE (source) == POINTER_TYPE)
11927     source = TREE_TYPE (source);
11928   if (TREE_CODE (dest) == POINTER_TYPE)
11929     dest = TREE_TYPE (dest);
11930
11931   if (TREE_CODE (source) == RECORD_TYPE && TREE_CODE (dest) == RECORD_TYPE)
11932     return valid_ref_assignconv_cast_p (source, dest, 1);
11933
11934   else if (JNUMERIC_TYPE_P (source) && JNUMERIC_TYPE_P (dest))
11935     return 1;
11936
11937   return 0;
11938 }
11939
11940 /* Method invocation conversion test. Return 1 if type SOURCE can be
11941    converted to type DEST through the methond invocation conversion
11942    process (5.3) */
11943
11944 static tree
11945 do_unary_numeric_promotion (arg)
11946      tree arg;
11947 {
11948   tree type = TREE_TYPE (arg);
11949   if (TREE_CODE (type) == INTEGER_TYPE ? TYPE_PRECISION (type) < 32
11950       : TREE_CODE (type) == CHAR_TYPE)
11951     arg = convert (int_type_node, arg);
11952   return arg;
11953 }
11954
11955 /* Return a non zero value if SOURCE can be converted into DEST using
11956    the method invocation conversion rule (5.3).  */
11957 static int
11958 valid_method_invocation_conversion_p (dest, source)
11959      tree dest, source;
11960 {
11961   return ((JPRIMITIVE_TYPE_P (source) && JPRIMITIVE_TYPE_P (dest)
11962            && valid_builtin_assignconv_identity_widening_p (dest, source))
11963           || ((JREFERENCE_TYPE_P (source) || JNULLP_TYPE_P (source))
11964               && (JREFERENCE_TYPE_P (dest) || JNULLP_TYPE_P (dest))
11965               && valid_ref_assignconv_cast_p (source, dest, 0)));
11966 }
11967
11968 /* Build an incomplete binop expression. */
11969
11970 static tree
11971 build_binop (op, op_location, op1, op2)
11972      enum tree_code op;
11973      int op_location;
11974      tree op1, op2;
11975 {
11976   tree binop = build (op, NULL_TREE, op1, op2);
11977   TREE_SIDE_EFFECTS (binop) = 1;
11978   /* Store the location of the operator, for better error report. The
11979      string of the operator will be rebuild based on the OP value. */
11980   EXPR_WFL_LINECOL (binop) = op_location;
11981   return binop;
11982 }
11983
11984 /* Build the string of the operator retained by NODE. If NODE is part
11985    of a compound expression, add an '=' at the end of the string. This
11986    function is called when an error needs to be reported on an
11987    operator. The string is returned as a pointer to a static character
11988    buffer. */
11989
11990 static char *
11991 operator_string (node)
11992      tree node;
11993 {
11994 #define BUILD_OPERATOR_STRING(S)                                        \
11995   {                                                                     \
11996     sprintf (buffer, "%s%s", S, (COMPOUND_ASSIGN_P (node) ? "=" : "")); \
11997     return buffer;                                                      \
11998   }
11999   
12000   static char buffer [10];
12001   switch (TREE_CODE (node))
12002     {
12003     case MULT_EXPR: BUILD_OPERATOR_STRING ("*");
12004     case RDIV_EXPR: BUILD_OPERATOR_STRING ("/");
12005     case TRUNC_MOD_EXPR: BUILD_OPERATOR_STRING ("%");
12006     case PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
12007     case MINUS_EXPR: BUILD_OPERATOR_STRING ("-");
12008     case LSHIFT_EXPR: BUILD_OPERATOR_STRING ("<<");
12009     case RSHIFT_EXPR: BUILD_OPERATOR_STRING (">>");
12010     case URSHIFT_EXPR: BUILD_OPERATOR_STRING (">>>");
12011     case BIT_AND_EXPR: BUILD_OPERATOR_STRING ("&");
12012     case BIT_XOR_EXPR: BUILD_OPERATOR_STRING ("^");
12013     case BIT_IOR_EXPR: BUILD_OPERATOR_STRING ("|");
12014     case TRUTH_ANDIF_EXPR: BUILD_OPERATOR_STRING ("&&");
12015     case TRUTH_ORIF_EXPR: BUILD_OPERATOR_STRING ("||");
12016     case EQ_EXPR: BUILD_OPERATOR_STRING ("==");
12017     case NE_EXPR: BUILD_OPERATOR_STRING ("!=");
12018     case GT_EXPR: BUILD_OPERATOR_STRING (">");
12019     case GE_EXPR: BUILD_OPERATOR_STRING (">=");
12020     case LT_EXPR: BUILD_OPERATOR_STRING ("<");
12021     case LE_EXPR: BUILD_OPERATOR_STRING ("<=");
12022     case UNARY_PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
12023     case NEGATE_EXPR: BUILD_OPERATOR_STRING ("-");
12024     case TRUTH_NOT_EXPR: BUILD_OPERATOR_STRING ("!");
12025     case BIT_NOT_EXPR: BUILD_OPERATOR_STRING ("~");
12026     case PREINCREMENT_EXPR:     /* Fall through */
12027     case POSTINCREMENT_EXPR: BUILD_OPERATOR_STRING ("++");
12028     case PREDECREMENT_EXPR:     /* Fall through */
12029     case POSTDECREMENT_EXPR: BUILD_OPERATOR_STRING ("--");
12030     default:
12031       fatal ("unregistered operator %s - operator_string",
12032              tree_code_name [TREE_CODE (node)]);
12033     }
12034   return NULL;
12035 #undef BUILD_OPERATOR_STRING
12036 }
12037
12038 /* Return 1 if VAR_ACCESS1 is equivalent to VAR_ACCESS2.  */
12039
12040 static int
12041 java_decl_equiv (var_acc1, var_acc2)
12042      tree var_acc1, var_acc2;
12043 {
12044   if (JDECL_P (var_acc1))
12045     return (var_acc1 == var_acc2);
12046   
12047   return (TREE_CODE (var_acc1) == COMPONENT_REF
12048           && TREE_CODE (var_acc2) == COMPONENT_REF
12049           && TREE_OPERAND (TREE_OPERAND (var_acc1, 0), 0)
12050              == TREE_OPERAND (TREE_OPERAND (var_acc2, 0), 0)
12051           && TREE_OPERAND (var_acc1, 1) == TREE_OPERAND (var_acc2, 1));
12052 }
12053
12054 /* Return a non zero value if CODE is one of the operators that can be
12055    used in conjunction with the `=' operator in a compound assignment.  */
12056
12057 static int
12058 binop_compound_p (code)
12059     enum tree_code code;
12060 {
12061   int i;
12062   for (i = 0; i < BINOP_COMPOUND_CANDIDATES; i++)
12063     if (binop_lookup [i] == code)
12064       break;
12065
12066   return i < BINOP_COMPOUND_CANDIDATES;
12067 }
12068
12069 /* Reorganize after a fold to get SAVE_EXPR to generate what we want.  */
12070
12071 static tree
12072 java_refold (t)
12073      tree t;
12074 {
12075   tree c, b, ns, decl;
12076
12077   if (TREE_CODE (t) != MODIFY_EXPR)
12078     return t;
12079
12080   c = TREE_OPERAND (t, 1);
12081   if (! (c && TREE_CODE (c) == COMPOUND_EXPR
12082          && TREE_CODE (TREE_OPERAND (c, 0)) == MODIFY_EXPR
12083          && binop_compound_p (TREE_CODE (TREE_OPERAND (c, 1)))))
12084     return t;
12085
12086   /* Now the left branch of the binary operator. */
12087   b = TREE_OPERAND (TREE_OPERAND (c, 1), 0);
12088   if (! (b && TREE_CODE (b) == NOP_EXPR 
12089          && TREE_CODE (TREE_OPERAND (b, 0)) == SAVE_EXPR))
12090     return t;
12091
12092   ns = TREE_OPERAND (TREE_OPERAND (b, 0), 0);
12093   if (! (ns && TREE_CODE (ns) == NOP_EXPR
12094          && TREE_CODE (TREE_OPERAND (ns, 0)) == SAVE_EXPR))
12095     return t;
12096
12097   decl = TREE_OPERAND (TREE_OPERAND (ns, 0), 0);
12098   if ((JDECL_P (decl) || TREE_CODE (decl) == COMPONENT_REF)
12099       /* It's got to be the an equivalent decl */
12100       && java_decl_equiv (decl, TREE_OPERAND (TREE_OPERAND (c, 0), 0)))
12101     {
12102       /* Shorten the NOP_EXPR/SAVE_EXPR path. */
12103       TREE_OPERAND (TREE_OPERAND (c, 1), 0) = TREE_OPERAND (ns, 0);
12104       /* Substitute the COMPOUND_EXPR by the BINOP_EXPR */
12105       TREE_OPERAND (t, 1) = TREE_OPERAND (c, 1);
12106       /* Change the right part of the BINOP_EXPR */
12107       TREE_OPERAND (TREE_OPERAND (t, 1), 1) = TREE_OPERAND (c, 0);
12108     }
12109
12110   return t;
12111 }
12112
12113 /* Binary operators (15.16 up to 15.18). We return error_mark_node on
12114    errors but we modify NODE so that it contains the type computed
12115    according to the expression, when it's fixed. Otherwise, we write
12116    error_mark_node as the type. It allows us to further the analysis
12117    of remaining nodes and detects more errors in certain cases.  */
12118
12119 static tree
12120 patch_binop (node, wfl_op1, wfl_op2)
12121      tree node;
12122      tree wfl_op1;
12123      tree wfl_op2;
12124 {
12125   tree op1 = TREE_OPERAND (node, 0);
12126   tree op2 = TREE_OPERAND (node, 1);
12127   tree op1_type = TREE_TYPE (op1);
12128   tree op2_type = TREE_TYPE (op2);
12129   tree prom_type = NULL_TREE, cn;
12130   int code = TREE_CODE (node);
12131
12132   /* If 1, tell the routine that we have to return error_mark_node
12133      after checking for the initialization of the RHS */
12134   int error_found = 0;
12135
12136   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
12137
12138   switch (code)
12139     {
12140     /* 15.16 Multiplicative operators */
12141     case MULT_EXPR:             /* 15.16.1 Multiplication Operator * */
12142     case RDIV_EXPR:             /* 15.16.2 Division Operator / */
12143     case TRUNC_DIV_EXPR:        /* 15.16.2 Integral type Division Operator / */
12144     case TRUNC_MOD_EXPR:        /* 15.16.3 Remainder operator % */
12145       if (!JPRIMITIVE_TYPE_P (op1_type) || !JPRIMITIVE_TYPE_P (op2_type))
12146         {
12147           if (!JPRIMITIVE_TYPE_P (op1_type))
12148             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
12149           if (!JPRIMITIVE_TYPE_P (op2_type) && (op1_type != op2_type))
12150             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
12151           TREE_TYPE (node) = error_mark_node;
12152           error_found = 1;
12153           break;
12154         }
12155       prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12156       /* Change the division operator if necessary */
12157       if (code == RDIV_EXPR && TREE_CODE (prom_type) == INTEGER_TYPE)
12158         TREE_SET_CODE (node, TRUNC_DIV_EXPR);
12159
12160       if (TREE_CODE (prom_type) == INTEGER_TYPE
12161           && flag_use_divide_subroutine
12162           && ! flag_emit_class_files
12163           && (code == RDIV_EXPR || code == TRUNC_MOD_EXPR))
12164         return build_java_soft_divmod (TREE_CODE (node), prom_type, op1, op2);
12165  
12166       /* This one is more complicated. FLOATs are processed by a
12167          function call to soft_fmod. Duplicate the value of the
12168          COMPOUND_ASSIGN_P flag. */
12169       if (code == TRUNC_MOD_EXPR)
12170         {
12171           tree mod = build_java_binop (TRUNC_MOD_EXPR, prom_type, op1, op2);
12172           COMPOUND_ASSIGN_P (mod) = COMPOUND_ASSIGN_P (node);
12173           TREE_SIDE_EFFECTS (mod)
12174             = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
12175           return mod;
12176         }
12177       break;
12178
12179     /* 15.17 Additive Operators */
12180     case PLUS_EXPR:             /* 15.17.1 String Concatenation Operator + */
12181
12182       /* Operation is valid if either one argument is a string
12183          constant, a String object or a StringBuffer crafted for the
12184          purpose of the a previous usage of the String concatenation
12185          operator */
12186
12187       if (TREE_CODE (op1) == STRING_CST 
12188           || TREE_CODE (op2) == STRING_CST
12189           || JSTRING_TYPE_P (op1_type)
12190           || JSTRING_TYPE_P (op2_type)
12191           || IS_CRAFTED_STRING_BUFFER_P (op1)
12192           || IS_CRAFTED_STRING_BUFFER_P (op2))
12193         return build_string_concatenation (op1, op2);
12194
12195     case MINUS_EXPR:            /* 15.17.2 Additive Operators (+ and -) for
12196                                    Numeric Types */
12197       if (!JPRIMITIVE_TYPE_P (op1_type) || !JPRIMITIVE_TYPE_P (op2_type))
12198         {
12199           if (!JPRIMITIVE_TYPE_P (op1_type))
12200             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
12201           if (!JPRIMITIVE_TYPE_P (op2_type) && (op1_type != op2_type))
12202             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
12203           TREE_TYPE (node) = error_mark_node;
12204           error_found = 1;
12205           break;
12206         }
12207       prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12208       break;
12209
12210     /* 15.18 Shift Operators */
12211     case LSHIFT_EXPR:
12212     case RSHIFT_EXPR:
12213     case URSHIFT_EXPR:
12214       if (!JINTEGRAL_TYPE_P (op1_type) || !JINTEGRAL_TYPE_P (op2_type))
12215         {
12216           if (!JINTEGRAL_TYPE_P (op1_type))
12217             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
12218           else
12219             {
12220               if (JPRIMITIVE_TYPE_P (op2_type))
12221                 parse_error_context (wfl_operator,
12222                                      "Incompatible type for `%s'. Explicit cast needed to convert shift distance from `%s' to integral",
12223                                      operator_string (node),
12224                                      lang_printable_name (op2_type, 0));
12225               else
12226                 parse_error_context (wfl_operator,
12227                                      "Incompatible type for `%s'. Can't convert shift distance from `%s' to integral", 
12228                                      operator_string (node),
12229                                      lang_printable_name (op2_type, 0));
12230             }
12231           TREE_TYPE (node) = error_mark_node;
12232           error_found = 1;
12233           break;
12234         }
12235
12236       /* Unary numeric promotion (5.6.1) is performed on each operand
12237          separatly */
12238       op1 = do_unary_numeric_promotion (op1);
12239       op2 = do_unary_numeric_promotion (op2);
12240
12241       /* The type of the shift expression is the type of the promoted
12242          type of the left-hand operand */
12243       prom_type = TREE_TYPE (op1);
12244
12245       /* Shift int only up to 0x1f and long up to 0x3f */
12246       if (prom_type == int_type_node)
12247         op2 = fold (build (BIT_AND_EXPR, int_type_node, op2, 
12248                            build_int_2 (0x1f, 0)));
12249       else
12250         op2 = fold (build (BIT_AND_EXPR, int_type_node, op2, 
12251                            build_int_2 (0x3f, 0)));
12252
12253       /* The >>> operator is a >> operating on unsigned quantities */
12254       if (code == URSHIFT_EXPR && ! flag_emit_class_files)
12255         {
12256           tree to_return;
12257           tree utype = unsigned_type (prom_type);
12258           op1 = convert (utype, op1);
12259           TREE_SET_CODE (node, RSHIFT_EXPR);
12260           TREE_OPERAND (node, 0) = op1;
12261           TREE_OPERAND (node, 1) = op2;
12262           TREE_TYPE (node) = utype;
12263           to_return = convert (prom_type, node);
12264           /* Copy the original value of the COMPOUND_ASSIGN_P flag */
12265           COMPOUND_ASSIGN_P (to_return) = COMPOUND_ASSIGN_P (node);
12266           TREE_SIDE_EFFECTS (to_return)
12267             = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
12268           return to_return;
12269         }
12270       break;
12271
12272       /* 15.19.1 Type Comparison Operator instaceof */
12273     case INSTANCEOF_EXPR:
12274
12275       TREE_TYPE (node) = boolean_type_node;
12276
12277       if (!(op2_type = resolve_type_during_patch (op2)))
12278         return error_mark_node;
12279
12280       /* The first operand must be a reference type or the null type */
12281       if (!JREFERENCE_TYPE_P (op1_type) && op1 != null_pointer_node)
12282         error_found = 1;        /* Error reported further below */
12283
12284       /* The second operand must be a reference type */
12285       if (!JREFERENCE_TYPE_P (op2_type))
12286         {
12287           SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
12288           parse_error_context
12289             (wfl_operator, "Invalid argument `%s' for `instanceof'",
12290              lang_printable_name (op2_type, 0));
12291           error_found = 1;
12292         }
12293
12294       if (!error_found && valid_ref_assignconv_cast_p (op1_type, op2_type, 1))
12295         {
12296           /* If the first operand is null, the result is always false */
12297           if (op1 == null_pointer_node)
12298             return boolean_false_node;
12299           else if (flag_emit_class_files)
12300             {
12301               TREE_OPERAND (node, 1) = op2_type;
12302               TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1);
12303               return node;
12304             }
12305           /* Otherwise we have to invoke instance of to figure it out */
12306           else
12307             {
12308               tree call =
12309                 build (CALL_EXPR, boolean_type_node,
12310                        build_address_of (soft_instanceof_node),
12311                        tree_cons 
12312                        (NULL_TREE, op1,
12313                         build_tree_list (NULL_TREE,
12314                                          build_class_ref (op2_type))),
12315                        NULL_TREE);
12316               TREE_SIDE_EFFECTS (call) = TREE_SIDE_EFFECTS (op1);
12317               return call;
12318             }
12319         }
12320       /* There is no way the expression operand can be an instance of
12321          the type operand. This is a compile time error. */
12322       else
12323         {
12324           char *t1 = xstrdup (lang_printable_name (op1_type, 0));
12325           SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
12326           parse_error_context 
12327             (wfl_operator, "Impossible for `%s' to be instance of `%s'",
12328              t1, lang_printable_name (op2_type, 0));
12329           free (t1);
12330           error_found = 1;
12331         }
12332       
12333       break;
12334
12335       /* 15.21 Bitwise and Logical Operators */
12336     case BIT_AND_EXPR:
12337     case BIT_XOR_EXPR:
12338     case BIT_IOR_EXPR:
12339       if (JINTEGRAL_TYPE_P (op1_type) && JINTEGRAL_TYPE_P (op2_type))
12340         /* Binary numeric promotion is performed on both operand and the
12341            expression retain that type */
12342         prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12343
12344       else if (TREE_CODE (op1_type) == BOOLEAN_TYPE 
12345                && TREE_CODE (op1_type) == BOOLEAN_TYPE)
12346         /* The type of the bitwise operator expression is BOOLEAN */
12347         prom_type = boolean_type_node;
12348       else
12349         {
12350           if (!JINTEGRAL_TYPE_P (op1_type))
12351             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
12352           if (!JINTEGRAL_TYPE_P (op2_type) && (op1_type != op2_type))
12353             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op2_type);
12354           TREE_TYPE (node) = error_mark_node;
12355           error_found = 1;
12356           /* Insert a break here if adding thing before the switch's
12357              break for this case */
12358         }
12359       break;
12360
12361       /* 15.22 Conditional-And Operator */
12362     case TRUTH_ANDIF_EXPR:
12363       /* 15.23 Conditional-Or Operator */
12364     case TRUTH_ORIF_EXPR:
12365       /* Operands must be of BOOLEAN type */
12366       if (TREE_CODE (op1_type) != BOOLEAN_TYPE || 
12367           TREE_CODE (op2_type) != BOOLEAN_TYPE)
12368         {
12369           if (TREE_CODE (op1_type) != BOOLEAN_TYPE)
12370             ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op1_type);
12371           if (TREE_CODE (op2_type) != BOOLEAN_TYPE && (op1_type != op2_type))
12372             ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op2_type);
12373           TREE_TYPE (node) = boolean_type_node;
12374           error_found = 1;
12375           break;
12376         }
12377       /* The type of the conditional operators is BOOLEAN */
12378       prom_type = boolean_type_node;
12379       break;
12380
12381       /* 15.19.1 Numerical Comparison Operators <, <=, >, >= */
12382     case LT_EXPR:
12383     case GT_EXPR:
12384     case LE_EXPR:
12385     case GE_EXPR:
12386       /* The type of each of the operands must be a primitive numeric
12387          type */
12388       if (!JNUMERIC_TYPE_P (op1_type) || ! JNUMERIC_TYPE_P (op2_type))
12389         {
12390           if (!JNUMERIC_TYPE_P (op1_type))
12391             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
12392           if (!JNUMERIC_TYPE_P (op2_type) && (op1_type != op2_type))
12393             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
12394           TREE_TYPE (node) = boolean_type_node;
12395           error_found = 1;
12396           break;
12397         }
12398       /* Binary numeric promotion is performed on the operands */
12399       binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12400       /* The type of the relation expression is always BOOLEAN */
12401       prom_type = boolean_type_node;
12402       break;
12403
12404       /* 15.20 Equality Operator */
12405     case EQ_EXPR:
12406     case NE_EXPR:
12407       /* It's time for us to patch the strings. */
12408       if ((cn = patch_string (op1))) 
12409        {
12410          op1 = cn;
12411          op1_type = TREE_TYPE (op1);
12412        }
12413       if ((cn = patch_string (op2))) 
12414        {
12415          op2 = cn;
12416          op2_type = TREE_TYPE (op2);
12417        }
12418       
12419       /* 15.20.1 Numerical Equality Operators == and != */
12420       /* Binary numeric promotion is performed on the operands */
12421       if (JNUMERIC_TYPE_P (op1_type) && JNUMERIC_TYPE_P (op2_type))
12422         binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12423       
12424       /* 15.20.2 Boolean Equality Operators == and != */
12425       else if (TREE_CODE (op1_type) == BOOLEAN_TYPE &&
12426           TREE_CODE (op2_type) == BOOLEAN_TYPE)
12427         ;                       /* Nothing to do here */
12428       
12429       /* 15.20.3 Reference Equality Operators == and != */
12430       /* Types have to be either references or the null type. If
12431          they're references, it must be possible to convert either
12432          type to the other by casting conversion. */
12433       else if (op1 == null_pointer_node || op2 == null_pointer_node 
12434                || (JREFERENCE_TYPE_P (op1_type) && JREFERENCE_TYPE_P (op2_type)
12435                    && (valid_ref_assignconv_cast_p (op1_type, op2_type, 1)
12436                        || valid_ref_assignconv_cast_p (op2_type, 
12437                                                        op1_type, 1))))
12438         ;                       /* Nothing to do here */
12439           
12440       /* Else we have an error figure what can't be converted into
12441          what and report the error */
12442       else
12443         {
12444           char *t1;
12445           t1 = xstrdup (lang_printable_name (op1_type, 0));
12446           parse_error_context 
12447             (wfl_operator,
12448              "Incompatible type for `%s'. Can't convert `%s' to `%s'",
12449              operator_string (node), t1, 
12450              lang_printable_name (op2_type, 0));
12451           free (t1);
12452           TREE_TYPE (node) = boolean_type_node;
12453           error_found = 1;
12454           break;
12455         }
12456       prom_type = boolean_type_node;
12457       break;
12458     }
12459
12460   if (error_found)
12461     return error_mark_node;
12462
12463   TREE_OPERAND (node, 0) = op1;
12464   TREE_OPERAND (node, 1) = op2;
12465   TREE_TYPE (node) = prom_type;
12466   TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
12467   
12468   if (flag_emit_xref)
12469     return node;
12470
12471   /* fold does not respect side-effect order as required for Java but not C.
12472    * Also, it sometimes create SAVE_EXPRs which are bad when emitting
12473    * bytecode.
12474    */
12475   if (flag_emit_class_files ? (TREE_CONSTANT (op1) && TREE_CONSTANT (op2))
12476       : ! TREE_SIDE_EFFECTS (node))
12477     node = fold (node);
12478   return node;
12479 }
12480
12481 /* Concatenate the STRING_CST CSTE and STRING. When AFTER is a non
12482    zero value, the value of CSTE comes after the valude of STRING */
12483
12484 static tree
12485 do_merge_string_cste (cste, string, string_len, after)
12486      tree cste;
12487      const char *string;
12488      int string_len, after;
12489 {
12490   int len = TREE_STRING_LENGTH (cste) + string_len;
12491   const char *old = TREE_STRING_POINTER (cste);
12492   TREE_STRING_LENGTH (cste) = len;
12493   TREE_STRING_POINTER (cste) = obstack_alloc (expression_obstack, len+1);
12494   if (after)
12495     {
12496       strcpy (TREE_STRING_POINTER (cste), string);
12497       strcat (TREE_STRING_POINTER (cste), old);
12498     }
12499   else
12500     {
12501       strcpy (TREE_STRING_POINTER (cste), old);
12502       strcat (TREE_STRING_POINTER (cste), string);
12503     }
12504   return cste;
12505 }
12506
12507 /* Tries to merge OP1 (a STRING_CST) and OP2 (if suitable). Return a
12508    new STRING_CST on success, NULL_TREE on failure */
12509
12510 static tree
12511 merge_string_cste (op1, op2, after)
12512      tree op1, op2;
12513      int after;
12514 {
12515   /* Handle two string constants right away */
12516   if (TREE_CODE (op2) == STRING_CST)
12517     return do_merge_string_cste (op1, TREE_STRING_POINTER (op2), 
12518                                  TREE_STRING_LENGTH (op2), after);
12519   
12520   /* Reasonable integer constant can be treated right away */
12521   if (TREE_CODE (op2) == INTEGER_CST && !TREE_CONSTANT_OVERFLOW (op2))
12522     {
12523       static const char *boolean_true = "true";
12524       static const char *boolean_false = "false";
12525       static const char *null_pointer = "null";
12526       char ch[3];
12527       const char *string;
12528       
12529       if (op2 == boolean_true_node)
12530         string = boolean_true;
12531       else if (op2 == boolean_false_node)
12532         string = boolean_false;
12533       else if (op2 == null_pointer_node)
12534         string = null_pointer;
12535       else if (TREE_TYPE (op2) == char_type_node)
12536         {
12537           ch[0] = (char )TREE_INT_CST_LOW (op2);
12538           ch[1] = '\0';
12539           string = ch;
12540         }
12541       else
12542           string = print_int_node (op2);
12543       
12544       return do_merge_string_cste (op1, string, strlen (string), after);
12545     }
12546   return NULL_TREE;
12547 }
12548
12549 /* Tries to statically concatenate OP1 and OP2 if possible. Either one
12550    has to be a STRING_CST and the other part must be a STRING_CST or a
12551    INTEGRAL constant. Return a new STRING_CST if the operation
12552    succeed, NULL_TREE otherwise.
12553
12554    If the case we want to optimize for space, we might want to return
12555    NULL_TREE for each invocation of this routine. FIXME */
12556
12557 static tree
12558 string_constant_concatenation (op1, op2)
12559      tree op1, op2;
12560 {
12561   if (TREE_CODE (op1) == STRING_CST || (TREE_CODE (op2) == STRING_CST))
12562     {
12563       tree string, rest;
12564       int invert;
12565       
12566       string = (TREE_CODE (op1) == STRING_CST ? op1 : op2);
12567       rest   = (string == op1 ? op2 : op1);
12568       invert = (string == op1 ? 0 : 1 );
12569       
12570       /* Walk REST, only if it looks reasonable */
12571       if (TREE_CODE (rest) != STRING_CST
12572           && !IS_CRAFTED_STRING_BUFFER_P (rest)
12573           && !JSTRING_TYPE_P (TREE_TYPE (rest))
12574           && TREE_CODE (rest) == EXPR_WITH_FILE_LOCATION)
12575         {
12576           rest = java_complete_tree (rest);
12577           if (rest == error_mark_node)
12578             return error_mark_node;
12579           rest = fold (rest);
12580         }
12581       return merge_string_cste (string, rest, invert);
12582     }
12583   return NULL_TREE;
12584 }
12585
12586 /* Implement the `+' operator. Does static optimization if possible,
12587    otherwise create (if necessary) and append elements to a
12588    StringBuffer. The StringBuffer will be carried around until it is
12589    used for a function call or an assignment. Then toString() will be
12590    called on it to turn it into a String object. */
12591
12592 static tree
12593 build_string_concatenation (op1, op2)
12594      tree op1, op2;
12595 {
12596   tree result;
12597   int side_effects = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
12598
12599   if (flag_emit_xref)
12600     return build (PLUS_EXPR, string_type_node, op1, op2);
12601   
12602   /* Try to do some static optimization */
12603   if ((result = string_constant_concatenation (op1, op2)))
12604     return result;
12605
12606   /* Discard empty strings on either side of the expression */
12607   if (TREE_CODE (op1) == STRING_CST && TREE_STRING_LENGTH (op1) == 0)
12608     {
12609       op1 = op2;
12610       op2 = NULL_TREE;
12611     }
12612   else if (TREE_CODE (op2) == STRING_CST && TREE_STRING_LENGTH (op2) == 0)
12613     op2 = NULL_TREE;
12614
12615   /* If operands are string constant, turn then into object references */
12616   if (TREE_CODE (op1) == STRING_CST)
12617     op1 = patch_string_cst (op1);
12618   if (op2 && TREE_CODE (op2) == STRING_CST)
12619     op2 = patch_string_cst (op2);
12620
12621   /* If either one of the constant is null and the other non null
12622      operand is a String object, return it. */
12623   if (JSTRING_TYPE_P (TREE_TYPE (op1)) && !op2)
12624     return op1;
12625
12626   /* If OP1 isn't already a StringBuffer, create and
12627      initialize a new one */
12628   if (!IS_CRAFTED_STRING_BUFFER_P (op1))
12629     {
12630       /* Two solutions here: 
12631          1) OP1 is a constant string reference, we call new StringBuffer(OP1)
12632          2) OP1 is something else, we call new StringBuffer().append(OP1).  */
12633       if (TREE_CONSTANT (op1) && JSTRING_TYPE_P (TREE_TYPE (op1)))
12634         op1 = BUILD_STRING_BUFFER (op1);
12635       else
12636         {
12637           tree aNew = BUILD_STRING_BUFFER (NULL_TREE);
12638           op1 = make_qualified_primary (aNew, BUILD_APPEND (op1), 0);
12639         }
12640     }
12641
12642   if (op2)
12643     {
12644       /* OP1 is no longer the last node holding a crafted StringBuffer */
12645       IS_CRAFTED_STRING_BUFFER_P (op1) = 0;
12646       /* Create a node for `{new...,xxx}.append (op2)' */
12647       if (op2)
12648         op1 = make_qualified_primary (op1, BUILD_APPEND (op2), 0);
12649     }
12650
12651   /* Mark the last node holding a crafted StringBuffer */
12652   IS_CRAFTED_STRING_BUFFER_P (op1) = 1;
12653
12654   TREE_SIDE_EFFECTS (op1) = side_effects;
12655   return op1;
12656 }
12657
12658 /* Patch the string node NODE. NODE can be a STRING_CST of a crafted
12659    StringBuffer. If no string were found to be patched, return
12660    NULL. */
12661
12662 static tree
12663 patch_string (node)
12664     tree node;
12665 {
12666   if (node == error_mark_node)
12667     return error_mark_node;
12668   if (TREE_CODE (node) == STRING_CST)
12669     return patch_string_cst (node);
12670   else if (IS_CRAFTED_STRING_BUFFER_P (node))
12671     {
12672       int saved = ctxp->explicit_constructor_p;
12673       tree invoke = build_method_invocation (wfl_to_string, NULL_TREE);
12674       tree ret;
12675       /* Temporary disable forbid the use of `this'. */
12676       ctxp->explicit_constructor_p = 0;
12677       ret = java_complete_tree (make_qualified_primary (node, invoke, 0));
12678       /* String concatenation arguments must be evaluated in order too. */
12679       ret = force_evaluation_order (ret);
12680       /* Restore it at its previous value */
12681       ctxp->explicit_constructor_p = saved;
12682       return ret;
12683     }
12684   return NULL_TREE;
12685 }
12686
12687 /* Build the internal representation of a string constant.  */
12688
12689 static tree
12690 patch_string_cst (node)
12691      tree node;
12692 {
12693   int location;
12694   if (! flag_emit_class_files)
12695     {
12696       push_obstacks (&permanent_obstack, &permanent_obstack);
12697       node = get_identifier (TREE_STRING_POINTER (node));
12698       location = alloc_name_constant (CONSTANT_String, node);
12699       node = build_ref_from_constant_pool (location);
12700       pop_obstacks ();
12701     }
12702   TREE_TYPE (node) = string_ptr_type_node;
12703   TREE_CONSTANT (node) = 1;
12704   return node;
12705 }
12706
12707 /* Build an incomplete unary operator expression. */
12708
12709 static tree
12710 build_unaryop (op_token, op_location, op1)
12711      int op_token, op_location;
12712      tree op1;
12713 {
12714   enum tree_code op;
12715   tree unaryop;
12716   switch (op_token)
12717     {
12718     case PLUS_TK: op = UNARY_PLUS_EXPR; break;
12719     case MINUS_TK: op = NEGATE_EXPR; break;
12720     case NEG_TK: op = TRUTH_NOT_EXPR; break;
12721     case NOT_TK: op = BIT_NOT_EXPR; break;
12722     default: fatal ("Unknown token `%d' for unary operator - build_unaryop",
12723                     op_token);
12724     }
12725
12726   unaryop = build1 (op, NULL_TREE, op1);
12727   TREE_SIDE_EFFECTS (unaryop) = 1;
12728   /* Store the location of the operator, for better error report. The
12729      string of the operator will be rebuild based on the OP value. */
12730   EXPR_WFL_LINECOL (unaryop) = op_location;
12731   return unaryop;
12732 }
12733
12734 /* Special case for the ++/-- operators, since they require an extra
12735    argument to build, which is set to NULL and patched
12736    later. IS_POST_P is 1 if the operator, 0 otherwise.  */
12737
12738 static tree
12739 build_incdec (op_token, op_location, op1, is_post_p)
12740      int op_token, op_location;
12741      tree op1;
12742      int is_post_p;
12743 {
12744   static enum tree_code lookup [2][2] = 
12745     {
12746       { PREDECREMENT_EXPR, PREINCREMENT_EXPR, },
12747       { POSTDECREMENT_EXPR, POSTINCREMENT_EXPR, },
12748     };
12749   tree node = build (lookup [is_post_p][(op_token - DECR_TK)], 
12750                      NULL_TREE, op1, NULL_TREE);
12751   TREE_SIDE_EFFECTS (node) = 1;
12752   /* Store the location of the operator, for better error report. The
12753      string of the operator will be rebuild based on the OP value. */
12754   EXPR_WFL_LINECOL (node) = op_location;
12755   return node;
12756 }     
12757
12758 /* Build an incomplete cast operator, based on the use of the
12759    CONVERT_EXPR. Note that TREE_TYPE of the constructed node is
12760    set. java_complete_tree is trained to walk a CONVERT_EXPR even
12761    though its type is already set.  */
12762
12763 static tree
12764 build_cast (location, type, exp)
12765      int location;
12766      tree type, exp;
12767 {
12768   tree node = build1 (CONVERT_EXPR, type, exp);
12769   EXPR_WFL_LINECOL (node) = location;
12770   return node;
12771 }
12772
12773 /* Build an incomplete class reference operator.  */
12774 static tree
12775 build_incomplete_class_ref (location, class_name)
12776     int location;
12777     tree class_name;
12778 {
12779   tree node = build1 (CLASS_LITERAL, NULL_TREE, class_name);
12780   EXPR_WFL_LINECOL (node) = location;
12781   return node;
12782 }
12783
12784 /* Complete an incomplete class reference operator.  */
12785 static tree
12786 patch_incomplete_class_ref (node)
12787     tree node;
12788 {
12789   tree type = TREE_OPERAND (node, 0);
12790   tree ref_type;
12791
12792   if (!(ref_type = resolve_type_during_patch (type)))
12793     return error_mark_node;
12794
12795   if (!flag_emit_class_files || JPRIMITIVE_TYPE_P (ref_type))
12796     return build_class_ref (ref_type);
12797
12798   /* If we're emitting class files and we have to deal with non
12799      primitive types, we invoke (and consider generating) the
12800      synthetic static method `class$'. */
12801   if (!TYPE_DOT_CLASS (current_class))
12802       build_dot_class_method (current_class);
12803   ref_type = 
12804     build_dot_class_method_invocation (DECL_NAME (TYPE_NAME (ref_type)));
12805   return java_complete_tree (ref_type);
12806 }
12807
12808 /* 15.14 Unary operators. We return error_mark_node in case of error,
12809    but preserve the type of NODE if the type is fixed.  */
12810
12811 static tree
12812 patch_unaryop (node, wfl_op)
12813      tree node;
12814      tree wfl_op;
12815 {
12816   tree op = TREE_OPERAND (node, 0);
12817   tree op_type = TREE_TYPE (op);
12818   tree prom_type = NULL_TREE, value, decl;
12819   int outer_field_flag = 0;
12820   int code = TREE_CODE (node);
12821   int error_found = 0;
12822
12823   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
12824
12825   switch (code)
12826     {
12827       /* 15.13.2 Postfix Increment Operator ++ */
12828     case POSTINCREMENT_EXPR:
12829       /* 15.13.3 Postfix Increment Operator -- */
12830     case POSTDECREMENT_EXPR:
12831       /* 15.14.1 Prefix Increment Operator ++ */
12832     case PREINCREMENT_EXPR:
12833       /* 15.14.2 Prefix Decrement Operator -- */
12834     case PREDECREMENT_EXPR:
12835       op = decl = strip_out_static_field_access_decl (op);
12836       outer_field_flag = outer_field_expanded_access_p (op, NULL, NULL, NULL);
12837       /* We might be trying to change an outer field accessed using
12838          access method. */
12839       if (outer_field_flag)
12840         {
12841           /* Retrieve the decl of the field we're trying to access. We
12842              do that by first retrieving the function we would call to
12843              access the field. It has been already verified that this
12844              field isn't final */
12845           if (flag_emit_class_files)
12846             decl = TREE_OPERAND (op, 0);
12847           else
12848             decl = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (op, 0), 0), 0);
12849           decl = DECL_FUNCTION_ACCESS_DECL (decl);
12850         }
12851       /* We really should have a JAVA_ARRAY_EXPR to avoid this */
12852       else if (!JDECL_P (decl) 
12853           && TREE_CODE (decl) != COMPONENT_REF
12854           && !(flag_emit_class_files && TREE_CODE (decl) == ARRAY_REF)
12855           && TREE_CODE (decl) != INDIRECT_REF
12856           && !(TREE_CODE (decl) == COMPOUND_EXPR
12857                && TREE_OPERAND (decl, 1)
12858                && (TREE_CODE (TREE_OPERAND (decl, 1)) == INDIRECT_REF)))
12859         {
12860           tree lvalue;
12861           /* Before screaming, check that we're not in fact trying to
12862              increment a optimized static final access, in which case
12863              we issue an different error message. */
12864           if (!(TREE_CODE (wfl_op) == EXPR_WITH_FILE_LOCATION
12865                 && resolve_expression_name (wfl_op, &lvalue)
12866                 && check_final_assignment (lvalue, wfl_op)))
12867             parse_error_context (wfl_operator, "Invalid argument to `%s'",
12868                                  operator_string (node));
12869           TREE_TYPE (node) = error_mark_node;
12870           error_found = 1;
12871         }
12872       
12873       if (check_final_assignment (op, wfl_op))
12874         error_found = 1;
12875
12876       /* From now on, we know that op if a variable and that it has a
12877          valid wfl. We use wfl_op to locate errors related to the
12878          ++/-- operand. */
12879       else if (!JNUMERIC_TYPE_P (op_type))
12880         {
12881           parse_error_context
12882             (wfl_op, "Invalid argument type `%s' to `%s'",
12883              lang_printable_name (op_type, 0), operator_string (node));
12884           TREE_TYPE (node) = error_mark_node;
12885           error_found = 1;
12886         }
12887       else
12888         {
12889           /* Before the addition, binary numeric promotion is performed on
12890              both operands, if really necessary */
12891           if (JINTEGRAL_TYPE_P (op_type))
12892             {
12893               value = build_int_2 (1, 0);
12894               TREE_TYPE (value) = TREE_TYPE (node) = op_type;
12895             }
12896           else
12897             {
12898               value = build_int_2 (1, 0);
12899               TREE_TYPE (node) = 
12900                 binary_numeric_promotion (op_type, 
12901                                           TREE_TYPE (value), &op, &value);
12902             }
12903
12904           /* We remember we might be accessing an outer field */
12905           if (outer_field_flag)
12906             {
12907               /* We re-generate an access to the field */
12908               value = build (PLUS_EXPR, TREE_TYPE (op), 
12909                              build_outer_field_access (wfl_op, decl), value);
12910                                                     
12911               /* And we patch the original access$() into a write 
12912                  with plus_op as a rhs */
12913               return outer_field_access_fix (node, op, value);
12914             }
12915
12916           /* And write back into the node. */
12917           TREE_OPERAND (node, 0) = op;
12918           TREE_OPERAND (node, 1) = value;
12919           /* Convert the overall back into its original type, if
12920              necessary, and return */
12921           if (JINTEGRAL_TYPE_P (op_type))
12922             return fold (node);
12923           else
12924             return fold (convert (op_type, node));
12925         }
12926       break;
12927
12928       /* 15.14.3 Unary Plus Operator + */
12929     case UNARY_PLUS_EXPR:
12930       /* 15.14.4 Unary Minus Operator - */
12931     case NEGATE_EXPR:
12932       if (!JNUMERIC_TYPE_P (op_type))
12933         {
12934           ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op_type);
12935           TREE_TYPE (node) = error_mark_node;
12936           error_found = 1;
12937         }
12938       /* Unary numeric promotion is performed on operand */
12939       else
12940         {
12941           op = do_unary_numeric_promotion (op);
12942           prom_type = TREE_TYPE (op);
12943           if (code == UNARY_PLUS_EXPR)
12944             return fold (op);
12945         }
12946       break;
12947
12948       /* 15.14.5 Bitwise Complement Operator ~ */
12949     case BIT_NOT_EXPR:
12950       if (!JINTEGRAL_TYPE_P (op_type))
12951         {
12952           ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op_type);
12953           TREE_TYPE (node) = error_mark_node;
12954           error_found = 1;
12955         }
12956       else
12957         {
12958           op = do_unary_numeric_promotion (op);
12959           prom_type = TREE_TYPE (op);
12960         }
12961       break;
12962
12963       /* 15.14.6 Logical Complement Operator ! */
12964     case TRUTH_NOT_EXPR:
12965       if (TREE_CODE (op_type) != BOOLEAN_TYPE)
12966         {
12967           ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op_type);
12968           /* But the type is known. We will report an error if further
12969              attempt of a assignment is made with this rhs */
12970           TREE_TYPE (node) = boolean_type_node;
12971           error_found = 1;
12972         }
12973       else
12974         prom_type = boolean_type_node;
12975       break;
12976
12977       /* 15.15 Cast Expression */
12978     case CONVERT_EXPR:
12979       value = patch_cast (node, wfl_operator);
12980       if (value == error_mark_node)
12981         {
12982           /* If this cast is part of an assignment, we tell the code
12983              that deals with it not to complain about a mismatch,
12984              because things have been cast, anyways */
12985           TREE_TYPE (node) = error_mark_node;
12986           error_found = 1;
12987         }
12988       else
12989         {
12990           value = fold (value);
12991           TREE_SIDE_EFFECTS (value) = TREE_SIDE_EFFECTS (op);
12992           return value;
12993         }
12994       break;
12995     }
12996   
12997   if (error_found)
12998     return error_mark_node;
12999
13000   /* There are cases where node has been replaced by something else
13001      and we don't end up returning here: UNARY_PLUS_EXPR,
13002      CONVERT_EXPR, {POST,PRE}{INCR,DECR}EMENT_EXPR. */
13003   TREE_OPERAND (node, 0) = fold (op);
13004   TREE_TYPE (node) = prom_type;
13005   TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op);
13006   return fold (node);
13007 }
13008
13009 /* Generic type resolution that sometimes takes place during node
13010    patching. Returned the resolved type or generate an error
13011    message. Return the resolved type or NULL_TREE.  */
13012
13013 static tree
13014 resolve_type_during_patch (type)
13015      tree type;
13016 {
13017   if (unresolved_type_p (type, NULL))
13018     {
13019       tree type_decl = resolve_no_layout (EXPR_WFL_NODE (type), NULL_TREE);
13020       if (!type_decl)
13021         {
13022           parse_error_context (type, 
13023                                "Class `%s' not found in type declaration",
13024                                IDENTIFIER_POINTER (EXPR_WFL_NODE (type)));
13025           return NULL_TREE;
13026         }
13027       else
13028         {
13029           CLASS_LOADED_P (TREE_TYPE (type_decl)) = 1;
13030           return TREE_TYPE (type_decl);
13031         }
13032     }
13033   return type;
13034 }
13035 /* 5.5 Casting Conversion. error_mark_node is returned if an error is
13036    found. Otherwise NODE or something meant to replace it is returned.  */
13037
13038 static tree
13039 patch_cast (node, wfl_operator)
13040      tree node;
13041      tree wfl_operator;
13042 {
13043   tree op = TREE_OPERAND (node, 0);
13044   tree op_type = TREE_TYPE (op);
13045   tree cast_type = TREE_TYPE (node);
13046   char *t1;
13047
13048   /* First resolve OP_TYPE if unresolved */
13049   if (!(cast_type = resolve_type_during_patch (cast_type)))
13050     return error_mark_node;
13051
13052   /* Check on cast that are proven correct at compile time */
13053   if (JNUMERIC_TYPE_P (cast_type) && JNUMERIC_TYPE_P (op_type))
13054     {
13055       /* Same type */
13056       if (cast_type == op_type)
13057         return node;
13058
13059       /* float and double type are converted to the original type main
13060          variant and then to the target type. */
13061       if (JFLOAT_TYPE_P (op_type) && TREE_CODE (cast_type) == CHAR_TYPE)
13062         op = convert (integer_type_node, op);
13063
13064       /* Try widening/narowwing convertion. Potentially, things need
13065          to be worked out in gcc so we implement the extreme cases
13066          correctly. fold_convert() needs to be fixed. */
13067       return convert (cast_type, op);
13068     }
13069
13070   /* It's also valid to cast a boolean into a boolean */
13071   if (op_type == boolean_type_node && cast_type == boolean_type_node)
13072     return node;
13073
13074   /* null can be casted to references */
13075   if (op == null_pointer_node && JREFERENCE_TYPE_P (cast_type))
13076     return build_null_of_type (cast_type);
13077
13078   /* The remaining legal casts involve conversion between reference
13079      types. Check for their compile time correctness. */
13080   if (JREFERENCE_TYPE_P (op_type) && JREFERENCE_TYPE_P (cast_type) 
13081       && valid_ref_assignconv_cast_p (op_type, cast_type, 1))
13082     {
13083       TREE_TYPE (node) = promote_type (cast_type);
13084       /* Now, the case can be determined correct at compile time if
13085          OP_TYPE can be converted into CAST_TYPE by assignment
13086          conversion (5.2) */
13087
13088       if (valid_ref_assignconv_cast_p (op_type, cast_type, 0))
13089         {
13090           TREE_SET_CODE (node, NOP_EXPR);
13091           return node;
13092         }
13093
13094       if (flag_emit_class_files)
13095         {
13096           TREE_SET_CODE (node, CONVERT_EXPR);
13097           return node;
13098         }
13099
13100       /* The cast requires a run-time check */
13101       return build (CALL_EXPR, promote_type (cast_type),
13102                     build_address_of (soft_checkcast_node),
13103                     tree_cons (NULL_TREE, build_class_ref (cast_type),
13104                                build_tree_list (NULL_TREE, op)),
13105                     NULL_TREE);
13106     }
13107
13108   /* Any other casts are proven incorrect at compile time */
13109   t1 = xstrdup (lang_printable_name (op_type, 0));
13110   parse_error_context (wfl_operator, "Invalid cast from `%s' to `%s'",
13111                        t1, lang_printable_name (cast_type, 0));
13112   free (t1);
13113   return error_mark_node;
13114 }
13115
13116 /* Build a null constant and give it the type TYPE.  */
13117
13118 static tree
13119 build_null_of_type (type)
13120      tree type;
13121 {
13122   tree node = build_int_2 (0, 0);
13123   TREE_TYPE (node) = promote_type (type);
13124   return node;
13125 }
13126
13127 /* Build an ARRAY_REF incomplete tree node. Note that operand 1 isn't
13128    a list of indices. */
13129 static tree
13130 build_array_ref (location, array, index)
13131      int location;
13132      tree array, index;
13133 {
13134   tree node = build (ARRAY_REF, NULL_TREE, array, index);
13135   EXPR_WFL_LINECOL (node) = location;
13136   return node;
13137 }
13138
13139 /* 15.12 Array Access Expression */
13140
13141 static tree
13142 patch_array_ref (node)
13143      tree node;
13144 {
13145   tree array = TREE_OPERAND (node, 0);
13146   tree array_type  = TREE_TYPE (array);
13147   tree index = TREE_OPERAND (node, 1);
13148   tree index_type = TREE_TYPE (index);
13149   int error_found = 0;
13150
13151   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13152
13153   if (TREE_CODE (array_type) == POINTER_TYPE)
13154     array_type = TREE_TYPE (array_type);
13155
13156   /* The array reference must be an array */
13157   if (!TYPE_ARRAY_P (array_type))
13158     {
13159       parse_error_context 
13160         (wfl_operator,
13161          "`[]' can only be applied to arrays. It can't be applied to `%s'",
13162          lang_printable_name (array_type, 0));
13163       TREE_TYPE (node) = error_mark_node;
13164       error_found = 1;
13165     }
13166
13167   /* The array index undergoes unary numeric promotion. The promoted
13168      type must be int */
13169   index = do_unary_numeric_promotion (index);
13170   if (TREE_TYPE (index) != int_type_node)
13171     {
13172       if (valid_cast_to_p (index_type, int_type_node))
13173         parse_error_context (wfl_operator,
13174    "Incompatible type for `[]'. Explicit cast needed to convert `%s' to `int'",
13175                              lang_printable_name (index_type, 0));
13176       else
13177         parse_error_context (wfl_operator,
13178           "Incompatible type for `[]'. Can't convert `%s' to `int'",
13179                              lang_printable_name (index_type, 0));
13180       TREE_TYPE (node) = error_mark_node;
13181       error_found = 1;
13182     }
13183
13184   if (error_found)
13185     return error_mark_node;
13186
13187   array_type = TYPE_ARRAY_ELEMENT (array_type);
13188
13189   if (flag_emit_class_files || flag_emit_xref)
13190     {
13191       TREE_OPERAND (node, 0) = array;
13192       TREE_OPERAND (node, 1) = index;
13193     }
13194   else
13195     {
13196       /* The save_expr is for correct evaluation order.  It would be cleaner
13197          to use force_evaluation_order (see comment there), but that is
13198          difficult when we also have to deal with bounds checking. */
13199       if (TREE_SIDE_EFFECTS (index))
13200         array = save_expr (array);
13201       node = build_java_arrayaccess (array, array_type, index);
13202       if (TREE_SIDE_EFFECTS (index))
13203         node = build (COMPOUND_EXPR, array_type, array, node);
13204     }
13205   TREE_TYPE (node) = array_type;
13206   return node;
13207 }
13208
13209 /* 15.9 Array Creation Expressions */
13210
13211 static tree
13212 build_newarray_node (type, dims, extra_dims)
13213      tree type;
13214      tree dims;
13215      int extra_dims;
13216 {
13217   tree node =
13218     build (NEW_ARRAY_EXPR, NULL_TREE, type, nreverse (dims), 
13219            build_int_2 (extra_dims, 0));
13220   return node;
13221 }
13222
13223 static tree
13224 patch_newarray (node)
13225      tree node;
13226 {
13227   tree type = TREE_OPERAND (node, 0);
13228   tree dims = TREE_OPERAND (node, 1);
13229   tree cdim, array_type;
13230   int error_found = 0;
13231   int ndims = 0;
13232   int xdims = TREE_INT_CST_LOW (TREE_OPERAND (node, 2));
13233
13234   /* Dimension types are verified. It's better for the types to be
13235      verified in order. */
13236   for (cdim = dims, ndims = 0; cdim; cdim = TREE_CHAIN (cdim), ndims++ )
13237     {
13238       int dim_error = 0;
13239       tree dim = TREE_VALUE (cdim);
13240
13241       /* Dim might have been saved during its evaluation */
13242       dim = (TREE_CODE (dim) == SAVE_EXPR ? dim = TREE_OPERAND (dim, 0) : dim);
13243
13244       /* The type of each specified dimension must be an integral type. */
13245       if (!JINTEGRAL_TYPE_P (TREE_TYPE (dim)))
13246         dim_error = 1;
13247
13248       /* Each expression undergoes an unary numeric promotion (5.6.1) and the
13249          promoted type must be int. */
13250       else
13251         {
13252           dim = do_unary_numeric_promotion (dim);
13253           if (TREE_TYPE (dim) != int_type_node)
13254             dim_error = 1;
13255         }
13256
13257       /* Report errors on types here */
13258       if (dim_error)
13259         {
13260           parse_error_context 
13261             (TREE_PURPOSE (cdim), 
13262              "Incompatible type for dimension in array creation expression. %s convert `%s' to `int'", 
13263              (valid_cast_to_p (TREE_TYPE (dim), int_type_node) ?
13264               "Explicit cast needed to" : "Can't"),
13265              lang_printable_name (TREE_TYPE (dim), 0));
13266           error_found = 1;
13267         }
13268
13269       TREE_PURPOSE (cdim) = NULL_TREE;
13270     }
13271
13272   /* Resolve array base type if unresolved */
13273   if (!(type = resolve_type_during_patch (type)))
13274     error_found = 1;
13275
13276   if (error_found)
13277     {
13278       /* We don't want further evaluation of this bogus array creation
13279          operation */
13280       TREE_TYPE (node) = error_mark_node;
13281       return error_mark_node;
13282     }
13283
13284   /* Set array_type to the actual (promoted) array type of the result. */
13285   if (TREE_CODE (type) == RECORD_TYPE)
13286     type = build_pointer_type (type);
13287   while (--xdims >= 0)
13288     {
13289       type = promote_type (build_java_array_type (type, -1));
13290     }
13291   dims = nreverse (dims);
13292   array_type = type;
13293   for (cdim = dims; cdim; cdim = TREE_CHAIN (cdim))
13294     {
13295       type = array_type;
13296       array_type
13297         = build_java_array_type (type,
13298                                  TREE_CODE (cdim) == INTEGER_CST
13299                                  ? (HOST_WIDE_INT) TREE_INT_CST_LOW (cdim)
13300                                  : -1);
13301       array_type = promote_type (array_type);
13302     }
13303   dims = nreverse (dims);
13304
13305   /* The node is transformed into a function call. Things are done
13306      differently according to the number of dimensions. If the number
13307      of dimension is equal to 1, then the nature of the base type
13308      (primitive or not) matters. */
13309   if (ndims == 1)
13310     return build_new_array (type, TREE_VALUE (dims));
13311   
13312   /* Can't reuse what's already written in expr.c because it uses the
13313      JVM stack representation. Provide a build_multianewarray. FIXME */
13314   return build (CALL_EXPR, array_type,
13315                 build_address_of (soft_multianewarray_node),
13316                 tree_cons (NULL_TREE, build_class_ref (TREE_TYPE (array_type)),
13317                            tree_cons (NULL_TREE, 
13318                                       build_int_2 (ndims, 0), dims )),
13319                 NULL_TREE);
13320 }
13321
13322 /* 10.6 Array initializer.  */
13323
13324 /* Build a wfl for array element that don't have one, so we can
13325    pin-point errors.  */
13326
13327 static tree
13328 maybe_build_array_element_wfl (node)
13329      tree node;
13330 {
13331   if (TREE_CODE (node) != EXPR_WITH_FILE_LOCATION)
13332     return build_expr_wfl (NULL_TREE, ctxp->filename,
13333                            ctxp->elc.line, ctxp->elc.prev_col);
13334   else
13335     return NULL_TREE;
13336 }
13337
13338 /* Build a NEW_ARRAY_INIT that features a CONSTRUCTOR node. This makes
13339    identification of initialized arrays easier to detect during walk
13340    and expansion.  */
13341
13342 static tree
13343 build_new_array_init (location, values)
13344      int location;
13345      tree values;
13346 {
13347   tree constructor = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, values);
13348   tree to_return = build1 (NEW_ARRAY_INIT, NULL_TREE, constructor);
13349   EXPR_WFL_LINECOL (to_return) = location;
13350   return to_return;
13351 }
13352
13353 /* Expand a NEW_ARRAY_INIT node. Return error_mark_node if an error
13354    occurred.  Otherwise return NODE after having set its type
13355    appropriately.  */
13356
13357 static tree
13358 patch_new_array_init (type, node)
13359      tree type, node;
13360 {
13361   int error_seen = 0;
13362   tree current, element_type;
13363   HOST_WIDE_INT length;
13364   int all_constant = 1;
13365   tree init = TREE_OPERAND (node, 0);
13366
13367   if (TREE_CODE (type) != POINTER_TYPE || ! TYPE_ARRAY_P (TREE_TYPE (type)))
13368     {
13369       parse_error_context (node,
13370                            "Invalid array initializer for non-array type `%s'",
13371                            lang_printable_name (type, 1));
13372       return error_mark_node;
13373     }
13374   type = TREE_TYPE (type);
13375   element_type = TYPE_ARRAY_ELEMENT (type);
13376
13377   CONSTRUCTOR_ELTS (init) = nreverse (CONSTRUCTOR_ELTS (init));
13378
13379   for (length = 0, current = CONSTRUCTOR_ELTS (init);
13380        current;  length++, current = TREE_CHAIN (current))
13381     {
13382       tree elt = TREE_VALUE (current);
13383       if (elt == NULL_TREE || TREE_CODE (elt) != NEW_ARRAY_INIT)
13384         {
13385           error_seen |= array_constructor_check_entry (element_type, current);
13386           elt = TREE_VALUE (current);
13387           /* When compiling to native code, STRING_CST is converted to
13388              INDIRECT_REF, but still with a TREE_CONSTANT flag. */
13389           if (! TREE_CONSTANT (elt) || TREE_CODE (elt) == INDIRECT_REF)
13390             all_constant = 0;
13391         }
13392       else
13393         {
13394           TREE_VALUE (current) = patch_new_array_init (element_type, elt);
13395           TREE_PURPOSE (current) = NULL_TREE;
13396           all_constant = 0;
13397         }
13398       if (elt && TREE_VALUE (elt) == error_mark_node)
13399         error_seen = 1;
13400     }
13401
13402   if (error_seen)
13403     return error_mark_node;
13404
13405   /* Create a new type. We can't reuse the one we have here by
13406      patching its dimension because it originally is of dimension -1
13407      hence reused by gcc. This would prevent triangular arrays. */
13408   type = build_java_array_type (element_type, length);
13409   TREE_TYPE (init) = TREE_TYPE (TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (type))));
13410   TREE_TYPE (node) = promote_type (type);
13411   TREE_CONSTANT (init) = all_constant;
13412   TREE_CONSTANT (node) = all_constant;
13413   return node;
13414 }
13415
13416 /* Verify that one entry of the initializer element list can be
13417    assigned to the array base type. Report 1 if an error occurred, 0
13418    otherwise.  */
13419
13420 static int
13421 array_constructor_check_entry (type, entry)
13422      tree type, entry;
13423 {
13424   char *array_type_string = NULL;       /* For error reports */
13425   tree value, type_value, new_value, wfl_value, patched;
13426   int error_seen = 0;
13427
13428   new_value = NULL_TREE;
13429   wfl_value = TREE_VALUE (entry);
13430
13431   push_obstacks (&permanent_obstack, &permanent_obstack);
13432   value = java_complete_tree (TREE_VALUE (entry));
13433   /* patch_string return error_mark_node if arg is error_mark_node */
13434   if ((patched = patch_string (value)))
13435     value = patched;
13436   if (value == error_mark_node)
13437     return 1;
13438   
13439   type_value = TREE_TYPE (value);
13440   
13441   /* At anytime, try_builtin_assignconv can report a warning on
13442      constant overflow during narrowing. */
13443   SET_WFL_OPERATOR (wfl_operator, TREE_PURPOSE (entry), wfl_value);
13444   new_value = try_builtin_assignconv (wfl_operator, type, value);
13445   if (!new_value && (new_value = try_reference_assignconv (type, value)))
13446     type_value = promote_type (type);
13447
13448   pop_obstacks ();
13449   /* Check and report errors */
13450   if (!new_value)
13451     {
13452       const char *msg = (!valid_cast_to_p (type_value, type) ?
13453                    "Can't" : "Explicit cast needed to");
13454       if (!array_type_string)
13455         array_type_string = xstrdup (lang_printable_name (type, 1));
13456       parse_error_context 
13457         (wfl_operator, "Incompatible type for array. %s convert `%s' to `%s'",
13458          msg, lang_printable_name (type_value, 1), array_type_string);
13459       error_seen = 1;
13460     }
13461   
13462   if (new_value)
13463     {
13464       new_value = maybe_build_primttype_type_ref (new_value, wfl_operator);
13465       TREE_VALUE (entry) = new_value;
13466     }
13467
13468   if (array_type_string)
13469     free (array_type_string);
13470
13471   TREE_PURPOSE (entry) = NULL_TREE;
13472   return error_seen;
13473 }
13474
13475 static tree
13476 build_this (location)
13477      int location;
13478 {
13479   tree node = build_wfl_node (this_identifier_node);
13480   TREE_SET_CODE (node, THIS_EXPR);
13481   EXPR_WFL_LINECOL (node) = location;
13482   return node;
13483 }
13484
13485 /* 14.15 The return statement. It builds a modify expression that
13486    assigns the returned value to the RESULT_DECL that hold the value
13487    to be returned. */
13488
13489 static tree
13490 build_return (location, op)
13491      int location;
13492      tree op;
13493 {
13494   tree node = build1 (RETURN_EXPR, NULL_TREE, op);
13495   EXPR_WFL_LINECOL (node) = location;
13496   node = build_debugable_stmt (location, node);
13497   return node;
13498 }
13499
13500 static tree
13501 patch_return (node)
13502      tree node;
13503 {
13504   tree return_exp = TREE_OPERAND (node, 0);
13505   tree meth = current_function_decl;
13506   tree mtype = TREE_TYPE (TREE_TYPE (current_function_decl));
13507   int error_found = 0;
13508
13509   TREE_TYPE (node) = error_mark_node;
13510   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13511
13512   /* It's invalid to have a return value within a function that is
13513      declared with the keyword void or that is a constructor */
13514   if (return_exp && (mtype == void_type_node || DECL_CONSTRUCTOR_P (meth)))
13515     error_found = 1;
13516
13517   /* It's invalid to use a return statement in a static block */
13518   if (DECL_CLINIT_P (current_function_decl))
13519     error_found = 1;
13520
13521   /* It's invalid to have a no return value within a function that
13522      isn't declared with the keyword `void' */
13523   if (!return_exp && (mtype != void_type_node && !DECL_CONSTRUCTOR_P (meth)))
13524     error_found = 2;
13525   
13526   if (in_instance_initializer)
13527     error_found = 1;
13528
13529   if (error_found)
13530     {
13531       if (in_instance_initializer)
13532         parse_error_context (wfl_operator,
13533                              "`return' inside instance initializer");
13534         
13535       else if (DECL_CLINIT_P (current_function_decl))
13536         parse_error_context (wfl_operator,
13537                              "`return' inside static initializer");
13538
13539       else if (!DECL_CONSTRUCTOR_P (meth))
13540         {
13541           char *t = xstrdup (lang_printable_name (mtype, 0));
13542           parse_error_context (wfl_operator, 
13543                                "`return' with%s value from `%s %s'",
13544                                (error_found == 1 ? "" : "out"), 
13545                                t, lang_printable_name (meth, 0));
13546           free (t);
13547         }
13548       else
13549         parse_error_context (wfl_operator, 
13550                              "`return' with value from constructor `%s'",
13551                              lang_printable_name (meth, 0));
13552       return error_mark_node;
13553     }
13554
13555   /* If we have a return_exp, build a modify expression and expand
13556      it. Note: at that point, the assignment is declared valid, but we
13557      may want to carry some more hacks */
13558   if (return_exp)
13559     {
13560       tree exp = java_complete_tree (return_exp);
13561       tree modify, patched;
13562
13563       /* If the function returned value and EXP are booleans, EXP has
13564       to be converted into the type of DECL_RESULT, which is integer
13565       (see complete_start_java_method) */
13566       if (TREE_TYPE (exp) == boolean_type_node &&
13567           TREE_TYPE (TREE_TYPE (meth)) == boolean_type_node)
13568         exp = convert_to_integer (TREE_TYPE (DECL_RESULT (meth)), exp);
13569
13570       /* `null' can be assigned to a function returning a reference */
13571       if (JREFERENCE_TYPE_P (TREE_TYPE (TREE_TYPE (meth))) &&
13572           exp == null_pointer_node)
13573         exp = build_null_of_type (TREE_TYPE (TREE_TYPE (meth)));
13574
13575       if ((patched = patch_string (exp)))
13576         exp = patched;
13577       
13578       modify = build (MODIFY_EXPR, NULL_TREE, DECL_RESULT (meth), exp);
13579       EXPR_WFL_LINECOL (modify) = EXPR_WFL_LINECOL (node);
13580       modify = java_complete_tree (modify);
13581
13582       if (modify != error_mark_node)
13583         {
13584           TREE_SIDE_EFFECTS (modify) = 1;
13585           TREE_OPERAND (node, 0) = modify;
13586         }
13587       else
13588         return error_mark_node;
13589     }
13590   TREE_TYPE (node) = void_type_node;
13591   TREE_SIDE_EFFECTS (node) = 1;
13592   return node;
13593 }
13594
13595 /* 14.8 The if Statement */
13596
13597 static tree
13598 build_if_else_statement (location, expression, if_body, else_body)
13599      int location;
13600      tree expression, if_body, else_body;
13601 {
13602   tree node;
13603   if (!else_body)
13604     else_body = empty_stmt_node;
13605   node = build (COND_EXPR, NULL_TREE, expression, if_body, else_body);
13606   EXPR_WFL_LINECOL (node) = location;
13607   node = build_debugable_stmt (location, node);
13608   return node;
13609 }
13610
13611 static tree
13612 patch_if_else_statement (node)
13613      tree node;
13614 {
13615   tree expression = TREE_OPERAND (node, 0);
13616
13617   TREE_TYPE (node) = error_mark_node;
13618   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13619
13620   /* The type of expression must be boolean */
13621   if (TREE_TYPE (expression) != boolean_type_node
13622       && TREE_TYPE (expression) != promoted_boolean_type_node)
13623     {
13624       parse_error_context 
13625         (wfl_operator, 
13626          "Incompatible type for `if'. Can't convert `%s' to `boolean'", 
13627          lang_printable_name (TREE_TYPE (expression), 0));
13628       return error_mark_node;
13629     }
13630   
13631   TREE_TYPE (node) = void_type_node;
13632   TREE_SIDE_EFFECTS (node) = 1;
13633   CAN_COMPLETE_NORMALLY (node)
13634     = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1))
13635     | CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 2));
13636   return node;
13637 }
13638
13639 /* 14.6 Labeled Statements */
13640
13641 /* Action taken when a lableled statement is parsed. a new
13642    LABELED_BLOCK_EXPR is created. No statement is attached to the
13643    label, yet.  LABEL can be NULL_TREE for artificially-generated blocks. */
13644
13645 static tree
13646 build_labeled_block (location, label)
13647      int location;
13648      tree label;
13649 {
13650   tree label_name ;
13651   tree label_decl, node;
13652   if (label == NULL_TREE || label == continue_identifier_node)
13653     label_name = label;
13654   else
13655     {
13656       label_name = merge_qualified_name (label_id, label);
13657       /* Issue an error if we try to reuse a label that was previously
13658          declared */
13659       if (IDENTIFIER_LOCAL_VALUE (label_name))
13660         {
13661           EXPR_WFL_LINECOL (wfl_operator) = location;
13662           parse_error_context (wfl_operator,
13663             "Declaration of `%s' shadows a previous label declaration",
13664                                IDENTIFIER_POINTER (label));
13665           EXPR_WFL_LINECOL (wfl_operator) = 
13666             EXPR_WFL_LINECOL (IDENTIFIER_LOCAL_VALUE (label_name));
13667           parse_error_context (wfl_operator,
13668             "This is the location of the previous declaration of label `%s'",
13669                                IDENTIFIER_POINTER (label));
13670           java_error_count--;
13671         }
13672     }
13673
13674   label_decl = create_label_decl (label_name);
13675   node = build (LABELED_BLOCK_EXPR, NULL_TREE, label_decl, NULL_TREE);
13676   EXPR_WFL_LINECOL (node) = location;
13677   TREE_SIDE_EFFECTS (node) = 1;
13678   return node;
13679 }
13680
13681 /* A labeled statement LBE is attached a statement.  */
13682
13683 static tree
13684 finish_labeled_statement (lbe, statement)
13685      tree lbe;                  /* Labeled block expr */
13686      tree statement;
13687 {
13688   /* In anyways, tie the loop to its statement */
13689   LABELED_BLOCK_BODY (lbe) = statement;
13690   pop_labeled_block ();
13691   POP_LABELED_BLOCK ();
13692   return lbe;
13693 }
13694
13695 /* 14.10, 14.11, 14.12 Loop Statements */
13696
13697 /* Create an empty LOOP_EXPR and make it the last in the nested loop
13698    list. */
13699
13700 static tree
13701 build_new_loop (loop_body)
13702      tree loop_body;
13703 {
13704   tree loop =  build (LOOP_EXPR, NULL_TREE, loop_body);
13705   TREE_SIDE_EFFECTS (loop) = 1;
13706   PUSH_LOOP (loop);
13707   return loop;
13708 }
13709
13710 /* Create a loop body according to the following structure:
13711      COMPOUND_EXPR
13712        COMPOUND_EXPR            (loop main body)
13713          EXIT_EXPR              (this order is for while/for loops.
13714          LABELED_BLOCK_EXPR      the order is reversed for do loops)
13715            LABEL_DECL           (a continue occuring here branches at the 
13716            BODY                  end of this labeled block)
13717        INCREMENT                (if any)
13718
13719   REVERSED, if non zero, tells that the loop condition expr comes
13720   after the body, like in the do-while loop.
13721
13722   To obtain a loop, the loop body structure described above is
13723   encapsulated within a LOOP_EXPR surrounded by a LABELED_BLOCK_EXPR:
13724
13725    LABELED_BLOCK_EXPR
13726      LABEL_DECL                   (use this label to exit the loop)
13727      LOOP_EXPR
13728        <structure described above> */
13729
13730 static tree
13731 build_loop_body (location, condition, reversed)
13732      int location;
13733      tree condition;
13734      int reversed;
13735 {
13736   tree first, second, body;
13737
13738   condition = build (EXIT_EXPR, NULL_TREE, condition); /* Force walk */
13739   EXPR_WFL_LINECOL (condition) = location; /* For accurate error report */
13740   condition = build_debugable_stmt (location, condition);
13741   TREE_SIDE_EFFECTS (condition) = 1;
13742
13743   body = build_labeled_block (0, continue_identifier_node);
13744   first = (reversed ? body : condition);
13745   second = (reversed ? condition : body);
13746   return 
13747     build (COMPOUND_EXPR, NULL_TREE, 
13748            build (COMPOUND_EXPR, NULL_TREE, first, second), empty_stmt_node);
13749 }
13750
13751 /* Install CONDITION (if any) and loop BODY (using REVERSED to tell
13752    their order) on the current loop. Unlink the current loop from the
13753    loop list.  */
13754
13755 static tree
13756 finish_loop_body (location, condition, body, reversed)
13757      int location;
13758      tree condition, body;
13759      int reversed;
13760 {
13761   tree to_return = ctxp->current_loop;
13762   tree loop_body = LOOP_EXPR_BODY (to_return);
13763   if (condition)
13764     {
13765       tree cnode = LOOP_EXPR_BODY_CONDITION_EXPR (loop_body, reversed);
13766       /* We wrapped the EXIT_EXPR around a WFL so we can debug it.
13767          The real EXIT_EXPR is one operand further. */
13768       EXPR_WFL_LINECOL (cnode) = location;
13769       /* This one is for accurate error reports */
13770       EXPR_WFL_LINECOL (TREE_OPERAND (cnode, 0)) = location;
13771       TREE_OPERAND (TREE_OPERAND (cnode, 0), 0) = condition;
13772     }
13773   LOOP_EXPR_BODY_BODY_EXPR (loop_body, reversed) = body;
13774   POP_LOOP ();
13775   return to_return;
13776 }
13777
13778 /* Tailored version of finish_loop_body for FOR loops, when FOR
13779    loops feature the condition part */
13780
13781 static tree
13782 finish_for_loop (location, condition, update, body)
13783     int location;
13784     tree condition, update, body;
13785 {
13786   /* Put the condition and the loop body in place */
13787   tree loop = finish_loop_body (location, condition, body, 0);
13788   /* LOOP is the current loop which has been now popped of the loop
13789      stack. Install the update block */
13790   LOOP_EXPR_BODY_UPDATE_BLOCK (LOOP_EXPR_BODY (loop)) = update;
13791   return loop;
13792 }
13793
13794 /* Try to find the loop a block might be related to. This comprises
13795    the case where the LOOP_EXPR is found as the second operand of a
13796    COMPOUND_EXPR, because the loop happens to have an initialization
13797    part, then expressed as the first operand of the COMPOUND_EXPR. If
13798    the search finds something, 1 is returned. Otherwise, 0 is
13799    returned. The search is assumed to start from a
13800    LABELED_BLOCK_EXPR's block.  */
13801
13802 static tree
13803 search_loop (statement)
13804     tree statement;
13805 {
13806   if (TREE_CODE (statement) == LOOP_EXPR)
13807     return statement;
13808
13809   if (TREE_CODE (statement) == BLOCK)
13810     statement = BLOCK_SUBBLOCKS (statement);
13811   else
13812     return NULL_TREE;
13813
13814   if (statement && TREE_CODE (statement) == COMPOUND_EXPR)
13815     while (statement && TREE_CODE (statement) == COMPOUND_EXPR)
13816       statement = TREE_OPERAND (statement, 1);
13817
13818   return (TREE_CODE (statement) == LOOP_EXPR
13819           && FOR_LOOP_P (statement) ? statement : NULL_TREE);
13820 }
13821
13822 /* Return 1 if LOOP can be found in the labeled block BLOCK. 0 is
13823    returned otherwise.  */
13824
13825 static int
13826 labeled_block_contains_loop_p (block, loop)
13827     tree block, loop;
13828 {
13829   if (!block)
13830     return 0;
13831
13832   if (LABELED_BLOCK_BODY (block) == loop)
13833     return 1;
13834
13835   if (FOR_LOOP_P (loop) && search_loop (LABELED_BLOCK_BODY (block)) == loop)
13836     return 1;
13837
13838   return 0;
13839 }
13840
13841 /* If the loop isn't surrounded by a labeled statement, create one and
13842    insert LOOP as its body.  */
13843
13844 static tree
13845 patch_loop_statement (loop)
13846      tree loop;
13847 {
13848   tree loop_label;
13849
13850   TREE_TYPE (loop) = void_type_node;
13851   if (labeled_block_contains_loop_p (ctxp->current_labeled_block, loop))
13852     return loop;
13853
13854   loop_label = build_labeled_block (0, NULL_TREE);
13855   /* LOOP is an EXPR node, so it should have a valid EXPR_WFL_LINECOL
13856      that LOOP_LABEL could enquire about, for a better accuracy. FIXME */
13857   LABELED_BLOCK_BODY (loop_label) = loop;
13858   PUSH_LABELED_BLOCK (loop_label);
13859   return loop_label;
13860 }
13861
13862 /* 14.13, 14.14: break and continue Statements */
13863
13864 /* Build a break or a continue statement. a null NAME indicates an
13865    unlabeled break/continue statement.  */
13866
13867 static tree
13868 build_bc_statement (location, is_break, name)
13869      int location, is_break;
13870      tree name;
13871 {
13872   tree break_continue, label_block_expr = NULL_TREE;
13873
13874   if (name)
13875     {
13876       if (!(label_block_expr = IDENTIFIER_LOCAL_VALUE 
13877             (merge_qualified_name (label_id, EXPR_WFL_NODE (name)))))
13878         /* Null means that we don't have a target for this named
13879            break/continue. In this case, we make the target to be the
13880            label name, so that the error can be reported accuratly in
13881            patch_bc_statement. */
13882         label_block_expr = EXPR_WFL_NODE (name);
13883     }
13884   /* Unlabeled break/continue will be handled during the
13885      break/continue patch operation */
13886   break_continue 
13887     = build (EXIT_BLOCK_EXPR, NULL_TREE, label_block_expr, NULL_TREE);
13888
13889   IS_BREAK_STMT_P (break_continue) = is_break;
13890   TREE_SIDE_EFFECTS (break_continue) = 1;
13891   EXPR_WFL_LINECOL (break_continue) = location;
13892   break_continue = build_debugable_stmt (location, break_continue);
13893   return break_continue;
13894 }
13895
13896 /* Verification of a break/continue statement. */
13897
13898 static tree
13899 patch_bc_statement (node)
13900      tree node;
13901 {
13902   tree bc_label = EXIT_BLOCK_LABELED_BLOCK (node), target_stmt;
13903   tree labeled_block = ctxp->current_labeled_block;
13904   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13905  
13906   /* Having an identifier here means that the target is unknown. */
13907   if (bc_label != NULL_TREE && TREE_CODE (bc_label) == IDENTIFIER_NODE)
13908     {
13909       parse_error_context (wfl_operator, "No label definition found for `%s'",
13910                            IDENTIFIER_POINTER (bc_label));
13911       return error_mark_node;
13912     }
13913   if (! IS_BREAK_STMT_P (node))
13914     {
13915       /* It's a continue statement. */
13916       for (;; labeled_block = TREE_CHAIN (labeled_block))
13917         {
13918           if (labeled_block == NULL_TREE)
13919             {
13920               if (bc_label == NULL_TREE)
13921                 parse_error_context (wfl_operator,
13922                                      "`continue' must be in loop");
13923               else
13924                 parse_error_context 
13925                   (wfl_operator, "continue label `%s' does not name a loop",
13926                    IDENTIFIER_POINTER (bc_label));
13927               return error_mark_node;
13928             }
13929           if ((DECL_NAME (LABELED_BLOCK_LABEL (labeled_block))
13930                == continue_identifier_node)
13931               && (bc_label == NULL_TREE
13932                   || TREE_CHAIN (labeled_block) == bc_label))
13933             {
13934               bc_label = labeled_block;
13935               break;
13936             }
13937         }
13938     }
13939   else if (!bc_label)
13940     { 
13941       for (;; labeled_block = TREE_CHAIN (labeled_block))
13942         {
13943           if (labeled_block == NULL_TREE)
13944             {
13945               parse_error_context (wfl_operator,
13946                                      "`break' must be in loop or switch");
13947               return error_mark_node;
13948             }
13949           target_stmt = LABELED_BLOCK_BODY (labeled_block);
13950           if (TREE_CODE (target_stmt) == SWITCH_EXPR
13951               || search_loop (target_stmt))
13952             {
13953               bc_label = labeled_block;
13954               break;
13955             }
13956         }
13957     }
13958
13959   EXIT_BLOCK_LABELED_BLOCK (node) = bc_label;
13960   CAN_COMPLETE_NORMALLY (bc_label) = 1;
13961
13962   /* Our break/continue don't return values. */
13963   TREE_TYPE (node) = void_type_node;
13964   /* Encapsulate the break within a compound statement so that it's
13965      expanded all the times by expand_expr (and not clobbered
13966      sometimes, like after a if statement) */
13967   node = add_stmt_to_compound (NULL_TREE, void_type_node, node);
13968   TREE_SIDE_EFFECTS (node) = 1;
13969   return node;
13970 }
13971
13972 /* Process the exit expression belonging to a loop. Its type must be
13973    boolean.  */
13974
13975 static tree
13976 patch_exit_expr (node)
13977      tree node;
13978 {
13979   tree expression = TREE_OPERAND (node, 0);
13980   TREE_TYPE (node) = error_mark_node;
13981   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13982
13983   /* The type of expression must be boolean */
13984   if (TREE_TYPE (expression) != boolean_type_node)
13985     {
13986       parse_error_context 
13987         (wfl_operator, 
13988     "Incompatible type for loop conditional. Can't convert `%s' to `boolean'", 
13989          lang_printable_name (TREE_TYPE (expression), 0));
13990       return error_mark_node;
13991     }
13992   /* Now we know things are allright, invert the condition, fold and
13993      return */
13994   TREE_OPERAND (node, 0) = 
13995     fold (build1 (TRUTH_NOT_EXPR, boolean_type_node, expression));
13996
13997   if (! integer_zerop (TREE_OPERAND (node, 0))
13998       && ctxp->current_loop != NULL_TREE
13999       && TREE_CODE (ctxp->current_loop) == LOOP_EXPR)
14000     CAN_COMPLETE_NORMALLY (ctxp->current_loop) = 1;
14001   if (! integer_onep (TREE_OPERAND (node, 0)))
14002     CAN_COMPLETE_NORMALLY (node) = 1;
14003
14004
14005   TREE_TYPE (node) = void_type_node;
14006   return node;
14007 }
14008
14009 /* 14.9 Switch statement */
14010
14011 static tree
14012 patch_switch_statement (node)
14013      tree node;
14014 {
14015   tree se = TREE_OPERAND (node, 0), se_type;
14016
14017   /* Complete the switch expression */
14018   se = TREE_OPERAND (node, 0) = java_complete_tree (se);
14019   se_type = TREE_TYPE (se);
14020   /* The type of the switch expression must be char, byte, short or
14021      int */
14022   if (!JINTEGRAL_TYPE_P (se_type))
14023     {
14024       EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14025       parse_error_context (wfl_operator,
14026           "Incompatible type for `switch'. Can't convert `%s' to `int'",
14027                            lang_printable_name (se_type, 0));
14028       /* This is what java_complete_tree will check */
14029       TREE_OPERAND (node, 0) = error_mark_node;
14030       return error_mark_node;
14031     }
14032
14033   TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
14034
14035   /* Ready to return */
14036   if (TREE_CODE (TREE_OPERAND (node, 1)) == ERROR_MARK)
14037     {
14038       TREE_TYPE (node) = error_mark_node;
14039       return error_mark_node;
14040     }
14041   TREE_TYPE (node) = void_type_node;
14042   TREE_SIDE_EFFECTS (node) = 1;
14043   CAN_COMPLETE_NORMALLY (node)
14044     = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)) 
14045       || ! SWITCH_HAS_DEFAULT (node);
14046   return node;
14047 }
14048
14049 /* 14.18 The try/catch statements */
14050
14051 static tree
14052 build_try_statement (location, try_block, catches)
14053      int location;
14054      tree try_block, catches;
14055 {
14056   tree node = build (TRY_EXPR, NULL_TREE, try_block, catches);
14057   EXPR_WFL_LINECOL (node) = location;
14058   return node;
14059 }
14060
14061 static tree
14062 build_try_finally_statement (location, try_block, finally)
14063      int location;
14064      tree try_block, finally;
14065 {
14066   tree node = build (TRY_FINALLY_EXPR, NULL_TREE, try_block, finally);
14067   EXPR_WFL_LINECOL (node) = location;
14068   return node;
14069 }
14070
14071 static tree
14072 patch_try_statement (node)
14073      tree node;
14074 {
14075   int error_found = 0;
14076   tree try = TREE_OPERAND (node, 0);
14077   /* Exception handlers are considered in left to right order */
14078   tree catch = nreverse (TREE_OPERAND (node, 1));
14079   tree current, caught_type_list = NULL_TREE;
14080
14081   /* Check catch clauses, if any. Every time we find an error, we try
14082      to process the next catch clause. We process the catch clause before
14083      the try block so that when processing the try block we can check thrown
14084      exceptions againts the caught type list. */
14085   for (current = catch; current; current = TREE_CHAIN (current))
14086     {
14087       tree carg_decl, carg_type;
14088       tree sub_current, catch_block, catch_clause;
14089       int unreachable;
14090
14091       /* At this point, the structure of the catch clause is
14092            CATCH_EXPR           (catch node)
14093              BLOCK              (with the decl of the parameter)
14094                COMPOUND_EXPR
14095                  MODIFY_EXPR   (assignment of the catch parameter)
14096                  BLOCK          (catch clause block)
14097        */
14098       catch_clause = TREE_OPERAND (current, 0);
14099       carg_decl = BLOCK_EXPR_DECLS (catch_clause);
14100       carg_type = TREE_TYPE (TREE_TYPE (carg_decl));
14101
14102       /* Catch clauses can't have more than one parameter declared,
14103          but it's already enforced by the grammar. Make sure that the
14104          only parameter of the clause statement in of class Throwable
14105          or a subclass of Throwable, but that was done earlier. The
14106          catch clause parameter type has also been resolved. */
14107       
14108       /* Just make sure that the catch clause parameter type inherits
14109          from java.lang.Throwable */
14110       if (!inherits_from_p (carg_type, throwable_type_node))
14111         {
14112           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
14113           parse_error_context (wfl_operator,
14114                                "Can't catch class `%s'. Catch clause parameter type must be a subclass of class `java.lang.Throwable'",
14115                                lang_printable_name (carg_type, 0));
14116           error_found = 1;
14117           continue;
14118         }
14119       
14120       /* Partial check for unreachable catch statement: The catch
14121          clause is reachable iff is no earlier catch block A in
14122          the try statement such that the type of the catch
14123          clause's parameter is the same as or a subclass of the
14124          type of A's parameter */
14125       unreachable = 0;
14126       for (sub_current = catch;
14127            sub_current != current; sub_current = TREE_CHAIN (sub_current))
14128         {
14129           tree sub_catch_clause, decl;
14130           sub_catch_clause = TREE_OPERAND (sub_current, 0);
14131           decl = BLOCK_EXPR_DECLS (sub_catch_clause);
14132
14133           if (inherits_from_p (carg_type, TREE_TYPE (TREE_TYPE (decl))))
14134             {
14135               EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
14136               parse_error_context 
14137                 (wfl_operator,
14138                  "`catch' not reached because of the catch clause at line %d",
14139                  EXPR_WFL_LINENO (sub_current));
14140               unreachable = error_found = 1;
14141               break;
14142             }
14143         }
14144       /* Complete the catch clause block */
14145       catch_block = java_complete_tree (TREE_OPERAND (current, 0));
14146       if (catch_block == error_mark_node)
14147         {
14148           error_found = 1;
14149           continue;
14150         }
14151       if (CAN_COMPLETE_NORMALLY (catch_block))
14152         CAN_COMPLETE_NORMALLY (node) = 1;
14153       TREE_OPERAND (current, 0) = catch_block;
14154
14155       if (unreachable)
14156         continue;
14157
14158       /* Things to do here: the exception must be thrown */
14159
14160       /* Link this type to the caught type list */
14161       caught_type_list = tree_cons (NULL_TREE, carg_type, caught_type_list);
14162     }
14163
14164   PUSH_EXCEPTIONS (caught_type_list);
14165   if ((try = java_complete_tree (try)) == error_mark_node)
14166     error_found = 1;
14167   if (CAN_COMPLETE_NORMALLY (try))
14168     CAN_COMPLETE_NORMALLY (node) = 1;
14169   POP_EXCEPTIONS ();
14170
14171   /* Verification ends here */
14172   if (error_found) 
14173     return error_mark_node;
14174
14175   TREE_OPERAND (node, 0) = try;
14176   TREE_OPERAND (node, 1) = catch;
14177   TREE_TYPE (node) = void_type_node;
14178   return node;
14179 }
14180
14181 /* 14.17 The synchronized Statement */
14182
14183 static tree
14184 patch_synchronized_statement (node, wfl_op1)
14185     tree node, wfl_op1;
14186 {
14187   tree expr = java_complete_tree (TREE_OPERAND (node, 0));
14188   tree block = TREE_OPERAND (node, 1);
14189
14190   tree enter, exit, expr_decl, assignment;
14191
14192   if (expr == error_mark_node)
14193     {
14194       block = java_complete_tree (block);
14195       return expr;
14196     }
14197
14198   /* The TYPE of expr must be a reference type */
14199   if (!JREFERENCE_TYPE_P (TREE_TYPE (expr)))
14200     {
14201       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
14202       parse_error_context (wfl_operator, "Incompatible type for `synchronized'. Can't convert `%s' to `java.lang.Object'",
14203                            lang_printable_name (TREE_TYPE (expr), 0));
14204       return error_mark_node;
14205     }
14206
14207   if (flag_emit_xref)
14208     {
14209       TREE_OPERAND (node, 0) = expr;
14210       TREE_OPERAND (node, 1) = java_complete_tree (block);
14211       CAN_COMPLETE_NORMALLY (node) = 1;
14212       return node;
14213     }
14214
14215   /* Generate a try-finally for the synchronized statement, except
14216      that the handler that catches all throw exception calls
14217      _Jv_MonitorExit and then rethrow the exception.
14218      The synchronized statement is then implemented as:
14219      TRY 
14220        {
14221          _Jv_MonitorEnter (expression)
14222          synchronized_block
14223          _Jv_MonitorExit (expression)
14224        }
14225      CATCH_ALL
14226        {
14227          e = _Jv_exception_info ();
14228          _Jv_MonitorExit (expression)
14229          Throw (e);
14230        } */
14231
14232   expr_decl = build_decl (VAR_DECL, generate_name (), TREE_TYPE (expr));
14233   BUILD_MONITOR_ENTER (enter, expr_decl);
14234   BUILD_MONITOR_EXIT (exit, expr_decl);
14235   CAN_COMPLETE_NORMALLY (enter) = 1;
14236   CAN_COMPLETE_NORMALLY (exit) = 1;
14237   assignment = build (MODIFY_EXPR, NULL_TREE, expr_decl, expr);
14238   TREE_SIDE_EFFECTS (assignment) = 1;
14239   node = build1 (CLEANUP_POINT_EXPR, NULL_TREE,
14240                  build (COMPOUND_EXPR, NULL_TREE,
14241                         build (WITH_CLEANUP_EXPR, NULL_TREE,
14242                                build (COMPOUND_EXPR, NULL_TREE,
14243                                       assignment, enter),
14244                                NULL_TREE, exit),
14245                         block));
14246   node = build_expr_block (node, expr_decl);
14247
14248   return java_complete_tree (node);
14249 }
14250
14251 /* 14.16 The throw Statement */
14252
14253 static tree
14254 patch_throw_statement (node, wfl_op1)
14255     tree node, wfl_op1;
14256 {
14257   tree expr = TREE_OPERAND (node, 0);
14258   tree type = TREE_TYPE (expr);
14259   int unchecked_ok = 0, tryblock_throws_ok = 0;
14260
14261   /* Thrown expression must be assignable to java.lang.Throwable */
14262   if (!try_reference_assignconv (throwable_type_node, expr))
14263     {
14264       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
14265       parse_error_context (wfl_operator,
14266     "Can't throw `%s'; it must be a subclass of class `java.lang.Throwable'",
14267                            lang_printable_name (type, 0));
14268       /* If the thrown expression was a reference, we further the
14269          compile-time check. */
14270       if (!JREFERENCE_TYPE_P (type))
14271         return error_mark_node;
14272     }
14273
14274   /* At least one of the following must be true */
14275
14276   /* The type of the throw expression is a not checked exception,
14277      i.e. is a unchecked expression. */
14278   unchecked_ok = IS_UNCHECKED_EXCEPTION_P (TREE_TYPE (type));
14279
14280   SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
14281   /* An instance can't throw a checked excetion unless that exception
14282      is explicitely declared in the `throws' clause of each
14283      constructor. This doesn't apply to anonymous classes, since they
14284      don't have declared constructors. */
14285   if (!unchecked_ok 
14286       && in_instance_initializer && !ANONYMOUS_CLASS_P (current_class))
14287     {
14288       tree current;
14289       for (current = TYPE_METHODS (current_class); current; 
14290            current = TREE_CHAIN (current))
14291         if (DECL_CONSTRUCTOR_P (current) 
14292             && !check_thrown_exceptions_do (TREE_TYPE (expr)))
14293           {
14294             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)", 
14295                                  lang_printable_name (TREE_TYPE (expr), 0));
14296             return error_mark_node;
14297           }
14298     }
14299
14300   /* Throw is contained in a try statement and at least one catch
14301      clause can receive the thrown expression or the current method is
14302      declared to throw such an exception. Or, the throw statement is
14303      contained in a method or constructor declaration and the type of
14304      the Expression is assignable to at least one type listed in the
14305      throws clause the declaration. */
14306   if (!unchecked_ok)
14307     tryblock_throws_ok = check_thrown_exceptions_do (TREE_TYPE (expr));
14308   if (!(unchecked_ok || tryblock_throws_ok))
14309     {
14310       /* If there is a surrounding try block that has no matching
14311          clatch clause, report it first. A surrounding try block exits
14312          only if there is something after the list of checked
14313          exception thrown by the current function (if any). */
14314       if (IN_TRY_BLOCK_P ())
14315         parse_error_context (wfl_operator, "Checked exception `%s' can't be caught by any of the catch clause(s) of the surrounding `try' block",
14316                              lang_printable_name (type, 0));
14317       /* If we have no surrounding try statement and the method doesn't have
14318          any throws, report it now. FIXME */
14319
14320       /* We report that the exception can't be throw from a try block
14321          in all circumstances but when the `throw' is inside a static
14322          block. */
14323       else if (!EXCEPTIONS_P (currently_caught_type_list) 
14324                && !tryblock_throws_ok)
14325         {
14326           if (DECL_CLINIT_P (current_function_decl))
14327             parse_error_context (wfl_operator,
14328                    "Checked exception `%s' can't be thrown in initializer",
14329                                  lang_printable_name (type, 0));
14330           else
14331             parse_error_context (wfl_operator,
14332                    "Checked exception `%s' isn't thrown from a `try' block", 
14333                                  lang_printable_name (type, 0));
14334         }
14335       /* Otherwise, the current method doesn't have the appropriate
14336          throws declaration */
14337       else
14338         parse_error_context (wfl_operator, "Checked exception `%s' doesn't match any of current method's `throws' declaration(s)", 
14339                              lang_printable_name (type, 0));
14340       return error_mark_node;
14341     }
14342
14343   if (! flag_emit_class_files && ! flag_emit_xref)
14344     BUILD_THROW (node, expr);
14345
14346   /* If doing xrefs, keep the location where the `throw' was seen. */
14347   if (flag_emit_xref)
14348     EXPR_WFL_LINECOL (node) = EXPR_WFL_LINECOL (wfl_op1);
14349   return node;
14350 }
14351
14352 /* Check that exception said to be thrown by method DECL can be
14353    effectively caught from where DECL is invoked.  */
14354
14355 static void
14356 check_thrown_exceptions (location, decl)
14357      int location;
14358      tree decl;
14359 {
14360   tree throws;
14361   /* For all the unchecked exceptions thrown by DECL */
14362   for (throws = DECL_FUNCTION_THROWS (decl); throws; 
14363        throws = TREE_CHAIN (throws)) 
14364     if (!check_thrown_exceptions_do (TREE_VALUE (throws)))
14365       {
14366 #if 1
14367         /* Temporary hack to suppresses errors about cloning arrays. FIXME */
14368         if (DECL_NAME (decl) == get_identifier ("clone"))
14369           continue;
14370 #endif
14371         EXPR_WFL_LINECOL (wfl_operator) = location;
14372         if (DECL_FINIT_P (current_function_decl))
14373           parse_error_context
14374             (wfl_operator, "Exception `%s' can't be thrown in initializer",
14375              lang_printable_name (TREE_VALUE (throws), 0));
14376         else 
14377           {
14378             parse_error_context 
14379               (wfl_operator, "Exception `%s' must be caught, or it must be declared in the `throws' clause of `%s'", 
14380                lang_printable_name (TREE_VALUE (throws), 0),
14381                (DECL_INIT_P (current_function_decl) ?
14382                 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))) :
14383                 IDENTIFIER_POINTER (DECL_NAME (current_function_decl))));
14384           }
14385       }
14386 }
14387
14388 /* Return 1 if checked EXCEPTION is caught at the current nesting level of
14389    try-catch blocks, OR is listed in the `throws' clause of the
14390    current method.  */
14391
14392 static int
14393 check_thrown_exceptions_do (exception)
14394      tree exception;
14395 {
14396   tree list = currently_caught_type_list;
14397   resolve_and_layout (exception, NULL_TREE);
14398   /* First, all the nested try-catch-finally at that stage. The
14399      last element contains `throws' clause exceptions, if any. */
14400   if (IS_UNCHECKED_EXCEPTION_P (exception))
14401     return 1;
14402   while (list)
14403     {
14404       tree caught;
14405       for (caught = TREE_VALUE (list); caught; caught = TREE_CHAIN (caught))
14406         if (valid_ref_assignconv_cast_p (exception, TREE_VALUE (caught), 0))
14407           return 1;
14408       list = TREE_CHAIN (list);
14409     }
14410   return 0;
14411 }
14412
14413 static void
14414 purge_unchecked_exceptions (mdecl)
14415      tree mdecl;
14416 {
14417   tree throws = DECL_FUNCTION_THROWS (mdecl);
14418   tree new = NULL_TREE;
14419
14420   while (throws)
14421     {
14422       tree next = TREE_CHAIN (throws);
14423       if (!IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (throws)))
14424         {
14425           TREE_CHAIN (throws) = new;
14426           new = throws;
14427         }
14428       throws = next;
14429     }
14430   /* List is inverted here, but it doesn't matter */
14431   DECL_FUNCTION_THROWS (mdecl) = new;
14432 }
14433
14434 /* 15.24 Conditional Operator ?: */
14435
14436 static tree
14437 patch_conditional_expr (node, wfl_cond, wfl_op1)
14438      tree node, wfl_cond, wfl_op1;
14439 {
14440   tree cond = TREE_OPERAND (node, 0);
14441   tree op1 = TREE_OPERAND (node, 1);
14442   tree op2 = TREE_OPERAND (node, 2);
14443   tree resulting_type = NULL_TREE;
14444   tree t1, t2, patched;
14445   int error_found = 0;
14446
14447   /* Operands of ?: might be StringBuffers crafted as a result of a
14448      string concatenation. Obtain a descent operand here.  */
14449   if ((patched = patch_string (op1)))
14450     TREE_OPERAND (node, 1) = op1 = patched;
14451   if ((patched = patch_string (op2)))
14452     TREE_OPERAND (node, 2) = op2 = patched;
14453
14454   t1 = TREE_TYPE (op1);
14455   t2 = TREE_TYPE (op2);
14456
14457   /* The first expression must be a boolean */
14458   if (TREE_TYPE (cond) != boolean_type_node)
14459     {
14460       SET_WFL_OPERATOR (wfl_operator, node, wfl_cond);
14461       parse_error_context (wfl_operator,
14462                "Incompatible type for `?:'. Can't convert `%s' to `boolean'",
14463                            lang_printable_name (TREE_TYPE (cond), 0));
14464       error_found = 1;
14465     }
14466
14467   /* Second and third can be numeric, boolean (i.e. primitive),
14468      references or null. Anything else results in an error */
14469   if (!((JNUMERIC_TYPE_P (t1) && JNUMERIC_TYPE_P (t2))
14470         || ((JREFERENCE_TYPE_P (t1) || op1 == null_pointer_node) 
14471             && (JREFERENCE_TYPE_P (t2) || op2 == null_pointer_node))
14472         || (t1 == boolean_type_node && t2 == boolean_type_node)))
14473     error_found = 1;
14474
14475   /* Determine the type of the conditional expression. Same types are
14476      easy to deal with */
14477   else if (t1 == t2)
14478     resulting_type = t1;
14479
14480   /* There are different rules for numeric types */
14481   else if (JNUMERIC_TYPE_P (t1))
14482     {
14483       /* if byte/short found, the resulting type is short */
14484       if ((t1 == byte_type_node && t2 == short_type_node)
14485           || (t1 == short_type_node && t2 == byte_type_node))
14486         resulting_type = short_type_node;
14487
14488       /* If t1 is a constant int and t2 is of type byte, short or char
14489          and t1's value fits in t2, then the resulting type is t2 */
14490       else if ((t1 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 1)))
14491           && JBSC_TYPE_P (t2) && int_fits_type_p (TREE_OPERAND (node, 1), t2))
14492         resulting_type = t2;
14493
14494       /* If t2 is a constant int and t1 is of type byte, short or char
14495          and t2's value fits in t1, then the resulting type is t1 */
14496       else if ((t2 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 2)))
14497           && JBSC_TYPE_P (t1) && int_fits_type_p (TREE_OPERAND (node, 2), t1))
14498         resulting_type = t1;
14499
14500       /* Otherwise, binary numeric promotion is applied and the
14501          resulting type is the promoted type of operand 1 and 2 */
14502       else 
14503         resulting_type = binary_numeric_promotion (t1, t2, 
14504                                                    &TREE_OPERAND (node, 1), 
14505                                                    &TREE_OPERAND (node, 2));
14506     }
14507
14508   /* Cases of a reference and a null type */
14509   else if (JREFERENCE_TYPE_P (t1) && op2 == null_pointer_node)
14510     resulting_type = t1;
14511
14512   else if (JREFERENCE_TYPE_P (t2) && op1 == null_pointer_node)
14513     resulting_type = t2;
14514
14515   /* Last case: different reference types. If a type can be converted
14516      into the other one by assignment conversion, the latter
14517      determines the type of the expression */
14518   else if ((resulting_type = try_reference_assignconv (t1, op2)))
14519     resulting_type = promote_type (t1);
14520
14521   else if ((resulting_type = try_reference_assignconv (t2, op1)))
14522     resulting_type = promote_type (t2);
14523
14524   /* If we don't have any resulting type, we're in trouble */
14525   if (!resulting_type)
14526     {
14527       char *t = xstrdup (lang_printable_name (t1, 0));
14528       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
14529       parse_error_context (wfl_operator,
14530                  "Incompatible type for `?:'. Can't convert `%s' to `%s'",
14531                            t, lang_printable_name (t2, 0));
14532       free (t);
14533       error_found = 1;
14534     }
14535
14536   if (error_found)
14537     {
14538       TREE_TYPE (node) = error_mark_node;
14539       return error_mark_node;
14540     }
14541
14542   TREE_TYPE (node) = resulting_type;
14543   TREE_SET_CODE (node, COND_EXPR);
14544   CAN_COMPLETE_NORMALLY (node) = 1;
14545   return node;
14546 }
14547
14548 /* Try to constant fold NODE.
14549    If NODE is not a constant expression, return NULL_EXPR.
14550    CONTEXT is a static final VAR_DECL whose initializer we are folding. */
14551
14552 static tree
14553 fold_constant_for_init (node, context)
14554      tree node;
14555      tree context;
14556 {
14557   tree op0, op1, val;
14558   enum tree_code code = TREE_CODE (node);
14559
14560   if (code == STRING_CST)
14561     return node;
14562
14563   if (code == INTEGER_CST || code == REAL_CST)
14564     return convert (TREE_TYPE (context), node);
14565   if (TREE_TYPE (node) != NULL_TREE && code != VAR_DECL && code != FIELD_DECL)
14566     return NULL_TREE;
14567
14568   switch (code)
14569     {
14570     case PLUS_EXPR:
14571     case MINUS_EXPR:
14572     case MULT_EXPR:
14573     case TRUNC_MOD_EXPR:
14574     case RDIV_EXPR:
14575     case LSHIFT_EXPR:
14576     case RSHIFT_EXPR:
14577     case URSHIFT_EXPR:
14578     case BIT_AND_EXPR:
14579     case BIT_XOR_EXPR:
14580     case BIT_IOR_EXPR:
14581     case TRUTH_ANDIF_EXPR:
14582     case TRUTH_ORIF_EXPR:
14583     case EQ_EXPR: 
14584     case NE_EXPR:
14585     case GT_EXPR:
14586     case GE_EXPR:
14587     case LT_EXPR:
14588     case LE_EXPR:
14589       op0 = TREE_OPERAND (node, 0);
14590       op1 = TREE_OPERAND (node, 1);
14591       val = fold_constant_for_init (op0, context);
14592       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14593         return NULL_TREE;
14594       TREE_OPERAND (node, 0) = val;
14595       val = fold_constant_for_init (op1, context);
14596       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14597         return NULL_TREE;
14598       TREE_OPERAND (node, 1) = val;
14599       return patch_binop (node, op0, op1);
14600
14601     case UNARY_PLUS_EXPR:
14602     case NEGATE_EXPR:
14603     case TRUTH_NOT_EXPR:
14604     case BIT_NOT_EXPR:
14605     case CONVERT_EXPR:
14606       op0 = TREE_OPERAND (node, 0);
14607       val = fold_constant_for_init (op0, context);
14608       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14609         return NULL_TREE;
14610       TREE_OPERAND (node, 0) = val;
14611       return patch_unaryop (node, op0);
14612       break;
14613
14614     case COND_EXPR:
14615       val = fold_constant_for_init (TREE_OPERAND (node, 0), context);
14616       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14617         return NULL_TREE;
14618       TREE_OPERAND (node, 0) = val;
14619       val = fold_constant_for_init (TREE_OPERAND (node, 1), context);
14620       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14621         return NULL_TREE;
14622       TREE_OPERAND (node, 1) = val;
14623       val = fold_constant_for_init (TREE_OPERAND (node, 2), context);
14624       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14625         return NULL_TREE;
14626       TREE_OPERAND (node, 2) = val;
14627       return integer_zerop (TREE_OPERAND (node, 0)) ? TREE_OPERAND (node, 1)
14628         : TREE_OPERAND (node, 2);
14629
14630     case VAR_DECL:
14631     case FIELD_DECL:
14632       if (! FIELD_FINAL (node)
14633           || DECL_INITIAL (node) == NULL_TREE)
14634         return NULL_TREE;
14635       val = DECL_INITIAL (node);
14636       /* Guard against infinite recursion. */
14637       DECL_INITIAL (node) = NULL_TREE;
14638       val = fold_constant_for_init (val, node);
14639       DECL_INITIAL (node) = val;
14640       return val;
14641
14642     case EXPR_WITH_FILE_LOCATION:
14643       /* Compare java_complete_tree and resolve_expression_name. */
14644       if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
14645           || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
14646         {
14647           tree name = EXPR_WFL_NODE (node);
14648           tree decl;
14649           if (PRIMARY_P (node))
14650             return NULL_TREE;
14651           else if (! QUALIFIED_P (name))
14652             {
14653               decl = lookup_field_wrapper (DECL_CONTEXT (context), name);
14654               if (decl == NULL_TREE 
14655                   || (! FIELD_STATIC (decl) && ! FIELD_FINAL (decl)))
14656                 return NULL_TREE;
14657               return fold_constant_for_init (decl, decl);
14658             }
14659           else
14660             {
14661               /* Wait until the USE_COMPONENT_REF re-write.  FIXME. */
14662               qualify_ambiguous_name (node);
14663               if (resolve_field_access (node, &decl, NULL)
14664                   && decl != NULL_TREE)
14665                 return fold_constant_for_init (decl, decl);
14666               return NULL_TREE;
14667             }
14668         }
14669       else
14670         {
14671           op0 = TREE_OPERAND (node, 0);
14672           val = fold_constant_for_init (op0, context);
14673           if (val == NULL_TREE || ! TREE_CONSTANT (val))
14674             return NULL_TREE;
14675           TREE_OPERAND (node, 0) = val;
14676           return val;
14677         }
14678
14679 #ifdef USE_COMPONENT_REF
14680     case IDENTIFIER:
14681     case COMPONENT_REF:
14682       ?;
14683 #endif
14684
14685     default:
14686       return NULL_TREE;
14687     }
14688 }
14689
14690 #ifdef USE_COMPONENT_REF
14691 /* Context is 'T' for TypeName, 'P' for PackageName,
14692    'M' for MethodName, 'E' for ExpressionName, and 'A' for AmbiguousName. */
14693
14694 tree
14695 resolve_simple_name (name, context)
14696      tree name;
14697      int context;
14698 {
14699 }
14700
14701 tree
14702 resolve_qualified_name (name, context)
14703      tree name;
14704      int context;
14705 {
14706 }
14707 #endif