OSDN Git Service

* java-tree.h: Added init state enum.
[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 const 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   const 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   /* We're ending a class declaration, this is a good time to reset
3874      the interface cout. Note that might have been already done in
3875      create_interface, but if at that time an inner class was being
3876      dealt with, the interface count was reset in a context created
3877      for the sake of handling inner classes declaration. */
3878   ctxp->interface_number = 0;
3879 }
3880
3881 static void
3882 add_inner_class_fields (class_decl, fct_decl)
3883      tree class_decl;
3884      tree fct_decl;
3885 {
3886   tree block, marker, f;
3887
3888   f = add_field (TREE_TYPE (class_decl),
3889                  build_current_thisn (TREE_TYPE (class_decl)),
3890                  build_pointer_type (TREE_TYPE (DECL_CONTEXT (class_decl))), 
3891                  ACC_PRIVATE);
3892   FIELD_THISN (f) = 1;
3893
3894   if (!fct_decl)
3895     return;
3896     
3897   for (block = GET_CURRENT_BLOCK (fct_decl); 
3898        block && TREE_CODE (block) == BLOCK; block = BLOCK_SUPERCONTEXT (block))
3899     {
3900       tree decl;
3901       for (decl = BLOCK_EXPR_DECLS (block); decl; decl = TREE_CHAIN (decl))
3902         {
3903           char *name, *pname;
3904           tree wfl, init, list;
3905           
3906           /* Avoid non final arguments. */
3907           if (!LOCAL_FINAL (decl))
3908             continue;
3909           
3910           MANGLE_OUTER_LOCAL_VARIABLE_NAME (name, DECL_NAME (decl));
3911           MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_ID (pname, DECL_NAME (decl));
3912           wfl = build_wfl_node (get_identifier (name));
3913           init = build_wfl_node (get_identifier (pname));
3914           /* Build an initialization for the field: it will be
3915              initialized by a parameter added to $finit$, bearing a
3916              mangled name of the field itself (param$<n>.) The
3917              parameter is provided to $finit$ by the constructor
3918              invoking it (hence the constructor will also feature a
3919              hidden parameter, set to the value of the outer context
3920              local at the time the inner class is created.)
3921              
3922              Note: we take into account all possible locals that can
3923              be accessed by the inner class. It's actually not trivial
3924              to minimize these aliases down to the ones really
3925              used. One way to do that would be to expand all regular
3926              methods first, then $finit$ to get a picture of what's
3927              used.  It works with the exception that we would have to
3928              go back on all constructor invoked in regular methods to
3929              have their invokation reworked (to include the right amount
3930              of alias initializer parameters.)
3931
3932              The only real way around, I think, is a first pass to
3933              identify locals really used in the inner class. We leave
3934              the flag FIELD_LOCAL_ALIAS_USED around for that future
3935              use.
3936              
3937              On the other hand, it only affect local inner classes,
3938              whose constructors (and $finit$ call) will be featuring
3939              unecessary arguments. It's easy for a developper to keep
3940              this number of parameter down by using the `final'
3941              keyword only when necessary. For the time being, we can
3942              issue a warning on unecessary finals. FIXME */
3943           init = build_assignment (ASSIGN_TK, EXPR_WFL_LINECOL (wfl), 
3944                                    wfl, init);
3945
3946           /* Register the field. The TREE_LIST holding the part
3947              initialized/initializer will be marked ARG_FINAL_P so
3948              that the created field can be marked
3949              FIELD_LOCAL_ALIAS. */
3950           list = build_tree_list (wfl, init);
3951           ARG_FINAL_P (list) = 1;
3952           register_fields (ACC_PRIVATE | ACC_FINAL, TREE_TYPE (decl), list);
3953         }
3954     }
3955
3956   if (!CPC_INITIALIZER_STMT (ctxp))
3957     return;
3958
3959   /* If we ever registered an alias field, insert and marker to
3960      remeber where the list ends. The second part of the list (the one
3961      featuring initialized fields) so it can be later reversed to
3962      enforce 8.5. The marker will be removed during that operation. */
3963   marker = build_tree_list (NULL_TREE, NULL_TREE);
3964   TREE_CHAIN (marker) = CPC_INITIALIZER_STMT (ctxp);
3965   SET_CPC_INITIALIZER_STMT (ctxp, marker);
3966 }
3967
3968 /* Can't use lookup_field () since we don't want to load the class and
3969    can't set the CLASS_LOADED_P flag */
3970
3971 static tree
3972 find_field (class, name)
3973      tree class;
3974      tree name;
3975 {
3976   tree decl;
3977   for (decl = TYPE_FIELDS (class); decl; decl = TREE_CHAIN (decl))
3978     {
3979       if (DECL_NAME (decl) == name)
3980         return decl;
3981     }
3982   return NULL_TREE;
3983 }
3984
3985 /* Wrap around lookup_field that doesn't potentially upset the value
3986    of CLASS */
3987
3988 static tree
3989 lookup_field_wrapper (class, name)
3990      tree class, name;
3991 {
3992   tree type = class;
3993   tree decl;
3994   java_parser_context_save_global ();
3995   decl = lookup_field (&type, name);
3996
3997   /* Last chance: if we're within the context of an inner class, we
3998      might be trying to access a local variable defined in an outer
3999      context. We try to look for it now. */
4000   if (INNER_CLASS_TYPE_P (class) && (!decl || decl == error_mark_node))
4001     {
4002       char *alias_buffer;
4003       MANGLE_OUTER_LOCAL_VARIABLE_NAME (alias_buffer, name);
4004       name = get_identifier (alias_buffer);
4005       type = class;
4006       decl = lookup_field (&type, name);
4007       if (decl && decl != error_mark_node)
4008         FIELD_LOCAL_ALIAS_USED (decl) = 1;
4009     }
4010
4011   java_parser_context_restore_global ();
4012   return decl == error_mark_node ? NULL : decl;
4013 }
4014
4015 /* Find duplicate field within the same class declarations and report
4016    the error. Returns 1 if a duplicated field was found, 0
4017    otherwise.  */
4018
4019 static int
4020 duplicate_declaration_error_p (new_field_name, new_type, cl)
4021      tree new_field_name, new_type, cl;
4022 {
4023   /* This might be modified to work with method decl as well */
4024   tree decl = find_field (TREE_TYPE (GET_CPC ()), new_field_name);
4025   if (decl)
4026     {
4027       char *t1 = xstrdup (purify_type_name
4028                          ((TREE_CODE (new_type) == POINTER_TYPE 
4029                            && TREE_TYPE (new_type) == NULL_TREE) ?
4030                           IDENTIFIER_POINTER (TYPE_NAME (new_type)) :
4031                           lang_printable_name (new_type, 1)));
4032       /* The type may not have been completed by the time we report
4033          the error */
4034       char *t2 = xstrdup (purify_type_name
4035                          ((TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE 
4036                            && TREE_TYPE (TREE_TYPE (decl)) == NULL_TREE) ?
4037                           IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl))) :
4038                           lang_printable_name (TREE_TYPE (decl), 1)));
4039       parse_error_context 
4040         (cl , "Duplicate variable declaration: `%s %s' was `%s %s' (%s:%d)", 
4041          t1, IDENTIFIER_POINTER (new_field_name),
4042          t2, IDENTIFIER_POINTER (DECL_NAME (decl)),
4043          DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
4044       free (t1);
4045       free (t2);
4046       return 1;
4047     }
4048   return 0;
4049 }
4050
4051 /* Field registration routine. If TYPE doesn't exist, field
4052    declarations are linked to the undefined TYPE dependency list, to
4053    be later resolved in java_complete_class () */
4054
4055 static void
4056 register_fields (flags, type, variable_list)
4057      int flags;
4058      tree type, variable_list;
4059 {
4060   tree current, saved_type;
4061   tree class_type = NULL_TREE;
4062   int saved_lineno = lineno;
4063   int must_chain = 0;
4064   tree wfl = NULL_TREE;
4065
4066   if (GET_CPC ())
4067     class_type = TREE_TYPE (GET_CPC ());
4068
4069   if (!class_type || class_type == error_mark_node)
4070     return;
4071
4072   /* If we're adding fields to interfaces, those fields are public,
4073      static, final */
4074   if (CLASS_INTERFACE (TYPE_NAME (class_type)))
4075     {
4076       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (PUBLIC_TK),
4077                                  flags, ACC_PUBLIC, "interface field(s)");
4078       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (STATIC_TK),
4079                                  flags, ACC_STATIC, "interface field(s)");
4080       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (FINAL_TK),
4081                                  flags, ACC_FINAL, "interface field(s)");
4082       check_modifiers ("Illegal interface member modifier `%s'", flags,
4083                        INTERFACE_FIELD_MODIFIERS);
4084       flags |= (ACC_PUBLIC | ACC_STATIC | ACC_FINAL);
4085     }
4086
4087   /* Obtain a suitable type for resolution, if necessary */
4088   SET_TYPE_FOR_RESOLUTION (type, wfl, must_chain);
4089
4090   /* If TYPE is fully resolved and we don't have a reference, make one */
4091   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4092
4093   for (current = variable_list, saved_type = type; current; 
4094        current = TREE_CHAIN (current), type = saved_type)
4095     {
4096       tree real_type;
4097       tree field_decl;
4098       tree cl = TREE_PURPOSE (current);
4099       tree init = TREE_VALUE (current);
4100       tree current_name = EXPR_WFL_NODE (cl);
4101
4102       /* Can't declare static fields in inner classes */
4103       if ((flags & ACC_STATIC) && !TOPLEVEL_CLASS_TYPE_P (class_type)
4104           && !CLASS_INTERFACE (TYPE_NAME (class_type)))
4105         parse_error_context 
4106           (cl, "Field `%s' can't be static in innerclass `%s'. Only members of interfaces and top-level classes can be static",
4107            IDENTIFIER_POINTER (EXPR_WFL_NODE (cl)),
4108            lang_printable_name (class_type, 0));
4109
4110       /* Process NAME, as it may specify extra dimension(s) for it */
4111       type = build_array_from_name (type, wfl, current_name, &current_name);
4112
4113       /* Type adjustment. We may have just readjusted TYPE because
4114          the variable specified more dimensions. Make sure we have
4115          a reference if we can and don't have one already. Also
4116          change the name if we have an init. */
4117       if (type != saved_type)
4118         {
4119           PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4120           if (init)
4121             EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = current_name;
4122         }
4123
4124       real_type = GET_REAL_TYPE (type);
4125       /* Check for redeclarations */
4126       if (duplicate_declaration_error_p (current_name, real_type, cl))
4127         continue;
4128
4129       /* Set lineno to the line the field was found and create a
4130          declaration for it. Eventually sets the @deprecated tag flag. */
4131       if (flag_emit_xref)
4132         lineno = EXPR_WFL_LINECOL (cl);
4133       else
4134         lineno = EXPR_WFL_LINENO (cl);
4135       field_decl = add_field (class_type, current_name, real_type, flags);
4136       CHECK_DEPRECATED (field_decl);
4137
4138       /* If the couple initializer/initialized is marked ARG_FINAL_P, we
4139          mark the created field FIELD_LOCAL_ALIAS, so that we can 
4140          hide parameters to this inner class $finit$ and constructors. */
4141       if (ARG_FINAL_P (current))
4142         FIELD_LOCAL_ALIAS (field_decl) = 1;
4143       
4144       /* Check if we must chain. */
4145       if (must_chain)
4146         register_incomplete_type (JDEP_FIELD, wfl, field_decl, type);
4147           
4148       /* If we have an initialization value tied to the field */
4149       if (init)
4150         {
4151           /* The field is declared static */
4152           if (flags & ACC_STATIC)
4153             {
4154               /* We include the field and its initialization part into
4155                  a list used to generate <clinit>. After <clinit> is
4156                  walked, field initializations will be processed and
4157                  fields initialized with known constants will be taken
4158                  out of <clinit> and have their DECL_INITIAL set
4159                  appropriately. */
4160               TREE_CHAIN (init) = CPC_STATIC_INITIALIZER_STMT (ctxp);
4161               SET_CPC_STATIC_INITIALIZER_STMT (ctxp, init);
4162               if (TREE_OPERAND (init, 1) 
4163                   && TREE_CODE (TREE_OPERAND (init, 1)) == NEW_ARRAY_INIT)
4164                 TREE_STATIC (TREE_OPERAND (init, 1)) = 1;
4165             }
4166           /* A non-static field declared with an immediate initialization is
4167              to be initialized in <init>, if any.  This field is remembered
4168              to be processed at the time of the generation of <init>. */
4169           else
4170             {
4171               TREE_CHAIN (init) = CPC_INITIALIZER_STMT (ctxp);
4172               SET_CPC_INITIALIZER_STMT (ctxp, init);
4173             }
4174           MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
4175           DECL_INITIAL (field_decl) = TREE_OPERAND (init, 1);
4176         }
4177     }
4178   lineno = saved_lineno;
4179 }
4180
4181 /* Generate $finit$, using the list of initialized fields to populate
4182    its body. $finit$'s parameter(s) list is adjusted to include the
4183    one(s) used to initialized the field(s) caching outer context
4184    local(s). */
4185
4186 static tree
4187 generate_finit (class_type)
4188      tree class_type;
4189 {
4190   int count = 0;
4191   tree list = TYPE_FINIT_STMT_LIST (class_type);
4192   tree mdecl, current, parms;
4193
4194   parms = build_alias_initializer_parameter_list (AIPL_FUNCTION_CREATION, 
4195                                                   class_type, NULL_TREE, 
4196                                                   &count);
4197   CRAFTED_PARAM_LIST_FIXUP (parms);
4198   mdecl = create_artificial_method (class_type, ACC_PRIVATE, void_type_node,
4199                                     finit_identifier_node, parms);
4200   fix_method_argument_names (parms, mdecl);
4201   layout_class_method (class_type, CLASSTYPE_SUPER (class_type),
4202                        mdecl, NULL_TREE);
4203   DECL_FUNCTION_NAP (mdecl) = count;
4204   start_artificial_method_body (mdecl);
4205
4206   for (current = list; current; current = TREE_CHAIN (current))
4207     java_method_add_stmt (mdecl, 
4208                           build_debugable_stmt (EXPR_WFL_LINECOL (current), 
4209                                                 current));
4210   end_artificial_method_body (mdecl);
4211   return mdecl;
4212 }
4213
4214 static void
4215 add_instance_initializer (mdecl)
4216      tree mdecl;
4217 {
4218   tree current;
4219   tree stmt_list = TYPE_II_STMT_LIST (DECL_CONTEXT (mdecl));
4220   tree compound = NULL_TREE;
4221
4222   if (stmt_list)
4223     {
4224       for (current = stmt_list; current; current = TREE_CHAIN (current))
4225         compound = add_stmt_to_compound (compound, NULL_TREE, current);
4226
4227       java_method_add_stmt (mdecl, build1 (INSTANCE_INITIALIZERS_EXPR,
4228                                            NULL_TREE, compound));
4229     }
4230 }
4231
4232 /* Shared accros method_declarator and method_header to remember the
4233    patch stage that was reached during the declaration of the method.
4234    A method DECL is built differently is there is no patch
4235    (JDEP_NO_PATCH) or a patch (JDEP_METHOD or JDEP_METHOD_RETURN)
4236    pending on the currently defined method.  */
4237
4238 static int patch_stage;
4239
4240 /* Check the method declaration and add the method to its current
4241    class.  If the argument list is known to contain incomplete types,
4242    the method is partially added and the registration will be resume
4243    once the method arguments resolved. If TYPE is NULL, we're dealing
4244    with a constructor.  */
4245
4246 static tree
4247 method_header (flags, type, mdecl, throws)
4248      int flags;
4249      tree type, mdecl, throws;
4250 {
4251   tree meth = TREE_VALUE (mdecl);
4252   tree id = TREE_PURPOSE (mdecl);
4253   tree type_wfl = NULL_TREE;
4254   tree meth_name = NULL_TREE;
4255   tree current, orig_arg, this_class = NULL;
4256   int saved_lineno;
4257   int constructor_ok = 0, must_chain;
4258   int count;
4259   
4260   check_modifiers_consistency (flags);
4261
4262   if (GET_CPC ())
4263     this_class = TREE_TYPE (GET_CPC ());
4264
4265   if (!this_class || this_class == error_mark_node)
4266     return NULL_TREE;
4267   
4268   /* There are some forbidden modifiers for an abstract method and its
4269      class must be abstract as well.  */
4270   if (type && (flags & ACC_ABSTRACT))
4271     {
4272       ABSTRACT_CHECK (flags, ACC_PRIVATE, id, "Private");
4273       ABSTRACT_CHECK (flags, ACC_STATIC, id, "Static");
4274       ABSTRACT_CHECK (flags, ACC_FINAL, id, "Final");
4275       ABSTRACT_CHECK (flags, ACC_NATIVE, id, "Native");
4276       ABSTRACT_CHECK (flags, ACC_SYNCHRONIZED,id, "Synchronized");
4277       if (!CLASS_ABSTRACT (TYPE_NAME (this_class))
4278           && !CLASS_INTERFACE (TYPE_NAME (this_class)))
4279         parse_error_context 
4280           (id, "Class `%s' must be declared abstract to define abstract method `%s'", 
4281            IDENTIFIER_POINTER (DECL_NAME (ctxp->current_parsed_class)),
4282            IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
4283     }
4284
4285   /* Things to be checked when declaring a constructor */
4286   if (!type)
4287     {
4288       int ec = java_error_count;
4289       /* 8.6: Constructor declarations: we might be trying to define a
4290          method without specifying a return type. */
4291       if (EXPR_WFL_NODE (id) != GET_CPC_UN ())
4292         parse_error_context 
4293           (id, "Invalid method declaration, return type required");
4294       /* 8.6.3: Constructor modifiers */
4295       else
4296         {
4297           JCONSTRUCTOR_CHECK (flags, ACC_ABSTRACT, id, "abstract");
4298           JCONSTRUCTOR_CHECK (flags, ACC_STATIC, id, "static");
4299           JCONSTRUCTOR_CHECK (flags, ACC_FINAL, id, "final");
4300           JCONSTRUCTOR_CHECK (flags, ACC_NATIVE, id, "native");
4301           JCONSTRUCTOR_CHECK (flags, ACC_SYNCHRONIZED, id, "synchronized");
4302         }
4303       /* If we found error here, we don't consider it's OK to tread
4304          the method definition as a constructor, for the rest of this
4305          function */
4306       if (ec == java_error_count)
4307         constructor_ok = 1;
4308     }
4309
4310   /* Method declared within the scope of an interface are implicitly
4311      abstract and public. Conflicts with other erroneously provided
4312      modifiers are checked right after. */
4313
4314   if (CLASS_INTERFACE (TYPE_NAME (this_class)))
4315     {
4316       /* If FLAGS isn't set because of a modifier, turn the
4317          corresponding modifier WFL to NULL so we issue a warning on
4318          the obsolete use of the modifier */
4319       if (!(flags & ACC_PUBLIC))
4320         MODIFIER_WFL (PUBLIC_TK) = NULL;
4321       if (!(flags & ACC_ABSTRACT))
4322         MODIFIER_WFL (ABSTRACT_TK) = NULL;
4323       flags |= ACC_PUBLIC;
4324       flags |= ACC_ABSTRACT;
4325     }
4326
4327   /* Inner class can't declare static methods */
4328   if ((flags & ACC_STATIC) && !TOPLEVEL_CLASS_TYPE_P (this_class))
4329     {
4330       parse_error_context 
4331         (id, "Method `%s' can't be static in inner class `%s'. Only members of interfaces and top-level classes can be static",
4332          IDENTIFIER_POINTER (EXPR_WFL_NODE (id)),
4333          lang_printable_name (this_class, 0));
4334     }
4335
4336   /* Modifiers context reset moved up, so abstract method declaration
4337      modifiers can be later checked.  */
4338
4339   /* Set constructor returned type to void and method name to <init>,
4340      unless we found an error identifier the constructor (in which
4341      case we retain the original name) */
4342   if (!type)
4343     {
4344       type = void_type_node;
4345       if (constructor_ok)
4346         meth_name = init_identifier_node;
4347     }
4348   else
4349     meth_name = EXPR_WFL_NODE (id);
4350
4351   /* Do the returned type resolution and registration if necessary */
4352   SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
4353
4354   if (meth_name)
4355     type = build_array_from_name (type, type_wfl, meth_name, &meth_name);
4356   EXPR_WFL_NODE (id) = meth_name;
4357   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4358
4359   if (must_chain)
4360     {
4361       patch_stage = JDEP_METHOD_RETURN;
4362       register_incomplete_type (patch_stage, type_wfl, id, type);
4363       TREE_TYPE (meth) = GET_REAL_TYPE (type);
4364     }
4365   else
4366     TREE_TYPE (meth) = type;
4367
4368   saved_lineno = lineno;
4369   /* When defining an abstract or interface method, the curly
4370      bracket at level 1 doesn't exist because there is no function
4371      body */
4372   lineno = (ctxp->first_ccb_indent1 ? ctxp->first_ccb_indent1 : 
4373             EXPR_WFL_LINENO (id));
4374
4375   /* Remember the original argument list */
4376   orig_arg = TYPE_ARG_TYPES (meth);
4377
4378   if (patch_stage)              /* includes ret type and/or all args */
4379     {
4380       jdep *jdep;
4381       meth = add_method_1 (this_class, flags, meth_name, meth);
4382       /* Patch for the return type */
4383       if (patch_stage == JDEP_METHOD_RETURN)
4384         {
4385           jdep = CLASSD_LAST (ctxp->classd_list);
4386           JDEP_GET_PATCH (jdep) = &TREE_TYPE (TREE_TYPE (meth));
4387         }
4388       /* This is the stop JDEP. METH allows the function's signature
4389          to be computed. */
4390       register_incomplete_type (JDEP_METHOD_END, NULL_TREE, meth, NULL_TREE);
4391     }
4392   else
4393     meth = add_method (this_class, flags, meth_name, 
4394                        build_java_signature (meth));
4395
4396   /* Remember final parameters */
4397   MARK_FINAL_PARMS (meth, orig_arg);
4398
4399   /* Fix the method argument list so we have the argument name
4400      information */
4401   fix_method_argument_names (orig_arg, meth);
4402
4403   /* Register the parameter number and re-install the current line
4404      number */
4405   DECL_MAX_LOCALS (meth) = ctxp->formal_parameter_number+1;
4406   lineno = saved_lineno;
4407
4408   /* Register exception specified by the `throws' keyword for
4409      resolution and set the method decl appropriate field to the list.
4410      Note: the grammar ensures that what we get here are class
4411      types. */
4412   if (throws)
4413     {
4414       throws = nreverse (throws);
4415       for (current = throws; current; current = TREE_CHAIN (current))
4416         {
4417           register_incomplete_type (JDEP_EXCEPTION, TREE_VALUE (current),
4418                                     NULL_TREE, NULL_TREE);
4419           JDEP_GET_PATCH (CLASSD_LAST (ctxp->classd_list)) = 
4420             &TREE_VALUE (current);
4421         }
4422       DECL_FUNCTION_THROWS (meth) = throws;
4423     }
4424
4425   /* We set the DECL_NAME to ID so we can track the location where
4426      the function was declared. This allow us to report
4427      redefinition error accurately. When method are verified,
4428      DECL_NAME is reinstalled properly (using the content of the
4429      WFL node ID) (see check_method_redefinition). We don't do that
4430      when Object is being defined. Constructor <init> names will be
4431      reinstalled the same way. */
4432   if (TREE_TYPE (GET_CPC ()) != object_type_node)
4433     DECL_NAME (meth) = id;
4434
4435   /* Set the flag if we correctly processed a constructor */
4436   if (constructor_ok)
4437     {
4438       DECL_CONSTRUCTOR_P (meth) = 1;
4439       /* Compute and store the number of artificial parameters declared
4440          for this constructor */
4441       for (count = 0, current = TYPE_FIELDS (this_class); current; 
4442            current = TREE_CHAIN (current))
4443         if (FIELD_LOCAL_ALIAS (current))
4444           count++;
4445       DECL_FUNCTION_NAP (meth) = count;
4446     }
4447
4448   /* Eventually set the @deprecated tag flag */
4449   CHECK_DEPRECATED (meth);
4450
4451   /* If doing xref, store column and line number information instead
4452      of the line number only. */
4453   if (flag_emit_xref)
4454     DECL_SOURCE_LINE (meth) = EXPR_WFL_LINECOL (id);
4455
4456   return meth;
4457 }
4458
4459 static void
4460 fix_method_argument_names (orig_arg, meth)
4461     tree orig_arg, meth;
4462 {
4463   tree arg = TYPE_ARG_TYPES (TREE_TYPE (meth));
4464   if (TREE_CODE (TREE_TYPE (meth)) == METHOD_TYPE)
4465     {
4466       TREE_PURPOSE (arg) = this_identifier_node;
4467       arg = TREE_CHAIN (arg);
4468     }
4469   while (orig_arg != end_params_node)
4470     {
4471       TREE_PURPOSE (arg) = TREE_PURPOSE (orig_arg);
4472       orig_arg = TREE_CHAIN (orig_arg);
4473       arg = TREE_CHAIN (arg);
4474     }
4475 }
4476
4477 /* Complete the method declaration with METHOD_BODY.  */
4478
4479 static void
4480 finish_method_declaration (method_body)
4481      tree method_body;
4482 {
4483   int flags;
4484
4485   if (!current_function_decl)
4486     return;
4487
4488   flags = get_access_flags_from_decl (current_function_decl);
4489
4490   /* 8.4.5 Method Body */
4491   if ((flags & ACC_ABSTRACT || flags & ACC_NATIVE) && method_body)
4492     {
4493       tree wfl = DECL_NAME (current_function_decl);
4494       parse_error_context (wfl, 
4495                            "%s method `%s' can't have a body defined",
4496                            (METHOD_NATIVE (current_function_decl) ?
4497                             "Native" : "Abstract"),
4498                            IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
4499       method_body = NULL_TREE;
4500     }
4501   else if (!(flags & ACC_ABSTRACT) && !(flags & ACC_NATIVE) && !method_body)
4502     {
4503       tree wfl = DECL_NAME (current_function_decl);
4504       parse_error_context
4505         (wfl, 
4506          "Non native and non abstract method `%s' must have a body defined",
4507          IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
4508       method_body = NULL_TREE;
4509     }
4510
4511   if (flag_emit_class_files && method_body 
4512       && TREE_CODE (method_body) == NOP_EXPR 
4513       && TREE_TYPE (current_function_decl) 
4514       && TREE_TYPE (TREE_TYPE (current_function_decl)) == void_type_node)
4515     method_body = build1 (RETURN_EXPR, void_type_node, NULL);
4516
4517   BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (current_function_decl)) = method_body;
4518   maybe_absorb_scoping_blocks ();
4519   /* Exit function's body */
4520   exit_block ();
4521   /* Merge last line of the function with first line, directly in the
4522      function decl. It will be used to emit correct debug info. */
4523   if (!flag_emit_xref)
4524     DECL_SOURCE_LINE_MERGE (current_function_decl, ctxp->last_ccb_indent1);
4525
4526   /* Since function's argument's list are shared, reset the
4527      ARG_FINAL_P parameter that might have been set on some of this
4528      function parameters. */
4529   UNMARK_FINAL_PARMS (current_function_decl);
4530   
4531   /* So we don't have an irrelevant function declaration context for
4532      the next static block we'll see. */
4533   current_function_decl = NULL_TREE;
4534 }
4535
4536 /* Build a an error message for constructor circularity errors.  */
4537
4538 static char *
4539 constructor_circularity_msg (from, to)
4540      tree from, to;
4541 {
4542   static char string [4096];
4543   char *t = xstrdup (lang_printable_name (from, 0));
4544   sprintf (string, "`%s' invokes `%s'", t, lang_printable_name (to, 0));
4545   free (t);
4546   return string;
4547 }
4548
4549 /* Verify a circular call to METH. Return 1 if an error is found, 0
4550    otherwise.  */
4551
4552 static int
4553 verify_constructor_circularity (meth, current)
4554      tree meth, current;
4555 {
4556   static tree list = NULL_TREE;
4557   tree c;
4558   for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
4559     {
4560       if (TREE_VALUE (c) == meth)
4561         {
4562           char *t;
4563           if (list)
4564             {
4565               tree liste;
4566               list = nreverse (list);
4567               for (liste = list; liste; liste = TREE_CHAIN (liste))
4568                 {
4569                   parse_error_context 
4570                     (TREE_PURPOSE (TREE_PURPOSE (liste)), "%s",
4571                      constructor_circularity_msg
4572                       (TREE_VALUE (liste), TREE_VALUE (TREE_PURPOSE (liste)))); 
4573                   java_error_count--;
4574                 }
4575             }
4576           t = xstrdup (lang_printable_name (meth, 0));
4577           parse_error_context (TREE_PURPOSE (c), 
4578                                "%s: recursive invocation of constructor `%s'",
4579                                constructor_circularity_msg (current, meth), t);
4580           free (t);
4581           list = NULL_TREE;
4582           return 1;
4583         }
4584     }
4585   for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
4586     {
4587       list = tree_cons (c, current, list);
4588       if (verify_constructor_circularity (meth, TREE_VALUE (c)))
4589         return 1;
4590       list = TREE_CHAIN (list);
4591     }
4592   return 0;
4593 }
4594
4595 /* Check modifiers that can be declared but exclusively */
4596
4597 static void
4598 check_modifiers_consistency (flags)
4599      int flags;
4600 {
4601   int acc_count = 0;
4602   tree cl = NULL_TREE;
4603
4604   THIS_MODIFIER_ONLY (flags, ACC_PUBLIC, PUBLIC_TK, acc_count, cl);
4605   THIS_MODIFIER_ONLY (flags, ACC_PRIVATE, PRIVATE_TK, acc_count, cl);
4606   THIS_MODIFIER_ONLY (flags, ACC_PROTECTED, PROTECTED_TK, acc_count, cl);
4607   if (acc_count > 1)
4608     parse_error_context
4609       (cl, "Inconsistent member declaration.  At most one of `public', `private', or `protected' may be specified");
4610
4611   acc_count = 0;
4612   cl = NULL_TREE;
4613   THIS_MODIFIER_ONLY (flags, ACC_FINAL, FINAL_TK - PUBLIC_TK,
4614                       acc_count, cl);
4615   THIS_MODIFIER_ONLY (flags, ACC_VOLATILE, VOLATILE_TK - PUBLIC_TK,
4616                       acc_count, cl);
4617   if (acc_count > 1)
4618     parse_error_context (cl,
4619                          "Inconsistent member declaration.  At most one of `final' or `volatile' may be specified");
4620 }
4621
4622 /* Check the methode header METH for abstract specifics features */
4623
4624 static void
4625 check_abstract_method_header (meth)
4626      tree meth;
4627 {
4628   int flags = get_access_flags_from_decl (meth);
4629   /* DECL_NAME might still be a WFL node */
4630   tree name = GET_METHOD_NAME (meth);
4631
4632   OBSOLETE_MODIFIER_WARNING2 (MODIFIER_WFL (ABSTRACT_TK), flags,
4633                               ACC_ABSTRACT, "abstract method",
4634                               IDENTIFIER_POINTER (name));
4635   OBSOLETE_MODIFIER_WARNING2 (MODIFIER_WFL (PUBLIC_TK), flags, 
4636                               ACC_PUBLIC, "abstract method",
4637                               IDENTIFIER_POINTER (name));
4638
4639   check_modifiers ("Illegal modifier `%s' for interface method",
4640                   flags, INTERFACE_METHOD_MODIFIERS);
4641 }
4642
4643 /* Create a FUNCTION_TYPE node and start augmenting it with the
4644    declared function arguments. Arguments type that can't be resolved
4645    are left as they are, but the returned node is marked as containing
4646    incomplete types.  */
4647
4648 static tree
4649 method_declarator (id, list)
4650      tree id, list;
4651 {
4652   tree arg_types = NULL_TREE, current, node;
4653   tree meth = make_node (FUNCTION_TYPE);
4654   jdep *jdep;
4655
4656   patch_stage = JDEP_NO_PATCH;
4657
4658   /* If we're dealing with an inner class constructor, we hide the
4659      this$<n> decl in the name field of its parameter declaration.  We
4660      also might have to hide the outer context local alias
4661      initializers. Not done when the class is a toplevel class. */
4662   if (PURE_INNER_CLASS_DECL_P (GET_CPC ()) 
4663       && EXPR_WFL_NODE (id) == GET_CPC_UN ())
4664     {
4665       tree aliases_list, type, thisn;
4666       /* First the aliases, linked to the regular parameters */
4667       aliases_list =
4668         build_alias_initializer_parameter_list (AIPL_FUNCTION_DECLARATION, 
4669                                                 TREE_TYPE (GET_CPC ()),
4670                                                 NULL_TREE, NULL);
4671       list = chainon (nreverse (aliases_list), list);
4672
4673       /* Then this$<n> */
4674       type = TREE_TYPE (DECL_CONTEXT (GET_CPC ()));
4675       thisn = build_current_thisn (TYPE_NAME (GET_CPC ()));
4676       list = tree_cons (build_wfl_node (thisn), build_pointer_type (type),
4677                         list);
4678     }
4679   
4680   for (current = list; current; current = TREE_CHAIN (current))
4681     {
4682       int must_chain = 0;
4683       tree wfl_name = TREE_PURPOSE (current);
4684       tree type = TREE_VALUE (current);
4685       tree name = EXPR_WFL_NODE (wfl_name);
4686       tree already, arg_node;
4687       tree type_wfl = NULL_TREE;
4688       tree real_type;
4689
4690       /* Obtain a suitable type for resolution, if necessary */
4691       SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
4692
4693       /* Process NAME, as it may specify extra dimension(s) for it */
4694       type = build_array_from_name (type, type_wfl, name, &name);
4695       EXPR_WFL_NODE (wfl_name) = name;
4696
4697       real_type = GET_REAL_TYPE (type);
4698       if (TREE_CODE (real_type) == RECORD_TYPE)
4699         {
4700           real_type = promote_type (real_type);
4701           if (TREE_CODE (type) == TREE_LIST)
4702             TREE_PURPOSE (type) = real_type;
4703         }
4704
4705       /* Check redefinition */
4706       for (already = arg_types; already; already = TREE_CHAIN (already))
4707         if (TREE_PURPOSE (already) == name)
4708           {
4709             parse_error_context
4710               (wfl_name, "Variable `%s' is used more than once in the argument list of method `%s'",
4711                IDENTIFIER_POINTER (name),
4712                IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
4713             break;
4714           }
4715
4716       /* If we've an incomplete argument type, we know there is a location
4717          to patch when the type get resolved, later.  */
4718       jdep = NULL;
4719       if (must_chain)
4720         {
4721           patch_stage = JDEP_METHOD;
4722           type = register_incomplete_type (patch_stage, 
4723                                            type_wfl, wfl_name, type);
4724           jdep = CLASSD_LAST (ctxp->classd_list);
4725           JDEP_MISC (jdep) = id;
4726         }
4727
4728       /* The argument node: a name and a (possibly) incomplete type.  */
4729       arg_node = build_tree_list (name, real_type);
4730       /* Remeber arguments declared final. */
4731       ARG_FINAL_P (arg_node) = ARG_FINAL_P (current);
4732       
4733       if (jdep)
4734         JDEP_GET_PATCH (jdep) = &TREE_VALUE (arg_node);
4735       TREE_CHAIN (arg_node) = arg_types;
4736       arg_types = arg_node;
4737     }
4738   TYPE_ARG_TYPES (meth) = chainon (nreverse (arg_types), end_params_node);
4739   node = build_tree_list (id, meth);
4740   return node;
4741 }
4742
4743 static int
4744 unresolved_type_p (wfl, returned)
4745      tree wfl;
4746      tree *returned;
4747      
4748 {
4749   if (TREE_CODE (wfl) == EXPR_WITH_FILE_LOCATION)
4750     {
4751       if (returned)
4752         {
4753           tree decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (wfl));
4754           if (decl && current_class && (decl == TYPE_NAME (current_class)))
4755             *returned = TREE_TYPE (decl);
4756           else if (GET_CPC_UN () == EXPR_WFL_NODE (wfl))
4757             *returned = TREE_TYPE (GET_CPC ());
4758           else
4759             *returned = NULL_TREE;
4760         }
4761       return 1;
4762     }
4763   if (returned)
4764     *returned = wfl;
4765   return 0;
4766 }
4767
4768 /* From NAME, build a qualified identifier node using the
4769    qualification from the current package definition. */
4770
4771 static tree
4772 parser_qualified_classname (is_static, name)
4773      int is_static;
4774      tree name;
4775 {
4776   tree nested_class_name;
4777
4778   if (!is_static 
4779       && (nested_class_name = maybe_make_nested_class_name (name)))
4780     return nested_class_name;
4781
4782   if (ctxp->package)
4783     return merge_qualified_name (ctxp->package, name);
4784   else 
4785     return name;
4786 }
4787
4788 /* Called once the type a interface extends is resolved. Returns 0 if
4789    everything is OK.  */
4790
4791 static int
4792 parser_check_super_interface (super_decl, this_decl, this_wfl)
4793      tree super_decl, this_decl, this_wfl;
4794 {
4795   tree super_type = TREE_TYPE (super_decl);
4796
4797   /* Has to be an interface */
4798   if (!CLASS_INTERFACE (super_decl))
4799     {
4800       parse_error_context 
4801         (this_wfl, "Can't use %s `%s' to implement/extend %s `%s'",
4802          (TYPE_ARRAY_P (super_type) ? "array" : "class"),
4803          IDENTIFIER_POINTER (DECL_NAME (super_decl)),
4804          (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (this_decl))) ? 
4805           "interface" : "class"),
4806          IDENTIFIER_POINTER (DECL_NAME (this_decl)));
4807       return 1;
4808     }
4809
4810   /* Check scope: same package OK, other package: OK if public */
4811   if (check_pkg_class_access (DECL_NAME (super_decl), lookup_cl (this_decl)))
4812     return 1;
4813
4814   SOURCE_FRONTEND_DEBUG (("Completing interface %s with %s",
4815                           IDENTIFIER_POINTER (DECL_NAME (this_decl)),
4816                           IDENTIFIER_POINTER (DECL_NAME (super_decl))));
4817   return 0;
4818 }
4819
4820 /* Makes sure that SUPER_DECL is suitable to extend THIS_DECL. Returns
4821    0 if everthing is OK.  */
4822
4823 static int
4824 parser_check_super (super_decl, this_decl, wfl)
4825      tree super_decl, this_decl, wfl;
4826 {
4827   tree super_type = TREE_TYPE (super_decl);
4828
4829   /* SUPER should be a CLASS (neither an array nor an interface) */
4830   if (TYPE_ARRAY_P (super_type) || CLASS_INTERFACE (TYPE_NAME (super_type)))
4831     {
4832       parse_error_context 
4833         (wfl, "Class `%s' can't subclass %s `%s'",
4834          IDENTIFIER_POINTER (DECL_NAME (this_decl)),
4835          (CLASS_INTERFACE (TYPE_NAME (super_type)) ? "interface" : "array"),
4836          IDENTIFIER_POINTER (DECL_NAME (super_decl)));
4837       return 1;
4838     }
4839
4840   if (CLASS_FINAL (TYPE_NAME (super_type)))
4841     {
4842       parse_error_context (wfl, "Can't subclass final classes: %s",
4843                            IDENTIFIER_POINTER (DECL_NAME (super_decl)));
4844       return 1;
4845     }
4846
4847   /* Check scope: same package OK, other package: OK if public */
4848   if (check_pkg_class_access (DECL_NAME (super_decl), wfl))
4849     return 1;
4850   
4851   SOURCE_FRONTEND_DEBUG (("Completing class %s with %s",
4852                           IDENTIFIER_POINTER (DECL_NAME (this_decl)),
4853                           IDENTIFIER_POINTER (DECL_NAME (super_decl))));
4854   return 0;
4855 }
4856
4857 /* Create a new dependency list and link it (in a LIFO manner) to the
4858    CTXP list of type dependency list.  */
4859
4860 static void
4861 create_jdep_list (ctxp)
4862      struct parser_ctxt *ctxp;
4863 {
4864   jdeplist *new = (jdeplist *)xmalloc (sizeof (jdeplist));      
4865   new->first = new->last = NULL;
4866   new->next = ctxp->classd_list;
4867   ctxp->classd_list = new;
4868 }
4869
4870 static jdeplist *
4871 reverse_jdep_list (ctxp)
4872      struct parser_ctxt *ctxp;
4873 {
4874   register jdeplist *prev = NULL, *current, *next;
4875   for (current = ctxp->classd_list; current; current = next)
4876     {
4877       next = current->next;
4878       current->next = prev;
4879       prev = current;
4880     }
4881   return prev;
4882 }
4883
4884 /* Create a fake pointer based on the ID stored in
4885    TYPE_NAME. TYPE_NAME can be a WFL or a incomplete type asking to be
4886    registered again. */
4887
4888 static tree
4889 obtain_incomplete_type (type_name)
4890      tree type_name;
4891 {
4892   tree ptr, name;
4893
4894   if (TREE_CODE (type_name) == EXPR_WITH_FILE_LOCATION)
4895     name = EXPR_WFL_NODE (type_name);
4896   else if (INCOMPLETE_TYPE_P (type_name))
4897     name = TYPE_NAME (type_name);
4898   else
4899     fatal ("invalid type name - obtain_incomplete_type");
4900
4901   for (ptr = ctxp->incomplete_class; ptr; ptr = TREE_CHAIN (ptr))
4902     if (TYPE_NAME (ptr) == name)
4903       break;
4904
4905   if (!ptr)
4906     {
4907       push_obstacks (&permanent_obstack, &permanent_obstack);
4908       BUILD_PTR_FROM_NAME (ptr, name);
4909       layout_type (ptr);
4910       pop_obstacks ();
4911       TREE_CHAIN (ptr) = ctxp->incomplete_class;
4912       ctxp->incomplete_class = ptr;
4913     }
4914
4915   return ptr;
4916 }
4917
4918 /* Register a incomplete type whose name is WFL. Reuse PTR if PTR is
4919    non NULL instead of computing a new fake type based on WFL. The new
4920    dependency is inserted in the current type dependency list, in FIFO
4921    manner.  */
4922
4923 static tree
4924 register_incomplete_type (kind, wfl, decl, ptr)
4925      int kind;
4926      tree wfl, decl, ptr;
4927 {
4928   jdep *new = (jdep *)xmalloc (sizeof (jdep));
4929
4930   if (!ptr && kind != JDEP_METHOD_END) /* JDEP_METHOD_END is a mere marker */
4931     ptr = obtain_incomplete_type (wfl);
4932
4933   JDEP_KIND (new) = kind;
4934   JDEP_DECL (new) = decl;
4935   JDEP_SOLV (new) = ptr;
4936   JDEP_WFL (new) = wfl;
4937   JDEP_CHAIN (new) = NULL;
4938   JDEP_MISC (new) = NULL_TREE;
4939   /* For some dependencies, set the enclosing class of the current
4940      class to be the enclosing context */
4941   if ((kind == JDEP_SUPER || kind == JDEP_INTERFACE || kind == JDEP_ANONYMOUS)
4942       && GET_ENCLOSING_CPC ())
4943     JDEP_ENCLOSING (new) = TREE_VALUE (GET_ENCLOSING_CPC ());
4944   else
4945     JDEP_ENCLOSING (new) = GET_CPC ();
4946   JDEP_GET_PATCH (new) = (tree *)NULL;
4947
4948   JDEP_INSERT (ctxp->classd_list, new);
4949
4950   return ptr;
4951 }
4952
4953 void
4954 java_check_circular_reference ()
4955 {
4956   tree current;
4957   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
4958     {
4959       tree type = TREE_TYPE (current);
4960       if (CLASS_INTERFACE (current))
4961         {
4962           /* Check all interfaces this class extends */
4963           tree basetype_vec = TYPE_BINFO_BASETYPES (type);
4964           int n, i;
4965
4966           if (!basetype_vec)
4967             return;
4968           n = TREE_VEC_LENGTH (basetype_vec);
4969           for (i = 0; i < n; i++)
4970             {
4971               tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
4972               if (vec_elt && BINFO_TYPE (vec_elt) != object_type_node 
4973                   && interface_of_p (type, BINFO_TYPE (vec_elt)))
4974                 parse_error_context (lookup_cl (current),
4975                                      "Cyclic interface inheritance");
4976             }
4977         }
4978       else
4979         if (inherits_from_p (CLASSTYPE_SUPER (type), type))
4980           parse_error_context (lookup_cl (current), 
4981                                "Cyclic class inheritance%s",
4982                                (cyclic_inheritance_report ?
4983                                 cyclic_inheritance_report : ""));
4984     }
4985 }
4986
4987 /* Augment the parameter list PARM with parameters crafted to
4988    initialize outer context locals aliases. Through ARTIFICIAL, a
4989    count is kept of the number of crafted parameters. MODE governs
4990    what eventually gets created: something suitable for a function
4991    creation or a function invocation, either the constructor or
4992    $finit$.  */
4993
4994 static tree
4995 build_alias_initializer_parameter_list (mode, class_type, parm, artificial)
4996     int mode;
4997     tree class_type, parm;
4998     int *artificial;
4999 {
5000   tree field;
5001   for (field = TYPE_FIELDS (class_type); field; field = TREE_CHAIN (field))
5002     if (FIELD_LOCAL_ALIAS (field))
5003       {
5004         char *buffer = IDENTIFIER_POINTER (DECL_NAME (field));
5005         tree purpose = NULL_TREE, value = NULL_TREE, name = NULL_TREE;
5006
5007         switch (mode)
5008           {
5009           case AIPL_FUNCTION_DECLARATION:
5010             MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (buffer, &buffer [4]);
5011             purpose = build_wfl_node (get_identifier (buffer));
5012             if (TREE_CODE (TREE_TYPE (field)) == POINTER_TYPE)
5013               value = build_wfl_node (TYPE_NAME (TREE_TYPE (field)));
5014             else
5015               value = TREE_TYPE (field);
5016             break;
5017
5018           case AIPL_FUNCTION_CREATION:
5019             MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (buffer, &buffer [4]);
5020             purpose = get_identifier (buffer);
5021             value = TREE_TYPE (field);
5022             break;
5023
5024           case AIPL_FUNCTION_FINIT_INVOCATION:
5025             MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (buffer, &buffer [4]);
5026             /* Now, this is wrong. purpose should always be the NAME
5027                of something and value its matching value (decl, type,
5028                etc...) FIXME -- but there is a lot to fix. */
5029
5030             /* When invoked for this kind of operation, we already
5031                know whether a field is used or not. */
5032             purpose = TREE_TYPE (field);
5033             value = build_wfl_node (get_identifier (buffer));
5034             break;
5035
5036           case AIPL_FUNCTION_CTOR_INVOCATION:
5037             /* There are two case: the constructor invokation happends
5038                outside the local inner, in which case, locales from the outer
5039                context are directly used.
5040
5041                Otherwise, we fold to using the alias directly. */
5042             if (class_type == current_class)
5043               value = field;
5044             else
5045               {
5046                 name = get_identifier (&buffer[4]);
5047                 value = IDENTIFIER_LOCAL_VALUE (name);
5048               }
5049             break;
5050           }
5051         parm = tree_cons (purpose, value, parm);
5052         if (artificial)
5053           *artificial +=1;
5054       }
5055   return parm;
5056 }
5057
5058 /* Craft a constructor for CLASS_DECL -- what we should do when none
5059    where found. ARGS is non NULL when a special signature must be
5060    enforced. This is the case for anonymous classes.  */
5061
5062 static void
5063 craft_constructor (class_decl, args)
5064      tree class_decl, args;
5065 {
5066   tree class_type = TREE_TYPE (class_decl);
5067   tree parm = NULL_TREE;
5068   int flags = (get_access_flags_from_decl (class_decl) & ACC_PUBLIC ?
5069                ACC_PUBLIC : 0);
5070   int i = 0, artificial = 0;
5071   tree decl, ctor_name;
5072   char buffer [80];
5073   
5074   push_obstacks (&permanent_obstack, &permanent_obstack);
5075
5076   /* The constructor name is <init> unless we're dealing with an
5077      anonymous class, in which case the name will be fixed after having
5078      be expanded. */
5079   if (ANONYMOUS_CLASS_P (class_type))
5080     ctor_name = DECL_NAME (class_decl);
5081   else
5082     ctor_name = init_identifier_node;
5083
5084   /* If we're dealing with an inner class constructor, we hide the
5085      this$<n> decl in the name field of its parameter declaration. */
5086   if (PURE_INNER_CLASS_TYPE_P (class_type))
5087     {
5088       tree type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class_type)));
5089       parm = tree_cons (build_current_thisn (class_type),
5090                         build_pointer_type (type), parm);
5091
5092       /* Some more arguments to be hidden here. The values of the local
5093          variables of the outer context that the inner class needs to see. */
5094       parm = build_alias_initializer_parameter_list (AIPL_FUNCTION_CREATION,
5095                                                      class_type, parm, 
5096                                                      &artificial);
5097     }
5098
5099   /* Then if there are any args to be enforced, enforce them now */
5100   for (; args && args != end_params_node; args = TREE_CHAIN (args))
5101     {
5102       sprintf (buffer, "parm%d", i++);
5103       parm = tree_cons (get_identifier (buffer), TREE_VALUE (args), parm);
5104     }
5105
5106   CRAFTED_PARAM_LIST_FIXUP (parm);
5107   decl = create_artificial_method (class_type, flags, void_type_node, 
5108                                    ctor_name, parm);
5109   fix_method_argument_names (parm, decl);
5110   /* Now, mark the artificial parameters. */
5111   DECL_FUNCTION_NAP (decl) = artificial;
5112
5113   pop_obstacks ();
5114   DECL_CONSTRUCTOR_P (decl) = 1;
5115 }
5116
5117
5118 /* Fix the constructors. This will be called right after circular
5119    references have been checked. It is necessary to fix constructors
5120    early even if no code generation will take place for that class:
5121    some generated constructor might be required by the class whose
5122    compilation triggered this one to be simply loaded.  */
5123
5124 void
5125 java_fix_constructors ()
5126 {
5127   tree current;
5128
5129   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
5130     {
5131       tree class_type = TREE_TYPE (current);
5132       int saw_ctor = 0;
5133       tree decl;
5134
5135       if (CLASS_INTERFACE (TYPE_NAME (class_type)))
5136         continue;
5137
5138       for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
5139         {
5140           if (DECL_CONSTRUCTOR_P (decl))
5141             {
5142               fix_constructors (decl);
5143               saw_ctor = 1;
5144             }
5145         }
5146
5147       /* Anonymous class constructor can't be generated that early. */
5148       if (!saw_ctor && !ANONYMOUS_CLASS_P (class_type))
5149         craft_constructor (current, NULL_TREE);
5150     }
5151 }
5152
5153 /* safe_layout_class just makes sure that we can load a class without
5154    disrupting the current_class, input_file, lineno, etc, information
5155    about the class processed currently.  */
5156
5157 void
5158 safe_layout_class (class)
5159      tree class;
5160 {
5161   tree save_current_class = current_class;
5162   const char *save_input_filename = input_filename;
5163   int save_lineno = lineno;
5164
5165   push_obstacks (&permanent_obstack, &permanent_obstack);
5166
5167   layout_class (class);
5168   pop_obstacks ();
5169
5170   current_class = save_current_class;
5171   input_filename = save_input_filename;
5172   lineno = save_lineno;
5173   CLASS_LOADED_P (class) = 1;
5174 }
5175
5176 static tree
5177 jdep_resolve_class (dep)
5178      jdep *dep;
5179 {
5180   tree decl;
5181
5182   if (JDEP_RESOLVED_P (dep))
5183     decl = JDEP_RESOLVED_DECL (dep);
5184   else
5185     {
5186       decl = resolve_class (JDEP_ENCLOSING (dep), JDEP_TO_RESOLVE (dep),
5187                             JDEP_DECL (dep), JDEP_WFL (dep));
5188       JDEP_RESOLVED (dep, decl);
5189     }
5190     
5191   if (!decl)
5192     complete_class_report_errors (dep);
5193
5194   return decl;
5195 }
5196
5197 /* Complete unsatisfied class declaration and their dependencies */
5198
5199 void
5200 java_complete_class ()
5201 {
5202   tree cclass;
5203   jdeplist *cclassd;
5204   int error_found;
5205   tree type;
5206
5207   push_obstacks (&permanent_obstack, &permanent_obstack);
5208
5209   /* Process imports and reverse the import on demand list */
5210   process_imports ();
5211   if (ctxp->import_demand_list)
5212     ctxp->import_demand_list = nreverse (ctxp->import_demand_list);
5213
5214   /* Rever things so we have the right order */
5215   ctxp->class_list = nreverse (ctxp->class_list);
5216   ctxp->classd_list = reverse_jdep_list (ctxp);
5217
5218   for (cclassd = ctxp->classd_list, cclass = ctxp->class_list; 
5219        cclass && cclassd; 
5220        cclass = TREE_CHAIN (cclass), cclassd = CLASSD_CHAIN (cclassd))
5221     {
5222       jdep *dep;
5223       for (dep = CLASSD_FIRST (cclassd); dep; dep = JDEP_CHAIN (dep))
5224         {
5225           tree decl;
5226           if (!(decl = jdep_resolve_class (dep)))
5227             continue;
5228
5229           /* Now it's time to patch */
5230           switch (JDEP_KIND (dep))
5231             {
5232             case JDEP_SUPER:
5233               /* Simply patch super */
5234               if (parser_check_super (decl, JDEP_DECL (dep), JDEP_WFL (dep)))
5235                 continue;
5236               BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO 
5237                 (TREE_TYPE (JDEP_DECL (dep)))), 0)) = TREE_TYPE (decl);
5238               break;
5239
5240             case JDEP_FIELD:
5241               {
5242                 /* We do part of the job done in add_field */
5243                 tree field_decl = JDEP_DECL (dep);
5244                 tree field_type = TREE_TYPE (decl);
5245                 push_obstacks (&permanent_obstack, &permanent_obstack);
5246                 if (TREE_CODE (field_type) == RECORD_TYPE)
5247                   field_type = promote_type (field_type);
5248                 pop_obstacks ();
5249                 TREE_TYPE (field_decl) = field_type;
5250                 DECL_ALIGN (field_decl) = 0;
5251                 layout_decl (field_decl, 0);
5252                 SOURCE_FRONTEND_DEBUG 
5253                   (("Completed field/var decl `%s' with `%s'",
5254                     IDENTIFIER_POINTER (DECL_NAME (field_decl)),
5255                     IDENTIFIER_POINTER (DECL_NAME (decl))));
5256                 break;
5257               }
5258             case JDEP_METHOD:   /* We start patching a method */
5259             case JDEP_METHOD_RETURN:
5260               error_found = 0;
5261               while (1)
5262                 {
5263                   if (decl)
5264                     {
5265                       type = TREE_TYPE(decl);
5266                       if (TREE_CODE (type) == RECORD_TYPE)
5267                         type = promote_type (type);
5268                       JDEP_APPLY_PATCH (dep, type);
5269                       SOURCE_FRONTEND_DEBUG 
5270                         (((JDEP_KIND (dep) == JDEP_METHOD_RETURN ?
5271                            "Completing fct `%s' with ret type `%s'":
5272                            "Completing arg `%s' with type `%s'"),
5273                           IDENTIFIER_POINTER (EXPR_WFL_NODE 
5274                                               (JDEP_DECL_WFL (dep))),
5275                           IDENTIFIER_POINTER (DECL_NAME (decl))));
5276                     }
5277                   else
5278                     error_found = 1;
5279                   dep = JDEP_CHAIN (dep);
5280                   if (JDEP_KIND (dep) == JDEP_METHOD_END)
5281                     break;
5282                   else
5283                     decl = jdep_resolve_class (dep);
5284                 }
5285               if (!error_found)
5286                 {
5287                   tree mdecl = JDEP_DECL (dep), signature;
5288                   push_obstacks (&permanent_obstack, &permanent_obstack);
5289                   /* Recompute and reset the signature, check first that
5290                      all types are now defined. If they're not,
5291                      dont build the signature. */
5292                   if (check_method_types_complete (mdecl))
5293                     {
5294                       signature = build_java_signature (TREE_TYPE (mdecl));
5295                       set_java_signature (TREE_TYPE (mdecl), signature);
5296                     }
5297                   pop_obstacks ();
5298                 }
5299               else
5300                 continue;
5301               break;
5302
5303             case JDEP_INTERFACE:
5304               if (parser_check_super_interface (decl, JDEP_DECL (dep),
5305                                                 JDEP_WFL (dep)))
5306                 continue;
5307               parser_add_interface (JDEP_DECL (dep), decl, JDEP_WFL (dep));
5308               break;
5309
5310             case JDEP_PARM:
5311             case JDEP_VARIABLE:
5312               type = TREE_TYPE(decl);
5313               if (TREE_CODE (type) == RECORD_TYPE)
5314                 type = promote_type (type);
5315               JDEP_APPLY_PATCH (dep, type);
5316               break;
5317
5318             case JDEP_TYPE:
5319               JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
5320               SOURCE_FRONTEND_DEBUG 
5321                 (("Completing a random type dependency on a '%s' node",
5322                   tree_code_name [TREE_CODE (JDEP_DECL (dep))]));
5323               break;
5324
5325             case JDEP_EXCEPTION:
5326               JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
5327               SOURCE_FRONTEND_DEBUG 
5328                 (("Completing `%s' `throws' argument node",
5329                   IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)))));
5330               break;
5331
5332             case JDEP_ANONYMOUS:
5333               patch_anonymous_class (decl, JDEP_DECL (dep), JDEP_WFL (dep));
5334               break;
5335
5336             default:
5337               fatal ("Can't handle patch code %d - java_complete_class",
5338                      JDEP_KIND (dep));
5339             }
5340         }
5341     }
5342   pop_obstacks ();
5343   return;
5344 }
5345
5346 /* Resolve class CLASS_TYPE. Handle the case of trying to resolve an
5347    array.  */
5348
5349 static tree
5350 resolve_class (enclosing, class_type, decl, cl)
5351      tree enclosing, class_type, decl, cl;
5352 {
5353   const char *name = IDENTIFIER_POINTER (TYPE_NAME (class_type));
5354   const char *base = name;
5355   tree resolved_type = TREE_TYPE (class_type);
5356   tree resolved_type_decl;
5357   
5358   if (resolved_type != NULL_TREE)
5359     {
5360       tree resolved_type_decl = TYPE_NAME (resolved_type);
5361       if (resolved_type_decl == NULL_TREE
5362           || TREE_CODE (resolved_type_decl) == IDENTIFIER_NODE)
5363         {
5364           resolved_type_decl = build_decl (TYPE_DECL,
5365                                            TYPE_NAME (class_type),
5366                                            resolved_type);
5367         }
5368       return resolved_type_decl;
5369     }
5370
5371   /* 1- Check to see if we have an array. If true, find what we really
5372      want to resolve  */
5373   while (name[0] == '[')
5374     name++;
5375   if (base != name)
5376     TYPE_NAME (class_type) = get_identifier (name);
5377
5378   /* 2- Resolve the bare type */
5379   if (!(resolved_type_decl = do_resolve_class (enclosing, class_type, 
5380                                                decl, cl)))
5381     return NULL_TREE;
5382   resolved_type = TREE_TYPE (resolved_type_decl);
5383
5384   /* 3- If we have and array, reconstruct the array down to its nesting */
5385   if (base != name)
5386     {
5387       while (base != name)
5388         {
5389           if (TREE_CODE (resolved_type) == RECORD_TYPE)
5390             resolved_type  = promote_type (resolved_type);
5391           resolved_type = build_java_array_type (resolved_type, -1);
5392           CLASS_LOADED_P (resolved_type) = 1;
5393           name--;
5394         }
5395       /* Build a fake decl for this, since this is what is expected to
5396          be returned.  */
5397       resolved_type_decl =
5398         build_decl (TYPE_DECL, TYPE_NAME (resolved_type), resolved_type);
5399       /* Figure how those two things are important for error report. FIXME */
5400       DECL_SOURCE_LINE (resolved_type_decl) = 0;
5401       DECL_SOURCE_FILE (resolved_type_decl) = input_filename;
5402       TYPE_NAME (class_type) = TYPE_NAME (resolved_type);
5403     }
5404   TREE_TYPE (class_type) = resolved_type;
5405   return resolved_type_decl;
5406 }
5407
5408 /* Effectively perform the resolution of class CLASS_TYPE. DECL or CL
5409    are used to report error messages.  */
5410
5411 tree
5412 do_resolve_class (enclosing, class_type, decl, cl)
5413      tree enclosing, class_type, decl, cl;
5414 {
5415   tree new_class_decl;
5416   tree original_name = NULL_TREE;
5417
5418   /* Do not try to replace TYPE_NAME (class_type) by a variable, since
5419      its is changed by find_in_imports{_on_demand} */
5420
5421   /* 0- Search in the current class as an inner class */
5422
5423   /* Maybe some code here should be added to load the class or
5424      something, at least if the class isn't an inner class and ended
5425      being loaded from class file. FIXME. */
5426   while (enclosing)
5427     {
5428       tree name;
5429
5430       if ((new_class_decl = find_as_inner_class (enclosing, class_type, cl)))
5431         return new_class_decl;
5432
5433       /* Now go to the upper classes, bail out if necessary. */
5434       enclosing = CLASSTYPE_SUPER (TREE_TYPE (enclosing));
5435       if (!enclosing || enclosing == object_type_node)
5436         break;
5437       
5438       if (TREE_CODE (enclosing) == RECORD_TYPE)
5439         {
5440           enclosing = TYPE_NAME (enclosing);
5441           continue;
5442         }
5443
5444       if (TREE_CODE (enclosing) == IDENTIFIER_NODE)
5445         {
5446           BUILD_PTR_FROM_NAME (name, enclosing);
5447         }
5448       else
5449         name = enclosing;
5450       enclosing = do_resolve_class (NULL, name, NULL, NULL);
5451     }
5452
5453   /* 1- Check for the type in single imports */
5454   if (find_in_imports (class_type))
5455     return NULL_TREE;
5456
5457   /* 2- And check for the type in the current compilation unit. If it fails,
5458      try with a name qualified with the package name we've seen so far */
5459   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
5460     {
5461       if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
5462           !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
5463         load_class (TYPE_NAME (class_type), 0);
5464       return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5465     }
5466
5467   original_name = TYPE_NAME (class_type);
5468   if (!QUALIFIED_P (TYPE_NAME (class_type)))
5469     {
5470       tree package;
5471       for (package = package_list; package; package = TREE_CHAIN (package))
5472         {
5473           tree new_qualified;
5474           
5475           new_qualified = merge_qualified_name (TREE_PURPOSE (package),
5476                                                 original_name);
5477           TYPE_NAME (class_type) = new_qualified;
5478           new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5479           if (!new_class_decl)
5480             load_class (TYPE_NAME (class_type), 0);
5481           new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5482           if (new_class_decl)
5483             {
5484               if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
5485                   !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
5486                 load_class (TYPE_NAME (class_type), 0);
5487               return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5488             }
5489         }
5490     }
5491
5492   TYPE_NAME (class_type) = original_name;
5493
5494   /* 3- Check an other compilation unit that bears the name of type */
5495   load_class (TYPE_NAME (class_type), 0);
5496   if (check_pkg_class_access (TYPE_NAME (class_type), 
5497                               (cl ? cl : lookup_cl (decl))))
5498     return NULL_TREE;
5499
5500   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
5501     return new_class_decl;
5502
5503   /* 4- Check the import on demands. Don't allow bar.baz to be
5504      imported from foo.* */
5505   if (!QUALIFIED_P (TYPE_NAME (class_type)))
5506     if (find_in_imports_on_demand (class_type))
5507       return NULL_TREE;
5508
5509   /* 5- Last call for a resolution */
5510   return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5511 }
5512
5513 /* Resolve NAME and lay it out (if not done and if not the current
5514    parsed class). Return a decl node. This function is meant to be
5515    called when type resolution is necessary during the walk pass.  */
5516
5517 static tree
5518 resolve_and_layout (something, cl)
5519      tree something;
5520      tree cl;
5521 {
5522   tree decl;
5523
5524   /* Don't do that on the current class */
5525   if (something == current_class)
5526     return TYPE_NAME (current_class);
5527
5528   /* Don't do anything for void and other primitive types */
5529   if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
5530     return NULL_TREE;
5531
5532   /* Pointer types can be reall pointer types or fake pointers. When
5533      finding a real pointer, recheck for primitive types */
5534   if (TREE_CODE (something) == POINTER_TYPE)
5535     {
5536       if (TREE_TYPE (something))
5537         {
5538           something = TREE_TYPE (something);
5539           if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
5540             return NULL_TREE;
5541         }
5542       else
5543         something = TYPE_NAME (something);
5544     }
5545
5546   /* Don't do anything for arrays of primitive types */
5547   if (TREE_CODE (something) == RECORD_TYPE && TYPE_ARRAY_P (something)
5548       && JPRIMITIVE_TYPE_P (TYPE_ARRAY_ELEMENT (something)))
5549     return NULL_TREE;
5550
5551   /* Something might be a WFL */
5552   if (TREE_CODE (something) == EXPR_WITH_FILE_LOCATION)
5553     something = EXPR_WFL_NODE (something);
5554
5555   /* Otherwise, if something is not and IDENTIFIER_NODE, it can be a a
5556      TYPE_DECL or a real TYPE */
5557   else if (TREE_CODE (something) != IDENTIFIER_NODE)
5558     something = (TREE_CODE (TYPE_NAME (something)) == TYPE_DECL ?
5559             DECL_NAME (TYPE_NAME (something)) : TYPE_NAME (something));
5560
5561   if (!(decl = resolve_no_layout (something, cl)))
5562     return NULL_TREE;
5563
5564   /* Resolve and layout if necessary */
5565   layout_class_methods (TREE_TYPE (decl));
5566   /* Check methods, but only once */
5567   if (CLASS_FROM_SOURCE_P (TREE_TYPE (decl)) 
5568       && !CLASS_LOADED_P (TREE_TYPE (decl)))
5569     CHECK_METHODS (decl);
5570   if (TREE_TYPE (decl) != current_class && !CLASS_LOADED_P (TREE_TYPE (decl)))
5571     safe_layout_class (TREE_TYPE (decl));
5572
5573   return decl;
5574 }
5575
5576 /* Resolve a class, returns its decl but doesn't perform any
5577    layout. The current parsing context is saved and restored */
5578
5579 static tree
5580 resolve_no_layout (name, cl)
5581      tree name, cl;
5582 {
5583   tree ptr, decl;
5584   BUILD_PTR_FROM_NAME (ptr, name);
5585   java_parser_context_save_global ();
5586   decl = resolve_class (TYPE_NAME (current_class), ptr, NULL_TREE, cl);
5587   java_parser_context_restore_global ();
5588   
5589   return decl;
5590 }
5591
5592 /* Called when reporting errors. Skip leader '[' in a complex array
5593    type description that failed to be resolved.  */
5594
5595 static const char *
5596 purify_type_name (name)
5597      const char *name;
5598 {
5599   while (*name && *name == '[')
5600     name++;
5601   return name;
5602 }
5603
5604 /* The type CURRENT refers to can't be found. We print error messages.  */
5605
5606 static void
5607 complete_class_report_errors (dep)
5608      jdep *dep;
5609 {
5610   const char *name;
5611
5612   if (!JDEP_WFL (dep))
5613     return;
5614
5615   name = IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)));
5616   switch (JDEP_KIND (dep))
5617     {
5618     case JDEP_SUPER:
5619       parse_error_context  
5620         (JDEP_WFL (dep), "Superclass `%s' of class `%s' not found",
5621          purify_type_name (name),
5622          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5623       break;
5624     case JDEP_FIELD:
5625       parse_error_context
5626         (JDEP_WFL (dep), "Type `%s' not found in declaration of field `%s'",
5627          purify_type_name (name),
5628          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5629       break;
5630     case JDEP_METHOD:           /* Covers arguments */
5631       parse_error_context
5632         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the argument `%s' of method `%s'",
5633          purify_type_name (name),
5634          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))),
5635          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_MISC (dep))));
5636       break;
5637     case JDEP_METHOD_RETURN:    /* Covers return type */
5638       parse_error_context
5639         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the return type of method `%s'", 
5640          purify_type_name (name),
5641          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))));
5642       break;
5643     case JDEP_INTERFACE:
5644       parse_error_context
5645         (JDEP_WFL (dep), "Superinterface `%s' of %s `%s' not found",
5646          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))),
5647          (CLASS_OR_INTERFACE (JDEP_DECL (dep), "class", "interface")),
5648          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5649       break;
5650     case JDEP_VARIABLE:
5651       parse_error_context
5652         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the local variable `%s'", 
5653          purify_type_name (IDENTIFIER_POINTER 
5654                            (EXPR_WFL_NODE (JDEP_WFL (dep)))),
5655          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5656       break;
5657     case JDEP_EXCEPTION:        /* As specified by `throws' */
5658       parse_error_context 
5659           (JDEP_WFL (dep), "Class `%s' not found in `throws'",
5660          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))));
5661       break;
5662     default:
5663       /* Fix for -Wall. Just break doing nothing. The error will be
5664          caught later */
5665       break;
5666     }
5667 }
5668
5669 /* Return a static string containing the DECL prototype string. If
5670    DECL is a constructor, use the class name instead of the form
5671    <init> */
5672
5673 static const char *
5674 get_printable_method_name (decl)
5675      tree decl;
5676 {
5677   const char *to_return;
5678   tree name = NULL_TREE;
5679
5680   if (DECL_CONSTRUCTOR_P (decl))
5681     {
5682       name = DECL_NAME (decl);
5683       DECL_NAME (decl) = DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)));
5684     }
5685       
5686   to_return = lang_printable_name (decl, 0);
5687   if (DECL_CONSTRUCTOR_P (decl))
5688     DECL_NAME (decl) = name;
5689   
5690   return to_return;
5691 }
5692
5693 /* Reinstall the proper DECL_NAME on METHOD. Return 0 if the method
5694    nevertheless needs to be verfied, 1 otherwise.  */
5695
5696 static int
5697 reset_method_name (method)
5698      tree method;
5699 {
5700   if (!DECL_CLINIT_P (method) && !DECL_FINIT_P (method))
5701     {
5702       /* NAME is just the plain name when Object is being defined */
5703       if (DECL_CONTEXT (method) != object_type_node)
5704         DECL_NAME (method) = (DECL_CONSTRUCTOR_P (method) ? 
5705                               init_identifier_node : GET_METHOD_NAME (method));
5706       return 0;
5707     }
5708   else 
5709     return 1;
5710 }
5711
5712 /* Return the name of METHOD_DECL, when DECL_NAME is a WFL */
5713
5714 tree
5715 java_get_real_method_name (method_decl)
5716      tree method_decl;
5717 {
5718   tree method_name = DECL_NAME (method_decl);
5719   if (DECL_CONSTRUCTOR_P (method_decl))
5720     return init_identifier_node;
5721
5722   /* Explain here why METHOD_DECL doesn't have the DECL_CONSTRUCTUR_P
5723      and still can be a constructor. FIXME */
5724
5725   /* Don't confuse method only bearing the name of their class as
5726      constructors */
5727   else if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (method_decl))
5728            && ctxp
5729            && GET_CPC_UN () == EXPR_WFL_NODE (method_name)
5730            && get_access_flags_from_decl (method_decl) <= ACC_PROTECTED
5731            && TREE_TYPE (TREE_TYPE (method_decl)) == void_type_node)
5732     return init_identifier_node;
5733   else
5734     return EXPR_WFL_NODE (method_name);
5735 }
5736
5737 /* Track method being redefined inside the same class. As a side
5738    effect, set DECL_NAME to an IDENTIFIER (prior entering this
5739    function it's a FWL, so we can track errors more accurately.)  */
5740
5741 static int
5742 check_method_redefinition (class, method)
5743      tree class, method;
5744 {
5745   tree redef, name;
5746   tree cl = DECL_NAME (method);
5747   tree sig = TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (method));
5748   /* decl name of artificial <clinit> and $finit$ doesn't need to be
5749      fixed and checked */
5750
5751   /* Reset the method name before running the check. If it returns 1,
5752      the method doesn't need to be verified with respect to method
5753      redeclaration and we return 0 */
5754   if (reset_method_name (method))
5755     return 0;
5756
5757   name = DECL_NAME (method);
5758   for (redef = TYPE_METHODS (class); redef; redef = TREE_CHAIN (redef))
5759     {
5760       if (redef == method)
5761         break;
5762       if (DECL_NAME (redef) == name 
5763           && sig == TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (redef)))
5764         {
5765           parse_error_context 
5766             (cl, "Duplicate %s declaration `%s'",
5767              (DECL_CONSTRUCTOR_P (redef) ? "constructor" : "method"),
5768              get_printable_method_name (redef));
5769           return 1;
5770         }
5771     }
5772   return 0;
5773 }
5774
5775 static void
5776 check_abstract_method_definitions (do_interface, class_decl, type)
5777      int do_interface;
5778      tree class_decl, type;
5779 {
5780   tree class = TREE_TYPE (class_decl);
5781   tree method, end_type;
5782
5783   end_type = (do_interface ? object_type_node : type);
5784   for (method = TYPE_METHODS (type); method; method = TREE_CHAIN (method))
5785     {
5786       tree other_super, other_method, method_sig, method_name;
5787       int found = 0;
5788       int end_type_reached = 0;
5789       
5790       if (!METHOD_ABSTRACT (method) || METHOD_FINAL (method))
5791         continue;
5792       
5793       /* Now verify that somewhere in between TYPE and CLASS,
5794          abstract method METHOD gets a non abstract definition
5795          that is inherited by CLASS.  */
5796       
5797       method_sig = build_java_signature (TREE_TYPE (method));
5798       method_name = DECL_NAME (method);
5799       if (TREE_CODE (method_name) == EXPR_WITH_FILE_LOCATION)
5800         method_name = EXPR_WFL_NODE (method_name);
5801
5802       other_super = class;
5803       do {
5804         if (other_super == end_type)
5805           end_type_reached = 1;
5806         
5807         /* Method search */
5808         for (other_method = TYPE_METHODS (other_super); other_method;
5809             other_method = TREE_CHAIN (other_method))
5810           {
5811             tree s = build_java_signature (TREE_TYPE (other_method));
5812             tree other_name = DECL_NAME (other_method);
5813             
5814             if (TREE_CODE (other_name) == EXPR_WITH_FILE_LOCATION)
5815               other_name = EXPR_WFL_NODE (other_name);
5816             if (!DECL_CLINIT_P (other_method)
5817                 && !DECL_CONSTRUCTOR_P (other_method)
5818                 && method_name == other_name && method_sig == s)
5819              {
5820                found = 1;
5821                break;
5822              }
5823           }
5824         other_super = CLASSTYPE_SUPER (other_super);
5825       } while (!end_type_reached);
5826  
5827       /* Report that abstract METHOD didn't find an implementation
5828          that CLASS can use. */
5829       if (!found)
5830         {
5831           char *t = xstrdup (lang_printable_name 
5832                             (TREE_TYPE (TREE_TYPE (method)), 0));
5833           tree ccn = DECL_NAME (TYPE_NAME (DECL_CONTEXT (method)));
5834           tree saved_wfl = NULL_TREE;
5835           
5836           if (TREE_CODE (DECL_NAME (method)) == EXPR_WITH_FILE_LOCATION)
5837             {
5838               saved_wfl = DECL_NAME (method);
5839               DECL_NAME (method) = EXPR_WFL_NODE (DECL_NAME (method));
5840             }
5841           
5842           parse_error_context 
5843             (lookup_cl (class_decl),
5844              "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",
5845              IDENTIFIER_POINTER (DECL_NAME (class_decl)),
5846              t, lang_printable_name (method, 0), 
5847              (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))) ? 
5848               "interface" : "class"),
5849              IDENTIFIER_POINTER (ccn),
5850              (CLASS_INTERFACE (class_decl) ? "interface" : "class"),
5851              IDENTIFIER_POINTER (DECL_NAME (class_decl)));
5852           
5853           free (t);
5854           
5855           if (saved_wfl)
5856             DECL_NAME (method) = saved_wfl;
5857         }
5858     }
5859 }
5860
5861 /* Check that CLASS_DECL somehow implements all inherited abstract
5862    methods.  */
5863
5864 static void
5865 java_check_abstract_method_definitions (class_decl)
5866      tree class_decl;
5867 {
5868   tree class = TREE_TYPE (class_decl);
5869   tree super, vector;
5870   int i;
5871
5872   if (CLASS_ABSTRACT (class_decl))
5873     return;
5874
5875   /* Check for inherited types */
5876   super = class;
5877   do {
5878     super = CLASSTYPE_SUPER (super);
5879     check_abstract_method_definitions (0, class_decl, super);
5880   } while (super != object_type_node);
5881
5882   /* Check for implemented interfaces. */
5883   vector = TYPE_BINFO_BASETYPES (class);
5884   for (i = 1; i < TREE_VEC_LENGTH (vector); i++)
5885     {
5886       super = BINFO_TYPE (TREE_VEC_ELT (vector, i));
5887       check_abstract_method_definitions (1, class_decl, super);
5888     }
5889 }
5890
5891 /* Check all the types method DECL uses and return 1 if all of them
5892    are now complete, 0 otherwise. This is used to check whether its
5893    safe to build a method signature or not.  */
5894
5895 static int
5896 check_method_types_complete (decl)
5897      tree decl;
5898 {
5899   tree type = TREE_TYPE (decl);
5900   tree args;
5901
5902   if (!INCOMPLETE_TYPE_P (TREE_TYPE (type)))
5903     return 0;
5904   
5905   args = TYPE_ARG_TYPES (type);
5906   if (TREE_CODE (type) == METHOD_TYPE)
5907     args = TREE_CHAIN (args);
5908   for (; args != end_params_node; args = TREE_CHAIN (args))
5909     if (INCOMPLETE_TYPE_P (TREE_VALUE (args)))
5910       return 0;
5911
5912   return 1;
5913 }
5914
5915 /* Check all the methods of CLASS_DECL. Methods are first completed
5916    then checked according to regular method existance rules.  If no
5917    constructor for CLASS_DECL were encountered, then build its
5918    declaration.  */
5919
5920 static void
5921 java_check_regular_methods (class_decl)
5922      tree class_decl;
5923 {
5924   int saw_constructor = ANONYMOUS_CLASS_P (TREE_TYPE (class_decl));
5925   tree method;
5926   tree class = CLASS_TO_HANDLE_TYPE (TREE_TYPE (class_decl));
5927   tree saved_found_wfl = NULL_TREE, found = NULL_TREE;
5928   tree mthrows;
5929
5930   /* It is not necessary to check methods defined in java.lang.Object */
5931   if (class == object_type_node)
5932     return;
5933
5934   if (!TYPE_NVIRTUALS (class))
5935     TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
5936
5937   /* Should take interfaces into account. FIXME */
5938   for (method = TYPE_METHODS (class); method; method = TREE_CHAIN (method))
5939     {
5940       tree sig;
5941       tree method_wfl = DECL_NAME (method);
5942       int aflags;
5943
5944       /* If we previously found something and its name was saved,
5945          reinstall it now */
5946       if (found && saved_found_wfl)
5947         {
5948           DECL_NAME (found) = saved_found_wfl;
5949           saved_found_wfl = NULL_TREE;
5950         }
5951
5952       /* Check for redefinitions */
5953       if (check_method_redefinition (class, method))
5954         continue;
5955
5956       /* If we see one constructor a mark so we don't generate the
5957          default one. Also skip other verifications: constructors
5958          can't be inherited hence hiden or overriden */
5959      if (DECL_CONSTRUCTOR_P (method))
5960        {
5961          saw_constructor = 1;
5962          continue;
5963        }
5964
5965       /* We verify things thrown by the method. They must inherits from
5966          java.lang.Throwable */
5967       for (mthrows = DECL_FUNCTION_THROWS (method);
5968            mthrows; mthrows = TREE_CHAIN (mthrows))
5969         {
5970           if (!inherits_from_p (TREE_VALUE (mthrows), throwable_type_node))
5971             parse_error_context 
5972               (TREE_PURPOSE (mthrows), "Class `%s' in `throws' clause must be a subclass of class `java.lang.Throwable'",
5973                IDENTIFIER_POINTER 
5974                  (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))));
5975         }
5976
5977       sig = build_java_argument_signature (TREE_TYPE (method));
5978       found = lookup_argument_method2 (class, DECL_NAME (method), sig);
5979
5980       /* Inner class can't declare static methods */
5981       if (METHOD_STATIC (method) && !TOPLEVEL_CLASS_DECL_P (class_decl))
5982         {
5983           char *t = xstrdup (lang_printable_name (class, 0));
5984           parse_error_context 
5985             (method_wfl, "Method `%s' can't be static in inner class `%s'. Only members of interfaces and top-level classes can be static",
5986              lang_printable_name (method, 0), t);
5987           free (t);
5988         }
5989
5990       /* Nothing overrides or it's a private method. */
5991       if (!found)
5992         continue;
5993       if (METHOD_PRIVATE (found))
5994         {
5995           found = NULL_TREE;
5996           continue;
5997         }
5998
5999       /* If found wasn't verified, it's DECL_NAME won't be set properly. 
6000          We set it temporarily for the sake of the error report. */
6001       saved_found_wfl = DECL_NAME (found);
6002       reset_method_name (found);
6003
6004       /* If `found' is declared in an interface, make sure the
6005          modifier matches. */
6006       if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (found))) 
6007           && clinit_identifier_node != DECL_NAME (found)
6008           && !METHOD_PUBLIC (method))
6009         {
6010           tree found_decl = TYPE_NAME (DECL_CONTEXT (found));
6011           parse_error_context (method_wfl, "Class `%s' must override `%s' with a public method in order to implement interface `%s'",
6012                                IDENTIFIER_POINTER (DECL_NAME (class_decl)),
6013                                lang_printable_name (method, 0),
6014                                IDENTIFIER_POINTER (DECL_NAME (found_decl)));
6015         }
6016
6017       /* Can't override a method with the same name and different return
6018          types. */
6019       if (TREE_TYPE (TREE_TYPE (found)) != TREE_TYPE (TREE_TYPE (method)))
6020         {
6021           char *t = xstrdup 
6022             (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
6023           parse_error_context 
6024             (method_wfl,
6025              "Method `%s' was defined with return type `%s' in class `%s'", 
6026              lang_printable_name (found, 0), t,
6027              IDENTIFIER_POINTER 
6028                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6029           free (t);
6030         }
6031
6032       aflags = get_access_flags_from_decl (found);
6033       /* If the method has default, access in an other package, then
6034          issue a warning that the current method doesn't override the
6035          one that was found elsewhere. Do not issue this warning when
6036          the match was found in java.lang.Object.  */
6037       if (DECL_CONTEXT (found) != object_type_node
6038           && ((aflags & ACC_VISIBILITY) == 0)
6039           && !class_in_current_package (DECL_CONTEXT (found))
6040           && !DECL_CLINIT_P (found)
6041           && flag_not_overriding)
6042         {
6043           parse_warning_context 
6044             (method_wfl, "Method `%s' in class `%s' does not override the corresponding method in class `%s', which is private to a different package",
6045              lang_printable_name (found, 0),
6046              IDENTIFIER_POINTER (DECL_NAME (class_decl)),
6047              IDENTIFIER_POINTER (DECL_NAME 
6048                                  (TYPE_NAME (DECL_CONTEXT (found)))));
6049           continue;
6050         }
6051
6052       /* Can't override final. Can't override static. */
6053       if (METHOD_FINAL (found) || METHOD_STATIC (found))
6054         {
6055           /* Static *can* override static */
6056           if (METHOD_STATIC (found) && METHOD_STATIC (method))
6057             continue;
6058           parse_error_context 
6059             (method_wfl,
6060              "%s methods can't be overriden. Method `%s' is %s in class `%s'",
6061              (METHOD_FINAL (found) ? "Final" : "Static"),
6062              lang_printable_name (found, 0),
6063              (METHOD_FINAL (found) ? "final" : "static"),
6064              IDENTIFIER_POINTER
6065                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6066           continue;
6067         }
6068
6069       /* Static method can't override instance method. */
6070       if (METHOD_STATIC (method))
6071         {
6072           parse_error_context 
6073             (method_wfl,
6074              "Instance methods can't be overriden by a static method. Method `%s' is an instance method in class `%s'",
6075              lang_printable_name (found, 0),
6076              IDENTIFIER_POINTER
6077                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6078           continue;
6079         }
6080
6081       /* - Overriding/hiding public must be public
6082          - Overriding/hiding protected must be protected or public
6083          - If the overriden or hidden method has default (package)
6084            access, then the overriding or hiding method must not be
6085            private; otherwise, a compile-time error occurs.  If
6086            `found' belongs to an interface, things have been already
6087            taken care of.  */
6088       if (!CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (found)))
6089           && ((METHOD_PUBLIC (found) && !METHOD_PUBLIC (method))
6090               || (METHOD_PROTECTED (found) 
6091                   && !(METHOD_PUBLIC (method) || METHOD_PROTECTED (method)))
6092               || (!(aflags & (ACC_PUBLIC | ACC_PRIVATE | ACC_STATIC))
6093                   && METHOD_PRIVATE (method))))
6094         {
6095           parse_error_context 
6096             (method_wfl,
6097              "Methods can't be overridden to be more private. Method `%s' is not %s in class `%s'", lang_printable_name (method, 0),
6098              (METHOD_PUBLIC (method) ? "public" : 
6099               (METHOD_PRIVATE (method) ? "private" : "protected")),
6100              IDENTIFIER_POINTER (DECL_NAME 
6101                                  (TYPE_NAME (DECL_CONTEXT (found)))));
6102           continue;
6103         }
6104
6105       /* Overriding methods must have compatible `throws' clauses on checked
6106          exceptions, if any */
6107       check_throws_clauses (method, method_wfl, found);
6108
6109       /* Inheriting multiple methods with the same signature. FIXME */
6110     }
6111   
6112   /* Don't forget eventual pending found and saved_found_wfl. Take
6113      into account that we might have exited because we saw an
6114      artificial method as the last entry. */
6115
6116   if (found && !DECL_ARTIFICIAL (found) && saved_found_wfl)
6117     DECL_NAME (found) = saved_found_wfl;
6118
6119   if (!TYPE_NVIRTUALS (class))
6120     TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
6121
6122   /* Search for inherited abstract method not yet implemented in this
6123      class.  */
6124   java_check_abstract_method_definitions (class_decl);
6125
6126   if (!saw_constructor)
6127     fatal ("No constructor found");
6128 }
6129
6130 /* Return a non zero value if the `throws' clause of METHOD (if any)
6131    is incompatible with the `throws' clause of FOUND (if any).  */
6132
6133 static void
6134 check_throws_clauses (method, method_wfl, found)
6135      tree method, method_wfl, found;
6136 {
6137   tree mthrows, fthrows;
6138
6139   /* Can't check these things with class loaded from bytecode. FIXME */
6140   if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (found)))
6141     return;
6142
6143   for (mthrows = DECL_FUNCTION_THROWS (method);
6144        mthrows; mthrows = TREE_CHAIN (mthrows))
6145     {
6146       /* We don't verify unchecked expressions */
6147       if (IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (mthrows)))
6148         continue;
6149       /* Checked expression must be compatible */
6150       for (fthrows = DECL_FUNCTION_THROWS (found); 
6151            fthrows; fthrows = TREE_CHAIN (fthrows))
6152         if (inherits_from_p (TREE_VALUE (mthrows), TREE_VALUE (fthrows)))
6153           break;
6154       if (!fthrows)
6155         {
6156           parse_error_context 
6157             (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'",
6158              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))),
6159              lang_printable_name (found, 0),
6160              IDENTIFIER_POINTER 
6161                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6162         }
6163     }
6164 }
6165
6166 /* Check abstract method of interface INTERFACE */
6167
6168 static void
6169 java_check_abstract_methods (interface_decl)
6170      tree interface_decl;
6171 {
6172   int i, n;
6173   tree method, basetype_vec, found;
6174   tree interface = TREE_TYPE (interface_decl);
6175
6176   for (method = TYPE_METHODS (interface); method; method = TREE_CHAIN (method))
6177     {
6178       tree method_wfl = DECL_NAME (method);
6179
6180       /* 2- Check for double definition inside the defining interface */
6181       if (check_method_redefinition (interface, method))
6182         continue;
6183
6184       /* 3- Overriding is OK as far as we preserve the return type and
6185          the thrown exceptions (FIXME) */
6186       found = lookup_java_interface_method2 (interface, method);
6187       if (found)
6188         {
6189           char *t;
6190           tree saved_found_wfl = DECL_NAME (found);
6191           reset_method_name (found);
6192           t = xstrdup (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
6193           parse_error_context 
6194             (method_wfl,
6195              "Method `%s' was defined with return type `%s' in class `%s'",
6196              lang_printable_name (found, 0), t,
6197              IDENTIFIER_POINTER 
6198                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6199           free (t);
6200           DECL_NAME (found) = saved_found_wfl;
6201           continue;
6202         }
6203     }
6204
6205   /* 4- Inherited methods can't differ by their returned types */
6206   if (!(basetype_vec = TYPE_BINFO_BASETYPES (interface)))
6207     return;
6208   n = TREE_VEC_LENGTH (basetype_vec);
6209   for (i = 0; i < n; i++)
6210     {
6211       tree sub_interface_method, sub_interface;
6212       tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
6213       if (!vec_elt)
6214         continue;
6215       sub_interface = BINFO_TYPE (vec_elt);
6216       for (sub_interface_method = TYPE_METHODS (sub_interface); 
6217            sub_interface_method;
6218            sub_interface_method = TREE_CHAIN (sub_interface_method))
6219         {
6220           found = lookup_java_interface_method2 (interface, 
6221                                                  sub_interface_method);
6222           if (found && (found != sub_interface_method))
6223             {
6224               tree saved_found_wfl = DECL_NAME (found);
6225               reset_method_name (found);
6226               parse_error_context 
6227                 (lookup_cl (sub_interface_method),
6228                  "Interface `%s' inherits method `%s' from interface `%s'. This method is redefined with a different return type in interface `%s'",
6229                  IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (interface))),
6230                  lang_printable_name (found, 0),
6231                  IDENTIFIER_POINTER 
6232                    (DECL_NAME (TYPE_NAME 
6233                                (DECL_CONTEXT (sub_interface_method)))),
6234                  IDENTIFIER_POINTER 
6235                    (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6236               DECL_NAME (found) = saved_found_wfl;
6237             }
6238         }
6239     }
6240 }
6241
6242 /* Lookup methods in interfaces using their name and partial
6243    signature. Return a matching method only if their types differ.  */
6244
6245 static tree
6246 lookup_java_interface_method2 (class, method_decl)
6247      tree class, method_decl;
6248 {
6249   int i, n;
6250   tree basetype_vec = TYPE_BINFO_BASETYPES (class), to_return;
6251
6252   if (!basetype_vec)
6253     return NULL_TREE;
6254
6255   n = TREE_VEC_LENGTH (basetype_vec);
6256   for (i = 0; i < n; i++)
6257     {
6258       tree vec_elt = TREE_VEC_ELT (basetype_vec, i), to_return;
6259       if ((BINFO_TYPE (vec_elt) != object_type_node)
6260           && (to_return = 
6261               lookup_java_method2 (BINFO_TYPE (vec_elt), method_decl, 1)))
6262         return to_return;
6263     }
6264   for (i = 0; i < n; i++)
6265     {
6266       to_return = lookup_java_interface_method2 
6267         (BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i)), method_decl);
6268       if (to_return)
6269         return to_return;
6270     }
6271
6272   return NULL_TREE;
6273 }
6274
6275 /* Lookup method using their name and partial signature. Return a
6276    matching method only if their types differ.  */
6277
6278 static tree
6279 lookup_java_method2 (clas, method_decl, do_interface)
6280      tree clas, method_decl;
6281      int do_interface;
6282 {
6283   tree method, method_signature, method_name, method_type, name;
6284
6285   method_signature = build_java_argument_signature (TREE_TYPE (method_decl));
6286   name = DECL_NAME (method_decl);
6287   method_name = (TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ? 
6288                  EXPR_WFL_NODE (name) : name);
6289   method_type = TREE_TYPE (TREE_TYPE (method_decl));
6290
6291   while (clas != NULL_TREE)
6292     {
6293       for (method = TYPE_METHODS (clas);
6294            method != NULL_TREE;  method = TREE_CHAIN (method))
6295         {
6296           tree method_sig = build_java_argument_signature (TREE_TYPE (method));
6297           tree name = DECL_NAME (method);
6298           if ((TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
6299                EXPR_WFL_NODE (name) : name) == method_name
6300               && method_sig == method_signature 
6301               && TREE_TYPE (TREE_TYPE (method)) != method_type)
6302             return method;
6303         }
6304       clas = (do_interface ? NULL_TREE : CLASSTYPE_SUPER (clas));
6305     }
6306   return NULL_TREE;
6307 }
6308
6309 /* Return the line that matches DECL line number, and try its best to
6310    position the column number. Used during error reports.  */
6311
6312 static tree
6313 lookup_cl (decl)
6314      tree decl;
6315 {
6316   static tree cl = NULL_TREE;
6317   char *line, *found;
6318   
6319   if (!decl)
6320     return NULL_TREE;
6321
6322   if (cl == NULL_TREE)
6323     cl = build_expr_wfl (NULL_TREE, NULL, 0, 0);
6324
6325   EXPR_WFL_FILENAME_NODE (cl) = get_identifier (DECL_SOURCE_FILE (decl));
6326   EXPR_WFL_SET_LINECOL (cl, DECL_SOURCE_LINE_FIRST (decl), -1);
6327
6328   line = java_get_line_col (IDENTIFIER_POINTER (EXPR_WFL_FILENAME_NODE (cl)),
6329                             EXPR_WFL_LINENO (cl), EXPR_WFL_COLNO (cl));
6330
6331   found = strstr ((const char *)line, 
6332                   (const char *)IDENTIFIER_POINTER (DECL_NAME (decl)));
6333   if (found)
6334     EXPR_WFL_SET_LINECOL (cl, EXPR_WFL_LINENO (cl), found - line);
6335
6336   return cl;
6337 }
6338
6339 /* Look for a simple name in the single-type import list */
6340
6341 static tree
6342 find_name_in_single_imports (name)
6343      tree name;
6344 {
6345   tree node;
6346
6347   for (node = ctxp->import_list; node; node = TREE_CHAIN (node))
6348     if (TREE_VALUE (node) == name)
6349       return (EXPR_WFL_NODE (TREE_PURPOSE (node)));
6350
6351   return NULL_TREE;
6352 }
6353
6354 /* Process all single-type import. */
6355
6356 static int
6357 process_imports ()
6358 {
6359   tree import;
6360   int error_found;
6361
6362   for (import = ctxp->import_list; import; import = TREE_CHAIN (import))
6363     {
6364       tree to_be_found = EXPR_WFL_NODE (TREE_PURPOSE (import));
6365
6366       /* Don't load twice something already defined. */
6367       if (IDENTIFIER_CLASS_VALUE (to_be_found))
6368         continue;
6369       QUALIFIED_P (to_be_found) = 1;
6370       load_class (to_be_found, 0);
6371       error_found =
6372         check_pkg_class_access (to_be_found, TREE_PURPOSE (import));
6373       if (!IDENTIFIER_CLASS_VALUE (to_be_found))
6374         {
6375           parse_error_context (TREE_PURPOSE (import),
6376                                "Class or interface `%s' not found in import",
6377                                IDENTIFIER_POINTER (to_be_found));
6378           return 1;
6379         }
6380       if (error_found)
6381         return 1;
6382     }
6383   return 0;
6384 }
6385
6386 /* Possibly find a class imported by a single-type import statement. Return
6387    1 if an error occured, 0 otherwise. */
6388
6389 static int
6390 find_in_imports (class_type)
6391      tree class_type;
6392 {
6393   tree import;
6394
6395   for (import = ctxp->import_list; import; import = TREE_CHAIN (import))
6396     if (TREE_VALUE (import) == TYPE_NAME (class_type))
6397       {
6398         TYPE_NAME (class_type) = EXPR_WFL_NODE (TREE_PURPOSE (import));
6399         QUALIFIED_P (TYPE_NAME (class_type)) = 1;
6400       }
6401   return 0;
6402 }
6403
6404 static int
6405 note_possible_classname (name, len)
6406      const char *name;
6407      int len;
6408 {
6409   tree node;
6410   if (len > 5 && strncmp (&name [len-5], ".java", 5) == 0)
6411     len = len - 5;
6412   else if (len > 6 && strncmp (&name [len-6], ".class", 6) == 0)
6413     len = len - 6;
6414   else
6415     return 0;
6416   node = ident_subst (name, len, "", '/', '.', "");
6417   IS_A_CLASSFILE_NAME (node) = 1; /* Or soon to be */
6418   QUALIFIED_P (node) = strchr (name, '/') ? 1 : 0;
6419   return 1;
6420 }
6421
6422 /* Read a import directory, gathering potential match for further type
6423    references. Indifferently reads a filesystem or a ZIP archive
6424    directory.  */
6425
6426 static void
6427 read_import_dir (wfl)
6428      tree wfl;
6429 {
6430   tree package_id = EXPR_WFL_NODE (wfl);
6431   const char *package_name = IDENTIFIER_POINTER (package_id);
6432   int package_length = IDENTIFIER_LENGTH (package_id);
6433   DIR *dirp = NULL;
6434   JCF *saved_jcf = current_jcf;
6435
6436   int found = 0;
6437   int k;
6438   void *entry;
6439   struct buffer filename[1];
6440
6441
6442   if (IS_AN_IMPORT_ON_DEMAND_P (package_id))
6443     return;
6444   IS_AN_IMPORT_ON_DEMAND_P (package_id) = 1;
6445
6446   BUFFER_INIT (filename);
6447   buffer_grow (filename, package_length + 100);
6448
6449   for (entry = jcf_path_start (); entry != NULL; entry = jcf_path_next (entry))
6450     {
6451       const char *entry_name = jcf_path_name (entry);
6452       int entry_length = strlen (entry_name);
6453       if (jcf_path_is_zipfile (entry))
6454         {
6455           ZipFile *zipf;
6456           buffer_grow (filename, entry_length);
6457           memcpy (filename->data, entry_name, entry_length - 1);
6458           filename->data[entry_length-1] = '\0';
6459           zipf = opendir_in_zip (filename->data, jcf_path_is_system (entry));
6460           if (zipf == NULL)
6461             error ("malformed .zip archive in CLASSPATH: %s", entry_name);
6462           else
6463             {
6464               ZipDirectory *zipd = (ZipDirectory *) zipf->central_directory;
6465               BUFFER_RESET (filename);
6466               for (k = 0; k < package_length; k++)
6467                 {
6468                   char ch = package_name[k];
6469                   *filename->ptr++ = ch == '.' ? '/' : ch;
6470                 }
6471               *filename->ptr++ = '/';
6472
6473               for (k = 0; k < zipf->count;  k++, zipd = ZIPDIR_NEXT (zipd))
6474                 {
6475                   const char *current_entry = ZIPDIR_FILENAME (zipd);
6476                   int current_entry_len = zipd->filename_length;
6477
6478                   if (current_entry_len >= BUFFER_LENGTH (filename)
6479                       && strncmp (filename->data, current_entry, 
6480                                   BUFFER_LENGTH (filename)) != 0)
6481                     continue;
6482                   found |= note_possible_classname (current_entry,
6483                                                     current_entry_len);
6484                 }
6485             }
6486         }
6487       else
6488         {
6489           BUFFER_RESET (filename);
6490           buffer_grow (filename, entry_length + package_length + 4);
6491           strcpy (filename->data, entry_name);
6492           filename->ptr = filename->data + entry_length;
6493           for (k = 0; k < package_length; k++)
6494             {
6495               char ch = package_name[k];
6496               *filename->ptr++ = ch == '.' ? '/' : ch;
6497             }
6498           *filename->ptr = '\0';
6499
6500           dirp = opendir (filename->data);
6501           if (dirp == NULL)
6502             continue;
6503           *filename->ptr++ = '/';
6504           for (;;)
6505             {
6506               int len; 
6507               const char *d_name;
6508               struct dirent *direntp = readdir (dirp);
6509               if (!direntp)
6510                 break;
6511               d_name = direntp->d_name;
6512               len = strlen (direntp->d_name);
6513               buffer_grow (filename, len+1);
6514               strcpy (filename->ptr, d_name);
6515               found |= note_possible_classname (filename->data + entry_length,
6516                                                 package_length+len+1);
6517             }
6518           if (dirp)
6519             closedir (dirp);
6520         }
6521     }
6522
6523   free (filename->data);
6524
6525   /* Here we should have a unified way of retrieving an entry, to be
6526      indexed. */
6527   if (!found)
6528     {
6529       static int first = 1;
6530       if (first)
6531         {
6532           error ("Can't find default package `%s'. Check the CLASSPATH environment variable and the access to the archives.", package_name);
6533           java_error_count++;
6534           first = 0;
6535         }
6536       else
6537         parse_error_context (wfl, "Package `%s' not found in import",
6538                              package_name);
6539       current_jcf = saved_jcf;
6540       return;
6541     }
6542   current_jcf = saved_jcf;
6543 }
6544
6545 /* Possibly find a type in the import on demands specified
6546    types. Returns 1 if an error occured, 0 otherwise. Run throught the
6547    entire list, to detected potential double definitions.  */
6548                  
6549 static int
6550 find_in_imports_on_demand (class_type)
6551      tree class_type;
6552 {
6553   tree node, import, node_to_use = NULL_TREE;
6554   int seen_once = -1;
6555   tree cl = NULL_TREE;
6556
6557   for (import = ctxp->import_demand_list; import; import = TREE_CHAIN (import))
6558     {
6559       const char *id_name;
6560       obstack_grow (&temporary_obstack, 
6561                     IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))),
6562                     IDENTIFIER_LENGTH (EXPR_WFL_NODE (TREE_PURPOSE (import))));
6563       obstack_1grow (&temporary_obstack, '.');
6564       obstack_grow0 (&temporary_obstack, 
6565                      IDENTIFIER_POINTER (TYPE_NAME (class_type)),
6566                      IDENTIFIER_LENGTH (TYPE_NAME (class_type)));
6567       id_name = obstack_finish (&temporary_obstack);
6568               
6569       node = maybe_get_identifier (id_name);
6570       if (node && IS_A_CLASSFILE_NAME (node))
6571         {
6572           if (seen_once < 0)
6573             {
6574               cl = TREE_PURPOSE (import);
6575               seen_once = 1;
6576               node_to_use = node;
6577             }
6578           else
6579             {
6580               seen_once++;
6581               parse_error_context 
6582                 (import, "Type `%s' also potentially defined in package `%s'",
6583                  IDENTIFIER_POINTER (TYPE_NAME (class_type)),
6584                  IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))));
6585             }
6586         }
6587     }
6588
6589   if (seen_once == 1)
6590     {
6591       /* Setup lineno so that it refers to the line of the import (in
6592          case we parse a class file and encounter errors */
6593       tree decl;
6594       int saved_lineno = lineno;
6595       lineno = EXPR_WFL_LINENO (cl);
6596       TYPE_NAME (class_type) = node_to_use;
6597       QUALIFIED_P (TYPE_NAME (class_type)) = 1;
6598       decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
6599       /* If there is no DECL set for the class or if the class isn't
6600          loaded and not seen in source yet, the load */
6601       if (!decl || (!CLASS_LOADED_P (TREE_TYPE (decl))
6602                     && !CLASS_FROM_SOURCE_P (TREE_TYPE (decl))))
6603         load_class (node_to_use, 0);
6604       lineno = saved_lineno;
6605       return check_pkg_class_access (TYPE_NAME (class_type), cl);
6606     }
6607   else
6608     return (seen_once < 0 ? 0 : seen_once); /* It's ok not to have found */
6609 }
6610
6611 static tree
6612 resolve_package (pkg, next)
6613      tree pkg, *next;
6614 {
6615   tree current, acc;
6616   tree type_name = NULL_TREE;
6617   const char *name = IDENTIFIER_POINTER (EXPR_WFL_NODE (pkg));
6618
6619   /* The trick is to determine when the package name stops and were
6620      the name of something contained in the package starts. Then we
6621      return a fully qualified name of what we want to get. */
6622
6623   /* Do a quick search on well known package names */
6624   if (!strncmp (name, "java.lang.reflect", 17))
6625     {
6626       *next = 
6627         TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg))));
6628       type_name = lookup_package_type (name, 17);
6629     }
6630   else if (!strncmp (name, "java.lang", 9))
6631     {
6632       *next = TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg)));
6633       type_name = lookup_package_type (name, 9);
6634     }
6635
6636   /* If we found something here, return */
6637   if (type_name)
6638     return type_name; 
6639
6640   *next = EXPR_WFL_QUALIFICATION (pkg);
6641
6642   /* Try the current package. */
6643   if (ctxp->package && !strncmp (name, IDENTIFIER_POINTER (ctxp->package),  
6644                                  IDENTIFIER_LENGTH (ctxp->package)))
6645     {
6646       type_name = 
6647         lookup_package_type_and_set_next (name, 
6648                                           IDENTIFIER_LENGTH (ctxp->package), 
6649                                           next );
6650       if (type_name)
6651         return type_name;
6652     }
6653
6654   /* Search in imported package */
6655   for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
6656     {
6657       tree current_pkg_name = EXPR_WFL_NODE (TREE_PURPOSE (current));
6658       int len = IDENTIFIER_LENGTH (current_pkg_name);
6659       if (!strncmp (name, IDENTIFIER_POINTER (current_pkg_name), len))
6660         {
6661           tree left, dummy;
6662           
6663           breakdown_qualified (&left, &dummy, current_pkg_name);
6664           len = IDENTIFIER_LENGTH (left);
6665           type_name = lookup_package_type_and_set_next (name, len, next);
6666           if (type_name)
6667             break;
6668         }
6669     }
6670
6671   /* Try to progressively construct a type name */
6672   if (TREE_CODE (pkg) == EXPR_WITH_FILE_LOCATION)
6673     for (acc = NULL_TREE, current = EXPR_WFL_QUALIFICATION (pkg); 
6674          current; current = TREE_CHAIN (current))
6675       {
6676         acc = merge_qualified_name (acc, EXPR_WFL_NODE (QUAL_WFL (current)));
6677         if ((type_name = resolve_no_layout (acc, NULL_TREE)))
6678           {
6679             type_name = acc;
6680             *next = TREE_CHAIN (current);
6681             break;
6682           }
6683       }
6684   return type_name;
6685 }
6686
6687 static tree
6688 lookup_package_type_and_set_next (name, len, next)
6689      const char *name;
6690      int len;
6691      tree *next;
6692 {
6693   const char *ptr;
6694   tree type_name = lookup_package_type (name, len);
6695
6696   if (!type_name)
6697     return NULL;
6698   
6699   ptr = IDENTIFIER_POINTER (type_name);
6700   while (ptr && (ptr = strchr (ptr, '.'))) 
6701     {
6702       *next = TREE_CHAIN (*next);
6703       ptr++;
6704     }
6705   return type_name;
6706 }
6707
6708 static tree
6709 lookup_package_type (name, from)
6710      const char *name;
6711      int from;
6712 {
6713   char subname [128];
6714   const char *sub = &name[from+1];
6715   while (*sub != '.' && *sub)
6716     sub++;
6717   strncpy (subname, name, sub-name);
6718   subname [sub-name] = '\0';
6719   return get_identifier (subname);
6720 }
6721
6722 /* Check that CLASS_NAME refers to a PUBLIC class. Return 0 if no
6723    access violations were found, 1 otherwise.  */
6724
6725 static int
6726 check_pkg_class_access (class_name, cl)
6727      tree class_name;
6728      tree cl;
6729 {
6730   tree type;
6731
6732   if (!QUALIFIED_P (class_name) || !IDENTIFIER_CLASS_VALUE (class_name))
6733     return 0;
6734
6735   if (!(type = TREE_TYPE (IDENTIFIER_CLASS_VALUE (class_name))))
6736     return 0;
6737
6738   if (!CLASS_PUBLIC (TYPE_NAME (type)))
6739     {
6740       /* Access to a private class within the same package is
6741          allowed. */
6742       tree l, r;
6743       breakdown_qualified (&l, &r, class_name);
6744       if (l == ctxp->package)
6745         return 0;
6746
6747       parse_error_context 
6748         (cl, "Can't access %s `%s'. Only public classes and interfaces in other packages can be accessed",
6749          (CLASS_INTERFACE (TYPE_NAME (type)) ? "interface" : "class"),
6750          IDENTIFIER_POINTER (class_name));
6751       return 1;
6752     }
6753   return 0;
6754 }
6755
6756 /* Local variable declaration. */
6757
6758 static void
6759 declare_local_variables (modifier, type, vlist)
6760      int modifier;
6761      tree type;
6762      tree vlist;
6763 {
6764   tree decl, current, saved_type;
6765   tree type_wfl = NULL_TREE;
6766   int must_chain = 0;
6767   int final_p = 0;
6768
6769   /* Push a new block if statements were seen between the last time we
6770      pushed a block and now. Keep a cound of block to close */
6771   if (BLOCK_EXPR_BODY (GET_CURRENT_BLOCK (current_function_decl)))
6772     {
6773       tree body = GET_CURRENT_BLOCK (current_function_decl);
6774       tree b = enter_block ();
6775       BLOCK_EXPR_ORIGIN (b) = body;
6776     }
6777
6778   if (modifier)
6779     {
6780       int i;
6781       for (i = 0; i <= 10; i++) if (1 << i & modifier) break;
6782       if (modifier == ACC_FINAL)
6783         final_p = 1;
6784       else 
6785         {
6786           parse_error_context 
6787             (ctxp->modifier_ctx [i], 
6788              "Only `final' is allowed as a local variables modifier");
6789           return;
6790         }
6791     }
6792
6793   /* Obtain an incomplete type if TYPE is not complete. TYPE_WFL will
6794      hold the TYPE value if a new incomplete has to be created (as
6795      opposed to being found already existing and reused). */
6796   SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
6797
6798   /* If TYPE is fully resolved and we don't have a reference, make one */
6799   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
6800
6801   /* Go through all the declared variables */
6802   for (current = vlist, saved_type = type; current;
6803        current = TREE_CHAIN (current), type = saved_type)
6804     {
6805       tree other, real_type;
6806       tree wfl  = TREE_PURPOSE (current);
6807       tree name = EXPR_WFL_NODE (wfl);
6808       tree init = TREE_VALUE (current);
6809
6810       /* Process NAME, as it may specify extra dimension(s) for it */
6811       type = build_array_from_name (type, type_wfl, name, &name);
6812
6813       /* Variable redefinition check */
6814       if ((other = lookup_name_in_blocks (name)))
6815         {
6816           variable_redefinition_error (wfl, name, TREE_TYPE (other),
6817                                        DECL_SOURCE_LINE (other));
6818           continue;
6819         }
6820
6821       /* Type adjustment. We may have just readjusted TYPE because
6822          the variable specified more dimensions. Make sure we have
6823          a reference if we can and don't have one already. */
6824       PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
6825
6826       real_type = GET_REAL_TYPE (type);
6827       /* Never layout this decl. This will be done when its scope
6828          will be entered */
6829       decl = build_decl (VAR_DECL, name, real_type);
6830       LOCAL_FINAL (decl) = final_p;
6831       BLOCK_CHAIN_DECL (decl);
6832       
6833       /* If doing xreferencing, replace the line number with the WFL
6834          compound value */
6835       if (flag_emit_xref)
6836         DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (wfl);
6837       
6838       /* Don't try to use an INIT statement when an error was found */
6839       if (init && java_error_count)
6840         init = NULL_TREE;
6841       
6842       /* Add the initialization function to the current function's code */
6843       if (init)
6844         {
6845           /* Name might have been readjusted */
6846           EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = name;
6847           MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
6848           java_method_add_stmt (current_function_decl,
6849                                 build_debugable_stmt (EXPR_WFL_LINECOL (init),
6850                                                       init));
6851         }
6852     
6853       /* Setup dependency the type of the decl */
6854       if (must_chain)
6855         {
6856           jdep *dep;
6857           register_incomplete_type (JDEP_VARIABLE, type_wfl, decl, type);
6858           dep = CLASSD_LAST (ctxp->classd_list);
6859           JDEP_GET_PATCH (dep) = &TREE_TYPE (decl);
6860         }
6861     }
6862   SOURCE_FRONTEND_DEBUG (("Defined locals"));
6863 }
6864
6865 /* Called during parsing. Build decls from argument list.  */
6866
6867 static void
6868 source_start_java_method (fndecl)
6869      tree fndecl;
6870 {
6871   tree tem;
6872   tree parm_decl;
6873   int i;
6874
6875   if (!fndecl)
6876     return;
6877
6878   current_function_decl = fndecl;
6879
6880   /* New scope for the function */
6881   enter_block ();
6882   for (tem = TYPE_ARG_TYPES (TREE_TYPE (fndecl)), i = 0;
6883        tem != end_params_node; tem = TREE_CHAIN (tem), i++)
6884     {
6885       tree type = TREE_VALUE (tem);
6886       tree name = TREE_PURPOSE (tem);
6887       
6888       /* If type is incomplete. Create an incomplete decl and ask for
6889          the decl to be patched later */
6890       if (INCOMPLETE_TYPE_P (type))
6891         {
6892           jdep *jdep;
6893           tree real_type = GET_REAL_TYPE (type);
6894           parm_decl = build_decl (PARM_DECL, name, real_type);
6895           type = obtain_incomplete_type (type);
6896           register_incomplete_type (JDEP_PARM, NULL_TREE, NULL_TREE, type);
6897           jdep = CLASSD_LAST (ctxp->classd_list);
6898           JDEP_MISC (jdep) = name;
6899           JDEP_GET_PATCH (jdep) = &TREE_TYPE (parm_decl);
6900         }
6901       else
6902         parm_decl = build_decl (PARM_DECL, name, type);
6903
6904       /* Remember if a local variable was declared final (via its
6905          TREE_LIST of type/name.) Set LOCAL_FINAL accordingly. */
6906       if (ARG_FINAL_P (tem))
6907         LOCAL_FINAL (parm_decl) = 1;
6908
6909       BLOCK_CHAIN_DECL (parm_decl);
6910     }
6911   tem = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
6912   BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl)) =
6913     nreverse (tem);
6914   DECL_ARG_SLOT_COUNT (current_function_decl) = i;
6915   DECL_MAX_LOCALS (current_function_decl) = i;
6916 }
6917
6918 /* Called during parsing. Creates an artificial method declaration.  */
6919
6920 static tree
6921 create_artificial_method (class, flags, type, name, args)
6922      tree class;
6923      int flags;
6924      tree type, name, args;
6925 {
6926   tree mdecl;
6927
6928   java_parser_context_save_global ();
6929   lineno = 0;                                                               
6930   mdecl = make_node (FUNCTION_TYPE);                                
6931   TREE_TYPE (mdecl) = type;
6932   TYPE_ARG_TYPES (mdecl) = args;
6933   mdecl = add_method (class, flags, name, build_java_signature (mdecl)); 
6934   java_parser_context_restore_global ();
6935   DECL_ARTIFICIAL (mdecl) = 1;                                      
6936   return mdecl;
6937 }
6938
6939 /* Starts the body if an artifical method.  */
6940
6941 static void
6942 start_artificial_method_body (mdecl)
6943      tree mdecl;
6944 {
6945   DECL_SOURCE_LINE (mdecl) = 1;
6946   DECL_SOURCE_LINE_MERGE (mdecl, 1);
6947   source_start_java_method (mdecl);
6948   enter_block ();
6949 }
6950
6951 static void
6952 end_artificial_method_body (mdecl)
6953      tree mdecl;
6954 {
6955   BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)) = exit_block ();
6956   exit_block ();
6957 }
6958
6959 /* Called during expansion. Push decls formerly built from argument
6960    list so they're usable during expansion. */
6961
6962 static void
6963 expand_start_java_method (fndecl)
6964      tree fndecl;
6965 {
6966   tree tem, *ptr;
6967
6968   current_function_decl = fndecl;
6969
6970   if (! quiet_flag)
6971     fprintf (stderr, " [%s.", lang_printable_name (DECL_CONTEXT (fndecl), 0));
6972   announce_function (fndecl);
6973   if (! quiet_flag)
6974     fprintf (stderr, "]");
6975
6976   pushlevel (1);                /* Prepare for a parameter push */
6977   ptr = &DECL_ARGUMENTS (fndecl);
6978   tem  = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
6979   while (tem)
6980     {
6981       tree next = TREE_CHAIN (tem);
6982       tree type = TREE_TYPE (tem);
6983       if (PROMOTE_PROTOTYPES
6984           && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
6985           && INTEGRAL_TYPE_P (type))
6986         type = integer_type_node;
6987       DECL_ARG_TYPE (tem) = type;
6988       layout_decl (tem, 0);
6989       pushdecl (tem);
6990       *ptr = tem;
6991       ptr = &TREE_CHAIN (tem);
6992       tem = next;
6993     }
6994   *ptr = NULL_TREE;
6995   pushdecl_force_head (DECL_ARGUMENTS (fndecl));
6996   lineno = DECL_SOURCE_LINE_FIRST (fndecl);
6997 }
6998
6999 /* Terminate a function and expand its body.  */
7000
7001 static void
7002 source_end_java_method ()
7003 {
7004   tree fndecl = current_function_decl;
7005   int flag_asynchronous_exceptions = asynchronous_exceptions;
7006
7007   if (!fndecl)
7008     return;
7009
7010   java_parser_context_save_global ();
7011   lineno = ctxp->last_ccb_indent1;
7012
7013   /* Set EH language codes */
7014   java_set_exception_lang_code ();
7015
7016   /* Turn function bodies with only a NOP expr null, so they don't get
7017      generated at all and we won't get warnings when using the -W
7018      -Wall flags. */
7019   if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) == empty_stmt_node)
7020     BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) = NULL_TREE;
7021
7022   /* Generate function's code */
7023   if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl))
7024       && ! flag_emit_class_files
7025       && ! flag_emit_xref)
7026     expand_expr_stmt (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)));
7027
7028   /* pop out of its parameters */
7029   pushdecl_force_head (DECL_ARGUMENTS (fndecl));
7030   poplevel (1, 0, 1);
7031   BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
7032
7033   /* Generate rtl for function exit.  */
7034   if (! flag_emit_class_files && ! flag_emit_xref)
7035     {
7036       lineno = DECL_SOURCE_LINE_LAST (fndecl);
7037       /* Emit catch-finally clauses */
7038       emit_handlers ();
7039       expand_function_end (input_filename, lineno, 0);
7040
7041       /* FIXME: If the current method contains any exception handlers,
7042          force asynchronous_exceptions: this is necessary because signal
7043          handlers in libjava may throw exceptions.  This is far from being
7044          a perfect solution, but it's better than doing nothing at all.*/
7045       if (catch_clauses)
7046         asynchronous_exceptions = 1;
7047
7048       /* Run the optimizers and output assembler code for this function. */
7049       rest_of_compilation (fndecl);
7050     }
7051
7052   current_function_decl = NULL_TREE;
7053   permanent_allocation (1);
7054   java_parser_context_restore_global ();
7055   asynchronous_exceptions = flag_asynchronous_exceptions;
7056 }
7057
7058 /* Record EXPR in the current function block. Complements compound
7059    expression second operand if necessary.  */
7060
7061 tree
7062 java_method_add_stmt (fndecl, expr)
7063      tree fndecl, expr;
7064 {
7065   if (!GET_CURRENT_BLOCK (fndecl))
7066     return NULL_TREE;
7067   return add_stmt_to_block (GET_CURRENT_BLOCK (fndecl), NULL_TREE, expr);
7068 }
7069
7070 static tree
7071 add_stmt_to_block (b, type, stmt)
7072      tree b, type, stmt;
7073 {
7074   tree body = BLOCK_EXPR_BODY (b), c;
7075   
7076   if (java_error_count)
7077     return body;
7078     
7079   if ((c = add_stmt_to_compound (body, type, stmt)) == body)
7080     return body;
7081
7082   BLOCK_EXPR_BODY (b) = c;
7083   TREE_SIDE_EFFECTS (c) = 1;
7084   return c;
7085 }
7086
7087 /* Add STMT to EXISTING if possible, otherwise create a new
7088    COMPOUND_EXPR and add STMT to it. */
7089
7090 static tree
7091 add_stmt_to_compound (existing, type, stmt)
7092      tree existing, type, stmt;
7093 {
7094   if (existing)
7095     return build (COMPOUND_EXPR, type, existing, stmt);
7096   else
7097     return stmt;
7098 }
7099
7100 /* Hold THIS for the scope of the current public method decl.  */
7101 static tree current_this;
7102
7103 void java_layout_seen_class_methods ()
7104 {
7105   tree previous_list = all_class_list;
7106   tree end = NULL_TREE;
7107   tree current;
7108
7109   while (1)
7110     {
7111       for (current = previous_list; 
7112            current != end; current = TREE_CHAIN (current))
7113         layout_class_methods (TREE_TYPE (TREE_VALUE (current)));
7114       
7115       if (previous_list != all_class_list)
7116         {
7117           end = previous_list;
7118           previous_list = all_class_list;
7119         }
7120       else
7121         break;
7122     }
7123 }
7124
7125 void
7126 java_reorder_fields ()
7127 {
7128   static tree stop_reordering = NULL_TREE;
7129
7130   tree current;
7131   for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
7132     {
7133       current_class = TREE_TYPE (TREE_VALUE (current));
7134
7135       if (current_class == stop_reordering)
7136         break;
7137
7138       /* Reverse the fields, but leave the dummy field in front.
7139          Fields are already ordered for Object and Class */
7140       if (TYPE_FIELDS (current_class) && current_class != object_type_node
7141           && current_class != class_type_node)
7142       {
7143         /* If the dummy field is there, reverse the right fields and
7144            just layout the type for proper fields offset */
7145         if (!DECL_NAME (TYPE_FIELDS (current_class)))
7146           {
7147             tree fields = TYPE_FIELDS (current_class);
7148             TREE_CHAIN (fields) = nreverse (TREE_CHAIN (fields));
7149             TYPE_SIZE (current_class) = NULL_TREE;
7150           }
7151         /* We don't have a dummy field, we need to layout the class,
7152            after having reversed the fields */
7153         else
7154           {
7155             TYPE_FIELDS (current_class) = 
7156               nreverse (TYPE_FIELDS (current_class));
7157             TYPE_SIZE (current_class) = NULL_TREE;
7158           }
7159       }
7160     }
7161   stop_reordering = TREE_TYPE (TREE_VALUE (ctxp->gclass_list));
7162 }
7163
7164 /* Layout the methods of all classes loaded in one way on an
7165    other. Check methods of source parsed classes. Then reorder the
7166    fields and layout the classes or the type of all source parsed
7167    classes */
7168
7169 void
7170 java_layout_classes ()
7171 {
7172   tree current;
7173   int save_error_count = java_error_count;
7174
7175   /* Layout the methods of all classes seen so far */
7176   java_layout_seen_class_methods ();
7177   java_parse_abort_on_error ();
7178   all_class_list = NULL_TREE;
7179
7180   /* Then check the methods of all parsed classes */
7181   for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
7182     if (CLASS_FROM_SOURCE_P (TREE_TYPE (TREE_VALUE (current))))
7183       CHECK_METHODS (TREE_VALUE (current));
7184   java_parse_abort_on_error ();
7185
7186   for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
7187     {
7188       current_class = TREE_TYPE (TREE_VALUE (current));
7189       layout_class (current_class);
7190
7191       /* From now on, the class is considered completely loaded */
7192       CLASS_LOADED_P (current_class) = 1;
7193
7194       /* Error reported by the caller */
7195       if (java_error_count)
7196         return;
7197     }
7198
7199   /* We might have reloaded classes durign the process of laying out
7200      classes for code generation. We must layout the methods of those
7201      late additions, as constructor checks might use them */
7202   java_layout_seen_class_methods ();
7203   java_parse_abort_on_error ();
7204 }
7205
7206 /* Expand methods in the current set of classes rememebered for
7207    generation.  */
7208
7209 static void
7210 java_complete_expand_classes ()
7211 {
7212   tree current;
7213
7214   do_not_fold = flag_emit_xref;
7215
7216   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
7217     if (!INNER_CLASS_DECL_P (current))
7218       java_complete_expand_class (current);
7219 }
7220
7221 /* Expand the methods found in OUTER, starting first by OUTER's inner
7222    classes, if any.  */
7223
7224 static void
7225 java_complete_expand_class (outer)
7226      tree outer;
7227 {
7228   tree inner_list;
7229
7230   set_nested_class_simple_name_value (outer, 1); /* Set */
7231
7232   /* We need to go after all inner classes and start expanding them,
7233      starting with most nested ones. We have to do that because nested
7234      classes might add functions to outer classes */
7235
7236   for (inner_list = DECL_INNER_CLASS_LIST (outer);
7237        inner_list; inner_list = TREE_CHAIN (inner_list))
7238     java_complete_expand_class (TREE_PURPOSE (inner_list));
7239
7240   java_complete_expand_methods (outer);
7241   set_nested_class_simple_name_value (outer, 0); /* Reset */
7242 }
7243
7244 /* Expand methods registered in CLASS_DECL. The general idea is that
7245    we expand regular methods first. This allows us get an estimate on
7246    how outer context local alias fields are really used so we can add
7247    to the constructor just enough code to initialize them properly (it
7248    also lets us generate $finit$ correctly.) Then we expand the
7249    constructors and then <clinit>.  */
7250
7251 static void
7252 java_complete_expand_methods (class_decl)
7253      tree class_decl;
7254 {
7255   tree clinit, finit, decl, first_decl;
7256
7257   current_class = TREE_TYPE (class_decl);
7258
7259   /* Initialize a new constant pool */
7260   init_outgoing_cpool ();
7261
7262   /* Pre-expand <clinit> to figure whether we really need it or
7263      not. If we do need it, we pre-expand the static fields so they're
7264      ready to be used somewhere else. <clinit> will be fully expanded
7265      after we processed the constructors. */
7266   first_decl = TYPE_METHODS (current_class);
7267   clinit = maybe_generate_pre_expand_clinit (current_class);
7268
7269   /* Then generate $finit$ (if we need to) because constructor will
7270    try to use it.*/
7271   if (TYPE_FINIT_STMT_LIST (current_class))
7272     {
7273       finit = generate_finit (current_class);
7274       java_complete_expand_method (finit);
7275     }
7276
7277   /* Now do the constructors */
7278   for (decl = first_decl ; !java_error_count && decl; decl = TREE_CHAIN (decl))
7279     {
7280       int no_body;
7281
7282       if (!DECL_CONSTRUCTOR_P (decl))
7283         continue;
7284       
7285       no_body = !DECL_FUNCTION_BODY (decl);
7286       /* Don't generate debug info on line zero when expanding a
7287          generated constructor. */
7288       if (no_body)
7289         restore_line_number_status (1);
7290
7291       java_complete_expand_method (decl);
7292       
7293       if (no_body)
7294         restore_line_number_status (0);
7295     }
7296
7297   /* First, do the ordinary methods. */
7298   for (decl = first_decl; decl; decl = TREE_CHAIN (decl))
7299     {
7300       /* Skip abstract or native methods -- but do handle native
7301          methods when generating JNI stubs.  */
7302       if (METHOD_ABSTRACT (decl)
7303           || (! flag_jni && METHOD_NATIVE (decl))
7304           || DECL_CONSTRUCTOR_P (decl) || DECL_CLINIT_P (decl))
7305         continue;
7306
7307       if (METHOD_NATIVE (decl))
7308         {
7309           tree body = build_jni_stub (decl);
7310           BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (decl)) = body;
7311         }
7312
7313       java_complete_expand_method (decl);
7314     }
7315
7316   /* If there is indeed a <clinit>, fully expand it now */
7317   if (clinit)
7318     {
7319       /* Prevent the use of `this' inside <clinit> */
7320       ctxp->explicit_constructor_p = 1;
7321       java_complete_expand_method (clinit);
7322       ctxp->explicit_constructor_p = 0;
7323     }
7324   
7325   /* We might have generated a class$ that we now want to expand */
7326   if (TYPE_DOT_CLASS (current_class))
7327     java_complete_expand_method (TYPE_DOT_CLASS (current_class));
7328
7329   /* Now verify constructor circularity (stop after the first one we
7330      prove wrong.) */
7331   if (!CLASS_INTERFACE (class_decl))
7332     for (decl = TYPE_METHODS (current_class); decl; decl = TREE_CHAIN (decl))
7333       if (DECL_CONSTRUCTOR_P (decl) 
7334           && verify_constructor_circularity (decl, decl))
7335         break;
7336
7337   /* Save the constant pool. We'll need to restore it later. */
7338   TYPE_CPOOL (current_class) = outgoing_cpool;
7339 }
7340
7341 /* Hold a list of catch clauses list. The first element of this list is
7342    the list of the catch clauses of the currently analysed try block. */
7343 static tree currently_caught_type_list;
7344
7345 /* Attempt to create <clinit>. Pre-expand static fields so they can be
7346    safely used in some other methods/constructors.  */
7347
7348 static tree
7349 maybe_generate_pre_expand_clinit (class_type)
7350      tree class_type;
7351 {
7352   tree current, mdecl;
7353
7354   if (!TYPE_CLINIT_STMT_LIST (class_type))
7355     return NULL_TREE;
7356
7357   /* Go through all static fields and pre expand them */
7358   for (current = TYPE_FIELDS (class_type); current; 
7359        current = TREE_CHAIN (current))
7360     if (FIELD_STATIC (current))
7361       build_field_ref (NULL_TREE, class_type, DECL_NAME (current));
7362
7363   /* Then build the <clinit> method */
7364   mdecl = create_artificial_method (class_type, ACC_STATIC, void_type_node,
7365                                     clinit_identifier_node, end_params_node);
7366   layout_class_method (class_type, CLASSTYPE_SUPER (class_type),
7367                        mdecl, NULL_TREE);
7368   start_artificial_method_body (mdecl);
7369
7370   /* We process the list of assignment we produced as the result of
7371      the declaration of initialized static field and add them as
7372      statement to the <clinit> method. */
7373   for (current = TYPE_CLINIT_STMT_LIST (class_type); current;
7374        current = TREE_CHAIN (current))
7375     {
7376       /* We build the assignment expression that will initialize the
7377          field to its value. There are strict rules on static
7378          initializers (8.5). FIXME */
7379       tree stmt = build_debugable_stmt (EXPR_WFL_LINECOL (current), current);
7380       java_method_add_stmt (mdecl, stmt);
7381     }
7382
7383   end_artificial_method_body (mdecl);
7384
7385   /* Now we want to place <clinit> as the last method for interface so
7386      that it doesn't interfere with the dispatch table based
7387      lookup. */
7388   if (CLASS_INTERFACE (TYPE_NAME (class_type))
7389       && TREE_CHAIN (TYPE_METHODS (class_type)))
7390     {
7391       tree current = 
7392         TYPE_METHODS (class_type) = TREE_CHAIN (TYPE_METHODS (class_type));
7393
7394       while (TREE_CHAIN (current))
7395         current = TREE_CHAIN (current);
7396       TREE_CHAIN (current) = mdecl;
7397       TREE_CHAIN (mdecl) = NULL_TREE;
7398     }
7399
7400   return mdecl;
7401 }
7402
7403 /* Complete and expand a method.  */
7404
7405 static void
7406 java_complete_expand_method (mdecl)
7407      tree mdecl;
7408 {
7409   current_function_decl = mdecl;
7410   /* Fix constructors before expanding them */
7411   if (DECL_CONSTRUCTOR_P (mdecl))
7412     fix_constructors (mdecl);
7413   
7414   /* Expand functions that have a body */
7415   if (DECL_FUNCTION_BODY (mdecl))
7416     {
7417       tree fbody = DECL_FUNCTION_BODY (mdecl);
7418       tree block_body = BLOCK_EXPR_BODY (fbody);
7419       tree exception_copy = NULL_TREE;
7420       expand_start_java_method (mdecl);
7421       build_result_decl (mdecl);
7422
7423       current_this 
7424         = (!METHOD_STATIC (mdecl) ? 
7425            BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl)) : NULL_TREE);
7426
7427       /* Purge the `throws' list of unchecked exceptions. If we're
7428          doing xref, save a copy of the list and re-install it
7429          later. */
7430       if (flag_emit_xref)
7431         exception_copy = copy_list (DECL_FUNCTION_THROWS (mdecl));
7432
7433       purge_unchecked_exceptions (mdecl);
7434
7435       /* Install exceptions thrown with `throws' */
7436       PUSH_EXCEPTIONS (DECL_FUNCTION_THROWS (mdecl));
7437
7438       if (block_body != NULL_TREE)
7439         {
7440           block_body = java_complete_tree (block_body);
7441
7442           if (! flag_emit_xref && ! METHOD_NATIVE (mdecl))
7443             check_for_initialization (block_body);
7444           ctxp->explicit_constructor_p = 0;
7445         }
7446
7447       BLOCK_EXPR_BODY (fbody) = block_body;
7448
7449       /* If we saw a return but couldn't evaluate it properly, we'll
7450          have an error_mark_node here. */
7451       if (block_body != error_mark_node
7452           && (block_body == NULL_TREE || CAN_COMPLETE_NORMALLY (block_body))
7453           && TREE_CODE (TREE_TYPE (TREE_TYPE (mdecl))) != VOID_TYPE
7454           && !flag_emit_xref)
7455         missing_return_error (current_function_decl);
7456
7457       complete_start_java_method (mdecl); 
7458
7459       /* Don't go any further if we've found error(s) during the
7460          expansion */
7461       if (!java_error_count)
7462         source_end_java_method ();
7463       else
7464         {
7465           pushdecl_force_head (DECL_ARGUMENTS (mdecl));
7466           poplevel (1, 0, 1);
7467         }
7468
7469       /* Pop the exceptions and sanity check */
7470       POP_EXCEPTIONS();
7471       if (currently_caught_type_list)
7472         fatal ("Exception list non empty - java_complete_expand_method");
7473
7474       if (flag_emit_xref)
7475         DECL_FUNCTION_THROWS (mdecl) = exception_copy;
7476     }
7477 }
7478
7479 \f
7480
7481 /* This section of the code deals with accessing enclosing context
7482    fields either directly by using the relevant access to this$<n> or
7483    by invoking an access method crafted for that purpose.  */
7484
7485 /* Build the necessary access from an inner class to an outer
7486    class. This routine could be optimized to cache previous result
7487    (decl, current_class and returned access).  When an access method
7488    needs to be generated, it always takes the form of a read. It might
7489    be later turned into a write by calling outer_field_access_fix.  */
7490
7491 static tree
7492 build_outer_field_access (id, decl)
7493      tree id, decl;
7494 {
7495   tree access = NULL_TREE;
7496   tree ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class)));
7497
7498   /* If decl's class is the direct outer class of the current_class,
7499      build the access as `this$<n>.<field>'. Not that we will break
7500      the `private' barrier if we're not emitting bytecodes. */
7501   if (ctx == DECL_CONTEXT (decl) 
7502       && (!FIELD_PRIVATE (decl) || !flag_emit_class_files ))
7503     {
7504       tree thisn = build_current_thisn (current_class);
7505       access = make_qualified_primary (build_wfl_node (thisn), 
7506                                        id, EXPR_WFL_LINECOL (id));
7507     }
7508   /* Otherwise, generate access methods to outer this and access the
7509      field (either using an access method or by direct access.) */
7510   else
7511     {
7512       int lc = EXPR_WFL_LINECOL (id);
7513
7514       /* Now we chain the required number of calls to the access$0 to
7515          get a hold to the enclosing instance we need, and the we
7516          build the field access. */
7517       access = build_access_to_thisn (ctx, DECL_CONTEXT (decl), lc);
7518
7519       /* If the field is private and we're generating bytecode, then
7520          we generate an access method */
7521       if (FIELD_PRIVATE (decl) && flag_emit_class_files )
7522         {
7523           tree name = build_outer_field_access_methods (decl);
7524           access = build_outer_field_access_expr (lc, DECL_CONTEXT (decl),
7525                                                   name, access, NULL_TREE);
7526         }
7527       /* Otherwise we use `access$(this$<j>). ... access$(this$<i>).<field>'.
7528          Once again we break the `private' access rule from a foreign
7529          class. */
7530       else
7531         access = make_qualified_primary (access, id, lc);
7532     }
7533   return resolve_expression_name (access, NULL);
7534 }
7535
7536 /* Return a non zero value if NODE describes an outer field inner
7537    access.  */
7538
7539 static int
7540 outer_field_access_p (type, decl)
7541     tree type, decl;
7542 {
7543   if (!INNER_CLASS_TYPE_P (type) 
7544       || TREE_CODE (decl) != FIELD_DECL
7545       || DECL_CONTEXT (decl) == type)
7546     return 0;
7547
7548   for (type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))); ;
7549        type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))))
7550     {
7551       if (type == DECL_CONTEXT (decl))
7552         return 1;
7553       if (!DECL_CONTEXT (TYPE_NAME (type)))
7554         break;
7555     }
7556
7557   return 0;
7558 }
7559
7560 /* Return a non zero value if NODE represents an outer field inner
7561    access that was been already expanded. As a side effect, it returns
7562    the name of the field being accessed and the argument passed to the
7563    access function, suitable for a regeneration of the access method
7564    call if necessary. */
7565
7566 static int
7567 outer_field_expanded_access_p (node, name, arg_type, arg)
7568     tree node, *name, *arg_type, *arg;
7569 {
7570   int identified = 0;
7571
7572   if (TREE_CODE (node) != CALL_EXPR)
7573     return 0;
7574
7575   /* Well, gcj generates slightly different tree nodes when compiling
7576      to native or bytecodes. It's the case for function calls. */
7577
7578   if (flag_emit_class_files 
7579       && TREE_CODE (node) == CALL_EXPR
7580       && OUTER_FIELD_ACCESS_IDENTIFIER_P (DECL_NAME (TREE_OPERAND (node, 0))))
7581     identified = 1;
7582   else if (!flag_emit_class_files)
7583     {
7584       node = TREE_OPERAND (node, 0);
7585       
7586       if (node && TREE_OPERAND (node, 0)
7587           && TREE_CODE (TREE_OPERAND (node, 0)) == ADDR_EXPR)
7588         {
7589           node = TREE_OPERAND (node, 0);
7590           if (TREE_OPERAND (node, 0)
7591               && TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL
7592               && (OUTER_FIELD_ACCESS_IDENTIFIER_P 
7593                   (DECL_NAME (TREE_OPERAND (node, 0)))))
7594             identified = 1;
7595         }
7596     }
7597
7598   if (identified && name && arg_type && arg)
7599     {
7600       tree argument = TREE_OPERAND (node, 1);
7601       *name = DECL_NAME (TREE_OPERAND (node, 0));
7602       *arg_type = TREE_TYPE (TREE_TYPE (TREE_VALUE (argument)));
7603       *arg = TREE_VALUE (argument);
7604     }
7605   return identified;
7606 }
7607
7608 /* Detect in NODE an outer field read access from an inner class and
7609    transform it into a write with RHS as an argument. This function is
7610    called from the java_complete_lhs when an assignment to a LHS can
7611    be identified. */
7612
7613 static tree
7614 outer_field_access_fix (wfl, node, rhs)
7615     tree wfl, node, rhs;
7616 {
7617   tree name, arg_type, arg;
7618   
7619   if (outer_field_expanded_access_p (node, &name, &arg_type, &arg))
7620     {
7621       /* At any rate, check whether we're trying to assign a value to
7622          a final. */
7623       tree accessed = (JDECL_P (node) ? node : 
7624                        (TREE_CODE (node) == COMPONENT_REF ? 
7625                         TREE_OPERAND (node, 1) : node));
7626       if (check_final_assignment (accessed, wfl))
7627         return error_mark_node;
7628   
7629       node = build_outer_field_access_expr (EXPR_WFL_LINECOL (wfl), 
7630                                             arg_type, name, arg, rhs);
7631       return java_complete_tree (node);
7632     }
7633   return NULL_TREE;
7634 }
7635
7636 /* Construct the expression that calls an access method:
7637      <type>.access$<n>(<arg1> [, <arg2>]); 
7638
7639    ARG2 can be NULL and will be omitted in that case. It will denote a
7640    read access.  */
7641
7642 static tree
7643 build_outer_field_access_expr (lc, type, access_method_name, arg1, arg2)
7644     int lc;
7645     tree type, access_method_name, arg1, arg2;
7646 {
7647   tree args, cn, access;
7648
7649   args = arg1 ? arg1 : 
7650     build_wfl_node (build_current_thisn (current_class));
7651   args = build_tree_list (NULL_TREE, args);
7652
7653   if (arg2)
7654     args = tree_cons (NULL_TREE, arg2, args);
7655
7656   access = build_method_invocation (build_wfl_node (access_method_name), args);
7657   cn = build_wfl_node (DECL_NAME (TYPE_NAME (type)));
7658   return make_qualified_primary (cn, access, lc);
7659 }
7660
7661 static tree
7662 build_new_access_id ()
7663 {
7664   static int access_n_counter = 1;
7665   char buffer [128];
7666
7667   sprintf (buffer, "access$%d", access_n_counter++);
7668   return get_identifier (buffer);
7669 }
7670
7671 /* Create the static access functions for the outer field DECL. We define a
7672    read:
7673      TREE_TYPE (<field>) access$<n> (DECL_CONTEXT (<field>) inst$) {
7674        return inst$.field;
7675      }
7676    and a write access:
7677      TREE_TYPE (<field>) access$<n> (DECL_CONTEXT (<field>) inst$,
7678                                      TREE_TYPE (<field>) value$) {
7679        return inst$.field = value$;
7680      }
7681    We should have a usage flags on the DECL so we can lazily turn the ones
7682    we're using for code generation. FIXME.
7683 */
7684
7685 static tree
7686 build_outer_field_access_methods (decl)
7687     tree decl;
7688 {
7689   tree id, args, stmt, mdecl;
7690   
7691   /* Check point, to be removed. FIXME */
7692   if (FIELD_INNER_ACCESS (decl) 
7693       && TREE_CODE (FIELD_INNER_ACCESS (decl)) != IDENTIFIER_NODE)
7694     abort ();
7695
7696   if (FIELD_INNER_ACCESS (decl))
7697     return FIELD_INNER_ACCESS (decl);
7698
7699   push_obstacks (&permanent_obstack, &permanent_obstack);
7700
7701   /* Create the identifier and a function named after it. */
7702   id = build_new_access_id ();
7703
7704   /* The identifier is marked as bearing the name of a generated write
7705      access function for outer field accessed from inner classes. */
7706   OUTER_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
7707
7708   /* Create the read access */
7709   args = build_tree_list (inst_id, build_pointer_type (DECL_CONTEXT (decl)));
7710   TREE_CHAIN (args) = end_params_node;
7711   stmt = make_qualified_primary (build_wfl_node (inst_id),
7712                                  build_wfl_node (DECL_NAME (decl)), 0);
7713   stmt = build_return (0, stmt);
7714   mdecl = build_outer_field_access_method (DECL_CONTEXT (decl), 
7715                                            TREE_TYPE (decl), id, args, stmt);
7716   DECL_FUNCTION_ACCESS_DECL (mdecl) = decl;
7717
7718   /* Create the write access method */
7719   args = build_tree_list (inst_id, build_pointer_type (DECL_CONTEXT (decl)));
7720   TREE_CHAIN (args) = build_tree_list (wpv_id, TREE_TYPE (decl));
7721   TREE_CHAIN (TREE_CHAIN (args)) = end_params_node;
7722   stmt = make_qualified_primary (build_wfl_node (inst_id),
7723                                  build_wfl_node (DECL_NAME (decl)), 0);
7724   stmt = build_return (0, build_assignment (ASSIGN_TK, 0, stmt,
7725                                             build_wfl_node (wpv_id)));
7726
7727   mdecl = build_outer_field_access_method (DECL_CONTEXT (decl), 
7728                                            TREE_TYPE (decl), id, args, stmt);
7729   DECL_FUNCTION_ACCESS_DECL (mdecl) = decl;
7730   pop_obstacks ();
7731
7732   /* Return the access name */
7733   return FIELD_INNER_ACCESS (decl) = id;
7734 }
7735
7736 /* Build an field access method NAME.  */
7737
7738 static tree 
7739 build_outer_field_access_method (class, type, name, args, body)
7740     tree class, type, name, args, body;
7741 {
7742   tree saved_current_function_decl, mdecl;
7743
7744   /* Create the method */
7745   mdecl = create_artificial_method (class, ACC_STATIC, type, name, args);
7746   fix_method_argument_names (args, mdecl);
7747   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
7748
7749   /* Attach the method body. */
7750   saved_current_function_decl = current_function_decl;
7751   start_artificial_method_body (mdecl);
7752   java_method_add_stmt (mdecl, body);
7753   end_artificial_method_body (mdecl);
7754   current_function_decl = saved_current_function_decl;
7755
7756   return mdecl;
7757 }
7758
7759 \f
7760 /* This section deals with building access function necessary for
7761    certain kinds of method invocation from inner classes.  */
7762
7763 static tree
7764 build_outer_method_access_method (decl)
7765     tree decl;
7766 {
7767   tree saved_current_function_decl, mdecl;
7768   tree args = NULL_TREE, call_args = NULL_TREE;
7769   tree carg, id, body, class;
7770   char buffer [80];
7771   int parm_id_count = 0;
7772
7773   /* Test this abort with an access to a private field */
7774   if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), "access$"))
7775     abort ();
7776
7777   /* Check the cache first */
7778   if (DECL_FUNCTION_INNER_ACCESS (decl))
7779     return DECL_FUNCTION_INNER_ACCESS (decl);
7780
7781   class = DECL_CONTEXT (decl);
7782
7783   /* Obtain an access identifier and mark it */
7784   id = build_new_access_id ();
7785   OUTER_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
7786
7787   push_obstacks (&permanent_obstack, &permanent_obstack);
7788
7789   carg = TYPE_ARG_TYPES (TREE_TYPE (decl));
7790   /* Create the arguments, as much as the original */
7791   for (; carg && carg != end_params_node; 
7792        carg = TREE_CHAIN (carg))
7793     {
7794       sprintf (buffer, "write_parm_value$%d", parm_id_count++);
7795       args = chainon (args, build_tree_list (get_identifier (buffer), 
7796                                              TREE_VALUE (carg)));
7797     }
7798   args = chainon (args, end_params_node);
7799
7800   /* Create the method */
7801   mdecl = create_artificial_method (class, ACC_STATIC, 
7802                                     TREE_TYPE (TREE_TYPE (decl)), id, args);
7803   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
7804   /* There is a potential bug here. We should be able to use
7805      fix_method_argument_names, but then arg names get mixed up and
7806      eventually a constructor will have its this$0 altered and the
7807      outer context won't be assignment properly. The test case is
7808      stub.java FIXME */
7809   TYPE_ARG_TYPES (TREE_TYPE (mdecl)) = args;
7810
7811   /* Attach the method body. */
7812   saved_current_function_decl = current_function_decl;
7813   start_artificial_method_body (mdecl);
7814
7815   /* The actual method invocation uses the same args. When invoking a
7816      static methods that way, we don't want to skip the first
7817      argument. */
7818   carg = args;
7819   if (!METHOD_STATIC (decl))
7820     carg = TREE_CHAIN (carg);
7821   for (; carg && carg != end_params_node; carg = TREE_CHAIN (carg))
7822     call_args = tree_cons (NULL_TREE, build_wfl_node (TREE_PURPOSE (carg)),
7823                            call_args);
7824
7825   body = build_method_invocation (build_wfl_node (DECL_NAME (decl)), 
7826                                   call_args);
7827   if (!METHOD_STATIC (decl))
7828     body = make_qualified_primary (build_wfl_node (TREE_PURPOSE (args)), 
7829                                    body, 0);
7830   if (TREE_TYPE (TREE_TYPE (decl)) != void_type_node)
7831     body = build_return (0, body);
7832   java_method_add_stmt (mdecl,body);
7833   end_artificial_method_body (mdecl);
7834   current_function_decl = saved_current_function_decl;
7835   pop_obstacks ();
7836
7837   /* Back tag the access function so it know what it accesses */
7838   DECL_FUNCTION_ACCESS_DECL (decl) = mdecl;
7839
7840   /* Tag the current method so it knows it has an access generated */
7841   return DECL_FUNCTION_INNER_ACCESS (decl) = mdecl;
7842 }
7843
7844 \f
7845 /* This section of the code deals with building expressions to access
7846    the enclosing instance of an inner class. The enclosing instance is
7847    kept in a generated field called this$<n>, with <n> being the
7848    inner class nesting level (starting from 0.)  */
7849     
7850 /* Build an access to a given this$<n>, possibly by chaining access
7851    call to others. Access methods to this$<n> are build on the fly if
7852    necessary */
7853
7854 static tree
7855 build_access_to_thisn (from, to, lc)
7856      tree from, to;
7857      int lc;
7858 {
7859   tree access = NULL_TREE;
7860
7861   while (from != to)
7862     {
7863       tree access0_wfl, cn;
7864
7865       maybe_build_thisn_access_method (from);
7866       access0_wfl = build_wfl_node (access0_identifier_node);
7867       cn = build_wfl_node (DECL_NAME (TYPE_NAME (from)));
7868       EXPR_WFL_LINECOL (access0_wfl) = lc;
7869       
7870       if (!access)
7871         {
7872           access = build_current_thisn (current_class);
7873           access = build_wfl_node (access);
7874         }
7875       access = build_tree_list (NULL_TREE, access);
7876       access = build_method_invocation (access0_wfl, access);
7877       access = make_qualified_primary (cn, access, lc);
7878       
7879       from = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (from)));
7880     }
7881   return access;
7882 }
7883
7884 /* Build an access function to the this$<n> local to TYPE. NULL_TREE
7885    is returned if nothing needs to be generated. Otherwise, the method
7886    generated, fully walked and a method decl is returned.  
7887
7888    NOTE: These generated methods should be declared in a class file
7889    attribute so that they can't be referred to directly.  */
7890
7891 static tree
7892 maybe_build_thisn_access_method (type)
7893     tree type;
7894 {
7895   tree mdecl, args, stmt, rtype;
7896   tree saved_current_function_decl;
7897
7898   /* If TYPE is a top-level class, no access method is required.
7899      If there already is such an access method, bail out. */
7900   if (CLASS_ACCESS0_GENERATED_P (type) || !INNER_CLASS_TYPE_P (type))
7901     return NULL_TREE;
7902
7903   /* We generate the method. The method looks like:
7904      static <outer_of_type> access$0 (<type> inst$) { return inst$.this$<n>; }
7905   */
7906   push_obstacks (&permanent_obstack, &permanent_obstack);
7907   args = build_tree_list (inst_id, build_pointer_type (type));
7908   TREE_CHAIN (args) = end_params_node;
7909   rtype = build_pointer_type (TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))));
7910   mdecl = create_artificial_method (type, ACC_STATIC, rtype,
7911                                     access0_identifier_node, args);
7912   fix_method_argument_names (args, mdecl);
7913   layout_class_method (type, NULL_TREE, mdecl, NULL_TREE);
7914   stmt = build_current_thisn (type);
7915   stmt = make_qualified_primary (build_wfl_node (inst_id), 
7916                                  build_wfl_node (stmt), 0);
7917   stmt = build_return (0, stmt);
7918
7919   saved_current_function_decl = current_function_decl;
7920   start_artificial_method_body (mdecl);
7921   java_method_add_stmt (mdecl, stmt);
7922   end_artificial_method_body (mdecl);
7923   current_function_decl = saved_current_function_decl;
7924   pop_obstacks ();
7925
7926   CLASS_ACCESS0_GENERATED_P (type) = 1;
7927
7928   return mdecl;
7929 }
7930
7931 /* Craft an correctly numbered `this$<n>'string. this$0 is used for
7932    the first level of innerclassing. this$1 for the next one, etc...
7933    This function can be invoked with TYPE to NULL, available and then
7934    has to count the parser context.  */
7935
7936 static tree
7937 build_current_thisn (type)
7938     tree type;
7939 {
7940   static int saved_i = -1;
7941   static tree saved_thisn = NULL_TREE;
7942
7943   tree decl;
7944   char buffer [80];
7945   int i = 0;
7946
7947   if (type)
7948     {
7949       static tree saved_type = NULL_TREE;
7950       static int saved_type_i = 0;
7951
7952       if (type == saved_type)
7953         i = saved_type_i;
7954       else
7955         {
7956           for (i = -1, decl = DECL_CONTEXT (TYPE_NAME (type)); 
7957                decl; decl = DECL_CONTEXT (decl), i++)
7958             ;
7959       
7960           saved_type = type;
7961           saved_type_i = i;
7962         }
7963     }
7964   else
7965     i = list_length (GET_CPC_LIST ())-2;
7966
7967   if (i == saved_i)
7968     return saved_thisn;
7969     
7970   sprintf (buffer, "this$%d", i);
7971   saved_i = i;
7972   saved_thisn = get_identifier (buffer);
7973   return saved_thisn;
7974 }
7975
7976 /* Return the assignement to the hidden enclosing context `this$<n>'
7977    by the second incoming parameter to the innerclass constructor. The
7978    form used is `this.this$<n> = this$<n>;'.  */
7979
7980 static tree
7981 build_thisn_assign ()
7982 {
7983   if (current_class && PURE_INNER_CLASS_TYPE_P (current_class))
7984     {
7985       tree thisn = build_current_thisn (current_class);
7986       tree lhs = make_qualified_primary (build_wfl_node (this_identifier_node),
7987                                          build_wfl_node (thisn), 0);
7988       tree rhs = build_wfl_node (thisn);
7989       EXPR_WFL_SET_LINECOL (lhs, lineno, 0);
7990       return build_assignment (ASSIGN_TK, EXPR_WFL_LINECOL (lhs), lhs, rhs);
7991     }
7992   return NULL_TREE;
7993 }
7994
7995 \f
7996 /* Building the synthetic `class$' used to implement the `.class' 1.1
7997    extension for non primitive types. This method looks like:
7998
7999     static Class class$(String type) throws NoClassDefFoundError
8000     {
8001       try {return (java.lang.Class.forName (String));}
8002       catch (ClassNotFoundException e) {
8003         throw new NoClassDefFoundError(e.getMessage());}
8004     } */
8005
8006 static tree
8007 build_dot_class_method (class)
8008      tree class;
8009 {
8010 #define BWF(S) build_wfl_node (get_identifier ((S)))
8011 #define MQN(X,Y) make_qualified_name ((X), (Y), 0)
8012   tree args, tmp, saved_current_function_decl, mdecl;
8013   tree stmt, throw_stmt, catch, catch_block, try_block;
8014   tree catch_clause_param;
8015   tree class_not_found_exception, no_class_def_found_error;
8016
8017   static tree get_message_wfl, type_parm_wfl;
8018
8019   if (!get_message_wfl)
8020     {
8021       get_message_wfl = build_wfl_node (get_identifier ("getMessage"));
8022       type_parm_wfl = build_wfl_node (get_identifier ("type$"));
8023     }
8024
8025   /* Build the arguments */
8026   args = build_tree_list (get_identifier ("type$"),
8027                           build_pointer_type (string_type_node));
8028   TREE_CHAIN (args) = end_params_node;
8029
8030   /* Build the qualified name java.lang.Class.forName */
8031   tmp = MQN (MQN (MQN (BWF ("java"), 
8032                        BWF ("lang")), BWF ("Class")), BWF ("forName"));
8033
8034   /* For things we have to catch and throw */
8035   class_not_found_exception = 
8036     lookup_class (get_identifier ("java.lang.ClassNotFoundException"));
8037   no_class_def_found_error = 
8038     lookup_class (get_identifier ("java.lang.NoClassDefFoundError"));
8039   load_class (class_not_found_exception, 1);
8040   load_class (no_class_def_found_error, 1);
8041
8042   /* Create the "class$" function */
8043   mdecl = create_artificial_method (class, ACC_STATIC, 
8044                                     build_pointer_type (class_type_node),
8045                                     get_identifier ("class$"), args);
8046   DECL_FUNCTION_THROWS (mdecl) = build_tree_list (NULL_TREE,
8047                                                   no_class_def_found_error);
8048   
8049   /* We start by building the try block. We need to build:
8050        return (java.lang.Class.forName (type)); */
8051   stmt = build_method_invocation (tmp, 
8052                                   build_tree_list (NULL_TREE, type_parm_wfl));
8053   stmt = build_return (0, stmt);
8054   /* Put it in a block. That's the try block */
8055   try_block = build_expr_block (stmt, NULL_TREE);
8056
8057   /* Now onto the catch block. We start by building the expression
8058      throwing a new exception: 
8059        throw new NoClassDefFoundError (_.getMessage); */
8060   throw_stmt = make_qualified_name (build_wfl_node (wpv_id), 
8061                                     get_message_wfl, 0);
8062   throw_stmt = build_method_invocation (throw_stmt, NULL_TREE);
8063   
8064   /* Build new NoClassDefFoundError (_.getMessage) */
8065   throw_stmt = build_new_invocation 
8066     (build_wfl_node (get_identifier ("NoClassDefFoundError")),
8067      build_tree_list (build_pointer_type (string_type_node), throw_stmt));
8068
8069   /* Build the throw, (it's too early to use BUILD_THROW) */
8070   throw_stmt = build1 (THROW_EXPR, NULL_TREE, throw_stmt);
8071
8072   /* Build the catch block to encapsulate all this. We begin by
8073      building an decl for the catch clause parameter and link it to
8074      newly created block, the catch block. */
8075   catch_clause_param = 
8076     build_decl (VAR_DECL, wpv_id, 
8077                 build_pointer_type (class_not_found_exception));
8078   catch_block = build_expr_block (NULL_TREE, catch_clause_param);
8079   
8080   /* We initialize the variable with the exception handler. */
8081   catch = build (MODIFY_EXPR, NULL_TREE, catch_clause_param,
8082                  soft_exceptioninfo_call_node);
8083   add_stmt_to_block (catch_block, NULL_TREE, catch);
8084
8085   /* We add the statement throwing the new exception */
8086   add_stmt_to_block (catch_block, NULL_TREE, throw_stmt);
8087
8088   /* Build a catch expression for all this */
8089   catch_block = build1 (CATCH_EXPR, NULL_TREE, catch_block);
8090
8091   /* Build the try/catch sequence */
8092   stmt = build_try_statement (0, try_block, catch_block);
8093
8094   fix_method_argument_names (args, mdecl);
8095   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
8096   saved_current_function_decl = current_function_decl;
8097   start_artificial_method_body (mdecl);
8098   java_method_add_stmt (mdecl, stmt);
8099   end_artificial_method_body (mdecl);
8100   current_function_decl = saved_current_function_decl;
8101   TYPE_DOT_CLASS (class) = mdecl;
8102
8103   return mdecl;
8104 }
8105
8106 static tree
8107 build_dot_class_method_invocation (name)
8108      tree name;
8109 {
8110   tree s = make_node (STRING_CST);
8111   TREE_STRING_LENGTH (s) = IDENTIFIER_LENGTH (name);
8112   TREE_STRING_POINTER (s) = obstack_alloc (expression_obstack,
8113                                            TREE_STRING_LENGTH (s)+1);
8114   strcpy (TREE_STRING_POINTER (s), IDENTIFIER_POINTER (name));
8115   return build_method_invocation (build_wfl_node (get_identifier ("class$")),
8116                                   build_tree_list (NULL_TREE, s));
8117 }
8118
8119 /* This section of the code deals with constructor.  */
8120
8121 /* Craft a body for default constructor. Patch existing constructor
8122    bodies with call to super() and field initialization statements if
8123    necessary.  */
8124
8125 static void
8126 fix_constructors (mdecl)
8127      tree mdecl;
8128 {
8129   tree body = DECL_FUNCTION_BODY (mdecl);
8130   tree thisn_assign, compound = NULL_TREE;
8131   tree class_type = DECL_CONTEXT (mdecl);
8132
8133   if (!body)
8134     {
8135       /* It is an error for the compiler to generate a default
8136          constructor if the superclass doesn't have a constructor that
8137          takes no argument, or the same args for an anonymous class */
8138       if (verify_constructor_super (mdecl))
8139         {
8140           tree sclass_decl = TYPE_NAME (CLASSTYPE_SUPER (class_type));
8141           tree save = DECL_NAME (mdecl);
8142           const char *n = IDENTIFIER_POINTER (DECL_NAME (sclass_decl));
8143           DECL_NAME (mdecl) = DECL_NAME (sclass_decl);
8144           parse_error_context
8145             (lookup_cl (TYPE_NAME (class_type)), 
8146              "No constructor matching `%s' found in class `%s'",
8147              lang_printable_name (mdecl, 0), n);
8148           DECL_NAME (mdecl) = save;
8149         }
8150       
8151       /* The constructor body must be crafted by hand. It's the
8152          constructor we defined when we realize we didn't have the
8153          CLASSNAME() constructor */
8154       start_artificial_method_body (mdecl);
8155       
8156       /* We don't generate a super constructor invocation if we're
8157          compiling java.lang.Object. build_super_invocation takes care
8158          of that. */
8159       compound = java_method_add_stmt (mdecl, build_super_invocation (mdecl));
8160
8161       /* Insert the instance initializer block right here, after the
8162          super invocation. */
8163       add_instance_initializer (mdecl);
8164
8165       /* Insert an assignment to the this$<n> hidden field, if
8166          necessary */
8167       if ((thisn_assign = build_thisn_assign ()))
8168         java_method_add_stmt (mdecl, thisn_assign);
8169
8170       end_artificial_method_body (mdecl);
8171     }
8172   /* Search for an explicit constructor invocation */
8173   else 
8174     {
8175       int found = 0;
8176       tree main_block = BLOCK_EXPR_BODY (body);
8177       
8178       while (body)
8179         switch (TREE_CODE (body))
8180           {
8181           case CALL_EXPR:
8182             found = CALL_EXPLICIT_CONSTRUCTOR_P (body);
8183             body = NULL_TREE;
8184             break;
8185           case COMPOUND_EXPR:
8186           case EXPR_WITH_FILE_LOCATION:
8187             body = TREE_OPERAND (body, 0);
8188             break;
8189           case BLOCK:
8190             body = BLOCK_EXPR_BODY (body);
8191             break;
8192           default:
8193             found = 0;
8194             body = NULL_TREE;
8195           }
8196       /* The constructor is missing an invocation of super() */
8197       if (!found)
8198         compound = add_stmt_to_compound (compound, NULL_TREE,
8199                                          build_super_invocation (mdecl));
8200       
8201       /* Insert the instance initializer block right here, after the
8202          super invocation. */
8203       add_instance_initializer (mdecl);
8204
8205       /* Generate the assignment to this$<n>, if necessary */
8206       if ((thisn_assign = build_thisn_assign ()))
8207         compound = add_stmt_to_compound (compound, NULL_TREE, thisn_assign);
8208
8209       /* Fix the constructor main block if we're adding extra stmts */
8210       if (compound)
8211         {
8212           compound = add_stmt_to_compound (compound, NULL_TREE,
8213                                            BLOCK_EXPR_BODY (main_block));
8214           BLOCK_EXPR_BODY (main_block) = compound;
8215         }
8216     }
8217 }
8218
8219 /* Browse constructors in the super class, searching for a constructor
8220    that doesn't take any argument. Return 0 if one is found, 1
8221    otherwise.  If the current class is an anonymous inner class, look
8222    for something that has the same signature. */
8223
8224 static int
8225 verify_constructor_super (mdecl)
8226      tree mdecl;
8227 {
8228   tree class = CLASSTYPE_SUPER (current_class);
8229   tree sdecl;
8230
8231   if (!class)
8232     return 0;
8233
8234   if (ANONYMOUS_CLASS_P (current_class))
8235     {
8236       tree mdecl_arg_type;
8237       SKIP_THIS_AND_ARTIFICIAL_PARMS (mdecl_arg_type, mdecl);
8238       for (sdecl = TYPE_METHODS (class); sdecl; sdecl = TREE_CHAIN (sdecl))
8239         if (DECL_CONSTRUCTOR_P (sdecl))
8240           {
8241             tree arg_type;
8242             for (arg_type = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (sdecl)));
8243                  arg_type != end_params_node && 
8244                    mdecl_arg_type != end_params_node;
8245                  arg_type = TREE_CHAIN (arg_type), 
8246                  mdecl_arg_type = TREE_CHAIN (mdecl_arg_type))
8247               if (TREE_VALUE (arg_type) != TREE_VALUE (mdecl_arg_type))
8248                 break;
8249
8250             if (arg_type == end_params_node && 
8251                 mdecl_arg_type == end_params_node)
8252               return 0;
8253           }
8254     }
8255   else
8256     {
8257       for (sdecl = TYPE_METHODS (class); sdecl; sdecl = TREE_CHAIN (sdecl))
8258         {
8259           if (DECL_CONSTRUCTOR_P (sdecl)
8260               && TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (sdecl))) 
8261                  == end_params_node)
8262             return 0;
8263         }
8264     }
8265   return 1;
8266 }
8267
8268 /* Generate code for all context remembered for code generation.  */
8269
8270 void
8271 java_expand_classes ()
8272 {
8273   int save_error_count = 0;
8274   static struct parser_ctxt *saved_ctxp = NULL;
8275
8276   java_parse_abort_on_error ();
8277   if (!(ctxp = ctxp_for_generation))
8278     return;
8279   java_layout_classes ();
8280   java_parse_abort_on_error ();
8281
8282   /* The list of packages declaration seen so far needs to be
8283      reversed, so that package declared in a file being compiled gets
8284      priority over packages declared as a side effect of parsing other
8285      files.*/
8286   package_list = nreverse (package_list);
8287
8288   saved_ctxp = ctxp_for_generation;
8289   for (; ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
8290     {
8291       ctxp = ctxp_for_generation;
8292       lang_init_source (2);            /* Error msgs have method prototypes */
8293       java_complete_expand_classes (); /* Complete and expand classes */
8294       java_parse_abort_on_error ();
8295     }
8296
8297   /* Find anonymous classes and expand their constructor, now they
8298      have been fixed. */
8299   for (ctxp_for_generation = saved_ctxp;
8300        ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
8301     {
8302       tree current;
8303       ctxp = ctxp_for_generation;
8304       for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
8305         {
8306           current_class = TREE_TYPE (current);
8307           if (ANONYMOUS_CLASS_P (current_class))
8308             {
8309               tree d;
8310               for (d = TYPE_METHODS (current_class); d; d = TREE_CHAIN (d))
8311                 {
8312                   if (DECL_CONSTRUCTOR_P (d))
8313                     {
8314                       restore_line_number_status (1);
8315                       reset_method_name (d);
8316                       java_complete_expand_method (d);
8317                       restore_line_number_status (0);
8318                       break;    /* We now there are no other ones */
8319                     }
8320                 }
8321             }
8322         }
8323     }
8324
8325   /* If we've found error at that stage, don't try to generate
8326      anything, unless we're emitting xrefs or checking the syntax only
8327      (but not using -fsyntax-only for the purpose of generating
8328      bytecode. */
8329   if (java_error_count && !flag_emit_xref 
8330       && (!flag_syntax_only && !flag_emit_class_files))
8331     return;
8332
8333   /* Now things are stable, go for generation of the class data. */
8334   for (ctxp_for_generation = saved_ctxp;
8335        ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
8336     {
8337       tree current;
8338       ctxp = ctxp_for_generation;
8339       for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
8340         {
8341           current_class = TREE_TYPE (current);
8342           outgoing_cpool = TYPE_CPOOL (current_class);
8343           if (flag_emit_class_files)
8344             write_classfile (current_class);
8345           if (flag_emit_xref)
8346             expand_xref (current_class);
8347           else if (! flag_syntax_only)
8348             finish_class ();
8349         }
8350     }
8351 }
8352
8353 /* Wrap non WFL PRIMARY around a WFL and set EXPR_WFL_QUALIFICATION to
8354    a tree list node containing RIGHT. Fore coming RIGHTs will be
8355    chained to this hook. LOCATION contains the location of the
8356    separating `.' operator.  */
8357
8358 static tree
8359 make_qualified_primary (primary, right, location)
8360      tree primary, right;
8361      int location;
8362 {
8363   tree wfl;
8364
8365   if (TREE_CODE (primary) != EXPR_WITH_FILE_LOCATION)
8366     wfl = build_wfl_wrap (primary);
8367   else
8368     {
8369       wfl = primary;
8370       /* If wfl wasn't qualified, we build a first anchor */
8371       if (!EXPR_WFL_QUALIFICATION (wfl))
8372         EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (wfl, NULL_TREE);
8373     }
8374
8375   /* And chain them */
8376   EXPR_WFL_LINECOL (right) = location;
8377   chainon (EXPR_WFL_QUALIFICATION (wfl), build_tree_list (right, NULL_TREE));
8378   PRIMARY_P (wfl) =  1;
8379   return wfl;
8380 }
8381
8382 /* Simple merge of two name separated by a `.' */
8383
8384 static tree
8385 merge_qualified_name (left, right)
8386      tree left, right;
8387 {
8388   tree node;
8389   if (!left && !right)
8390     return NULL_TREE;
8391
8392   if (!left)
8393     return right;
8394
8395   if (!right)
8396     return left;
8397
8398   obstack_grow (&temporary_obstack, IDENTIFIER_POINTER (left),
8399                 IDENTIFIER_LENGTH (left));
8400   obstack_1grow (&temporary_obstack, '.');
8401   obstack_grow0 (&temporary_obstack, IDENTIFIER_POINTER (right),
8402                  IDENTIFIER_LENGTH (right));
8403   node =  get_identifier (obstack_base (&temporary_obstack));
8404   obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
8405   QUALIFIED_P (node) = 1;
8406   return node;
8407 }
8408
8409 /* Merge the two parts of a qualified name into LEFT.  Set the
8410    location information of the resulting node to LOCATION, usually
8411    inherited from the location information of the `.' operator. */
8412
8413 static tree
8414 make_qualified_name (left, right, location)
8415      tree left, right;
8416      int location;
8417 {
8418 #ifdef USE_COMPONENT_REF
8419   tree node = build (COMPONENT_REF, NULL_TREE, left, right);
8420   EXPR_WFL_LINECOL (node) = location;
8421   return node;
8422 #else
8423   tree left_id = EXPR_WFL_NODE (left);
8424   tree right_id = EXPR_WFL_NODE (right);
8425   tree wfl, merge;
8426
8427   merge = merge_qualified_name (left_id, right_id);
8428
8429   /* Left wasn't qualified and is now qualified */
8430   if (!QUALIFIED_P (left_id))
8431     {
8432       tree wfl = build_expr_wfl (left_id, ctxp->filename, 0, 0);
8433       EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (left);
8434       EXPR_WFL_QUALIFICATION (left) = build_tree_list (wfl, NULL_TREE);
8435     }
8436   
8437   wfl = build_expr_wfl (right_id, ctxp->filename, 0, 0);
8438   EXPR_WFL_LINECOL (wfl) = location;
8439   chainon (EXPR_WFL_QUALIFICATION (left), build_tree_list (wfl, NULL_TREE));
8440
8441   EXPR_WFL_NODE (left) = merge;
8442   return left;
8443 #endif
8444 }
8445
8446 /* Extract the last identifier component of the qualified in WFL. The
8447    last identifier is removed from the linked list */
8448
8449 static tree
8450 cut_identifier_in_qualified (wfl)
8451      tree wfl;
8452 {
8453   tree q;
8454   tree previous = NULL_TREE;
8455   for (q = EXPR_WFL_QUALIFICATION (wfl); ; previous = q, q = TREE_CHAIN (q))
8456     if (!TREE_CHAIN (q))
8457       {
8458         if (!previous)
8459           fatal ("Operating on a non qualified qualified WFL - cut_identifier_in_qualified");
8460         TREE_CHAIN (previous) = NULL_TREE;
8461         return TREE_PURPOSE (q);
8462       }
8463 }
8464
8465 /* Resolve the expression name NAME. Return its decl.  */
8466
8467 static tree
8468 resolve_expression_name (id, orig)
8469      tree id;
8470      tree *orig;
8471 {
8472   tree name = EXPR_WFL_NODE (id);
8473   tree decl;
8474
8475   /* 6.5.5.1: Simple expression names */
8476   if (!PRIMARY_P (id) && !QUALIFIED_P (name))
8477     {
8478       /* 15.13.1: NAME can appear within the scope of a local variable
8479          declaration */
8480       if ((decl = IDENTIFIER_LOCAL_VALUE (name)))
8481         return decl;
8482
8483       /* 15.13.1: NAME can appear within a class declaration */
8484       else 
8485         {
8486           decl = lookup_field_wrapper (current_class, name);
8487           if (decl)
8488             {
8489               tree access = NULL_TREE;
8490               int fs = FIELD_STATIC (decl);
8491
8492               /* If we're accessing an outer scope local alias, make
8493                  sure we change the name of the field we're going to
8494                  build access to. */
8495               if (FIELD_LOCAL_ALIAS_USED (decl))
8496                 name = DECL_NAME (decl);
8497
8498               /* Instance variable (8.3.1.1) can't appear within
8499                  static method, static initializer or initializer for
8500                  a static variable. */
8501               if (!fs && METHOD_STATIC (current_function_decl))
8502                 {
8503                   static_ref_err (id, name, current_class);
8504                   return error_mark_node;
8505                 }
8506               /* Instance variables can't appear as an argument of
8507                  an explicit constructor invocation */
8508               if (!fs && ctxp->explicit_constructor_p)
8509                 {
8510                   parse_error_context
8511                     (id, "Can't reference `%s' before the superclass constructor has been called", IDENTIFIER_POINTER (name));
8512                   return error_mark_node;
8513                 }
8514
8515               /* If we're processing an inner class and we're trying
8516                  to access a field belonging to an outer class, build
8517                  the access to the field */
8518               if (!fs && outer_field_access_p (current_class, decl))
8519                 return build_outer_field_access (id, decl);
8520
8521               /* Otherwise build what it takes to access the field */
8522               access = build_field_ref ((fs ? NULL_TREE : current_this),
8523                                         DECL_CONTEXT (decl), name);
8524               if (fs && !flag_emit_class_files && !flag_emit_xref)
8525                 access = build_class_init (DECL_CONTEXT (access), access);
8526               /* We may be asked to save the real field access node */
8527               if (orig)
8528                 *orig = access;
8529               /* And we return what we got */
8530               return access;
8531             }
8532           /* Fall down to error report on undefined variable */
8533         }
8534     }
8535   /* 6.5.5.2 Qualified Expression Names */
8536   else
8537     {
8538       if (orig)
8539         *orig = NULL_TREE;
8540       qualify_ambiguous_name (id);
8541       /* 15.10.1 Field Access Using a Primary and/or Expression Name */
8542       /* 15.10.2: Accessing Superclass Members using super */
8543       return resolve_field_access (id, orig, NULL);
8544     }
8545
8546   /* We've got an error here */
8547   parse_error_context (id, "Undefined variable `%s'", 
8548                        IDENTIFIER_POINTER (name));
8549
8550   return error_mark_node;
8551 }
8552
8553 static void
8554 static_ref_err (wfl, field_id, class_type)
8555     tree wfl, field_id, class_type;
8556 {
8557   parse_error_context 
8558     (wfl, 
8559      "Can't make a static reference to nonstatic variable `%s' in class `%s'",
8560      IDENTIFIER_POINTER (field_id), 
8561      IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class_type))));
8562 }
8563
8564 /* 15.10.1 Field Acess Using a Primary and/or Expression Name.
8565    We return something suitable to generate the field access. We also
8566    return the field decl in FIELD_DECL and its type in FIELD_TYPE.  If
8567    recipient's address can be null. */
8568
8569 static tree
8570 resolve_field_access (qual_wfl, field_decl, field_type)
8571      tree qual_wfl;
8572      tree *field_decl, *field_type;
8573 {
8574   int is_static = 0;
8575   tree field_ref;
8576   tree decl, where_found, type_found;
8577
8578   if (resolve_qualified_expression_name (qual_wfl, &decl,
8579                                          &where_found, &type_found))
8580     return error_mark_node;
8581
8582   /* Resolve the LENGTH field of an array here */
8583   if (DECL_NAME (decl) == length_identifier_node && TYPE_ARRAY_P (type_found)
8584       && ! flag_emit_class_files && ! flag_emit_xref)
8585     {
8586       tree length = build_java_array_length_access (where_found);
8587       field_ref =
8588         build_java_arraynull_check (type_found, length, int_type_node);
8589     }
8590   /* We might have been trying to resolve field.method(). In which
8591      case, the resolution is over and decl is the answer */
8592   else if (JDECL_P (decl) && IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)) == decl)
8593     field_ref = decl;
8594   else if (JDECL_P (decl))
8595     {
8596       int static_final_found = 0;
8597       if (!type_found)
8598         type_found = DECL_CONTEXT (decl);
8599       is_static = JDECL_P (decl) && FIELD_STATIC (decl);
8600       if (FIELD_FINAL (decl) 
8601           && JPRIMITIVE_TYPE_P (TREE_TYPE (decl))
8602           && DECL_LANG_SPECIFIC (decl)
8603           && DECL_INITIAL (decl))
8604         {
8605           field_ref = DECL_INITIAL (decl);
8606           static_final_found = 1;
8607         }
8608       else
8609         field_ref = build_field_ref ((is_static && !flag_emit_xref? 
8610                                       NULL_TREE : where_found), 
8611                                      type_found, DECL_NAME (decl));
8612       if (field_ref == error_mark_node)
8613         return error_mark_node;
8614       if (is_static && !static_final_found 
8615           && !flag_emit_class_files && !flag_emit_xref)
8616         field_ref = build_class_init (type_found, field_ref);
8617     }
8618   else
8619     field_ref = decl;
8620
8621   if (field_decl)
8622     *field_decl = decl;
8623   if (field_type)
8624     *field_type = (QUAL_DECL_TYPE (decl) ? 
8625                    QUAL_DECL_TYPE (decl) : TREE_TYPE (decl));
8626   return field_ref;
8627 }
8628
8629 /* If NODE is an access to f static field, strip out the class
8630    initialization part and return the field decl, otherwise, return
8631    NODE. */
8632
8633 static tree
8634 strip_out_static_field_access_decl (node)
8635     tree node;
8636 {
8637   if (TREE_CODE (node) == COMPOUND_EXPR)
8638     {
8639       tree op1 = TREE_OPERAND (node, 1);
8640       if (TREE_CODE (op1) == COMPOUND_EXPR)
8641          {
8642            tree call = TREE_OPERAND (op1, 0);
8643            if (TREE_CODE (call) == CALL_EXPR
8644                && TREE_CODE (TREE_OPERAND (call, 0)) == ADDR_EXPR
8645                && TREE_OPERAND (TREE_OPERAND (call, 0), 0)
8646                == soft_initclass_node)
8647              return TREE_OPERAND (op1, 1);
8648          }
8649       else if (JDECL_P (op1))
8650         return op1;
8651     }
8652   return node;
8653 }
8654
8655 /* 6.5.5.2: Qualified Expression Names */
8656
8657 static int
8658 resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
8659      tree wfl;
8660      tree *found_decl, *type_found, *where_found;
8661 {
8662   int from_type = 0;            /* Field search initiated from a type */
8663   int from_super = 0, from_cast = 0, from_qualified_this = 0;
8664   int previous_call_static = 0;
8665   int is_static;
8666   tree decl = NULL_TREE, type = NULL_TREE, q;
8667   /* For certain for of inner class instantiation */
8668   tree saved_current, saved_this;               
8669 #define RESTORE_THIS_AND_CURRENT_CLASS                          \
8670   { current_class = saved_current; current_this = saved_this;}
8671
8672   *type_found = *where_found = NULL_TREE;
8673
8674   for (q = EXPR_WFL_QUALIFICATION (wfl); q; q = TREE_CHAIN (q))
8675     {
8676       tree qual_wfl = QUAL_WFL (q);
8677       tree ret_decl;            /* for EH checking */
8678       int location;             /* for EH checking */
8679
8680       /* 15.10.1 Field Access Using a Primary */
8681       switch (TREE_CODE (qual_wfl))
8682         {
8683         case CALL_EXPR:
8684         case NEW_CLASS_EXPR:
8685           /* If the access to the function call is a non static field,
8686              build the code to access it. */
8687           if (JDECL_P (decl) && !FIELD_STATIC (decl))
8688             {
8689               decl = maybe_access_field (decl, *where_found, 
8690                                          DECL_CONTEXT (decl));
8691               if (decl == error_mark_node)
8692                 return 1;
8693             }
8694
8695           /* And code for the function call */
8696           if (complete_function_arguments (qual_wfl))
8697             return 1;
8698
8699           /* We might have to setup a new current class and a new this
8700              for the search of an inner class, relative to the type of
8701              a expression resolved as `decl'. The current values are
8702              saved and restored shortly after */
8703           saved_current = current_class;
8704           saved_this = current_this;
8705           if (decl && TREE_CODE (qual_wfl) == NEW_CLASS_EXPR)
8706             {
8707               current_class = type;
8708               current_this = decl;
8709             }
8710
8711           if (from_super && TREE_CODE (qual_wfl) == CALL_EXPR)
8712             CALL_USING_SUPER (qual_wfl) = 1;
8713           location = (TREE_CODE (qual_wfl) == CALL_EXPR ?
8714                       EXPR_WFL_LINECOL (TREE_OPERAND (qual_wfl, 0)) : 0);
8715           *where_found = patch_method_invocation (qual_wfl, decl, type, 
8716                                                   &is_static, &ret_decl);
8717           if (*where_found == error_mark_node)
8718             {
8719               RESTORE_THIS_AND_CURRENT_CLASS;
8720               return 1;
8721             }
8722           *type_found = type = QUAL_DECL_TYPE (*where_found);
8723
8724           /* If we're creating an inner class instance, check for that
8725              an enclosing instance is in scope */
8726           if (TREE_CODE (qual_wfl) == NEW_CLASS_EXPR
8727               && INNER_ENCLOSING_SCOPE_CHECK (type))
8728             {
8729               parse_error_context 
8730                 (qual_wfl, "No enclosing instance for inner class `%s' is in scope%s",
8731                  lang_printable_name (type, 0),
8732                  (!current_this ? "" :
8733                   "; an explicit one must be provided when creating this inner class"));
8734               RESTORE_THIS_AND_CURRENT_CLASS;
8735               return 1;
8736             }
8737
8738           /* In case we had to change then to resolve a inner class
8739              instantiation using a primary qualified by a `new' */
8740           RESTORE_THIS_AND_CURRENT_CLASS;
8741
8742           /* EH check */
8743           if (location)
8744             check_thrown_exceptions (location, ret_decl);
8745
8746           /* If the previous call was static and this one is too,
8747              build a compound expression to hold the two (because in
8748              that case, previous function calls aren't transported as
8749              forcoming function's argument. */
8750           if (previous_call_static && is_static)
8751             {
8752               decl = build (COMPOUND_EXPR, type, decl, *where_found);
8753               TREE_SIDE_EFFECTS (decl) = 1;
8754             }
8755           else
8756             {
8757               previous_call_static = is_static;
8758               decl = *where_found;
8759             }
8760           from_type = 0;
8761           continue;
8762
8763         case NEW_ARRAY_EXPR:
8764         case NEW_ANONYMOUS_ARRAY_EXPR:
8765           *where_found = decl = java_complete_tree (qual_wfl);
8766           if (decl == error_mark_node)
8767             return 1;
8768           *type_found = type = QUAL_DECL_TYPE (decl);
8769           CLASS_LOADED_P (type) = 1;
8770           continue;
8771
8772         case CONVERT_EXPR:
8773           *where_found = decl = java_complete_tree (qual_wfl);
8774           if (decl == error_mark_node)
8775             return 1;
8776           *type_found = type = QUAL_DECL_TYPE (decl);
8777           from_cast = 1;
8778           continue;
8779
8780         case CONDITIONAL_EXPR:
8781         case STRING_CST:
8782         case MODIFY_EXPR:
8783           *where_found = decl = java_complete_tree (qual_wfl);
8784           if (decl == error_mark_node)
8785             return 1;
8786           *type_found = type = QUAL_DECL_TYPE (decl);
8787           continue;
8788
8789         case ARRAY_REF:
8790           /* If the access to the function call is a non static field,
8791              build the code to access it. */
8792           if (JDECL_P (decl) && !FIELD_STATIC (decl))
8793             {
8794               decl = maybe_access_field (decl, *where_found, type);
8795               if (decl == error_mark_node)
8796                 return 1;
8797             }
8798           /* And code for the array reference expression */
8799           decl = java_complete_tree (qual_wfl);
8800           if (decl == error_mark_node)
8801             return 1;
8802           type = QUAL_DECL_TYPE (decl);
8803           continue;
8804
8805         case PLUS_EXPR:
8806           if ((decl = java_complete_tree (qual_wfl)) == error_mark_node)
8807             return 1;
8808           if ((type = patch_string (decl)))
8809             decl = type;
8810           *where_found = QUAL_RESOLUTION (q) = decl;
8811           *type_found = type = TREE_TYPE (decl);
8812           break;
8813
8814         case CLASS_LITERAL:
8815           if ((decl = java_complete_tree (qual_wfl)) == error_mark_node)
8816             return 1;
8817           *where_found = QUAL_RESOLUTION (q) = decl;
8818           *type_found = type = TREE_TYPE (decl);
8819           break;
8820
8821         default:
8822           /* Fix for -Wall Just go to the next statement. Don't
8823              continue */
8824           break;
8825         }
8826
8827       /* If we fall here, we weren't processing a (static) function call. */
8828       previous_call_static = 0;
8829
8830       /* It can be the keyword THIS */
8831       if (EXPR_WFL_NODE (qual_wfl) == this_identifier_node)
8832         {
8833           if (!current_this)
8834             {
8835               parse_error_context 
8836                 (wfl, "Keyword `this' used outside allowed context");
8837               return 1;
8838             }
8839           if (ctxp->explicit_constructor_p)
8840             {
8841               parse_error_context (wfl, "Can't reference `this' before the superclass constructor has been called");
8842               return 1;
8843             }
8844           /* We have to generate code for intermediate acess */
8845           if (!from_type || TREE_TYPE (TREE_TYPE (current_this)) == type)
8846             {
8847               *where_found = decl = current_this;
8848               *type_found = type = QUAL_DECL_TYPE (decl);
8849             }
8850           /* We're trying to access the this from somewhere else... */
8851           else
8852             {
8853               *where_found = decl = build_current_thisn (type);
8854               from_qualified_this = 1;
8855             }
8856
8857           from_type = 0;
8858           continue;
8859         }
8860
8861       /* 15.10.2 Accessing Superclass Members using SUPER */
8862       if (EXPR_WFL_NODE (qual_wfl) == super_identifier_node)
8863         {
8864           tree node;
8865           /* Check on the restricted use of SUPER */
8866           if (METHOD_STATIC (current_function_decl)
8867               || current_class == object_type_node)
8868             {
8869               parse_error_context 
8870                 (wfl, "Keyword `super' used outside allowed context");
8871               return 1;
8872             }
8873           /* Otherwise, treat SUPER as (SUPER_CLASS)THIS */
8874           node = build_cast (EXPR_WFL_LINECOL (qual_wfl), 
8875                              CLASSTYPE_SUPER (current_class),
8876                              build_this (EXPR_WFL_LINECOL (qual_wfl)));
8877           *where_found = decl = java_complete_tree (node);
8878           if (decl == error_mark_node)
8879             return 1;
8880           *type_found = type = QUAL_DECL_TYPE (decl);
8881           from_super = from_type = 1;
8882           continue;
8883         }
8884
8885       /* 15.13.1: Can't search for field name in packages, so we
8886          assume a variable/class name was meant. */
8887       if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
8888         {
8889           tree name = resolve_package (wfl, &q);
8890           if (name)
8891             {
8892               tree list;
8893               *where_found = decl = resolve_no_layout (name, qual_wfl);
8894               /* We wan't to be absolutely that the class is laid
8895                  out. We're going to search something inside it. */
8896               *type_found = type = TREE_TYPE (decl);
8897               layout_class (type);
8898               from_type = 1;
8899
8900               /* Fix them all the way down, if any are left. */
8901               if (q)
8902                 {
8903                   list = TREE_CHAIN (q);
8904                   while (list)
8905                     {
8906                       RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (list)) = 1;
8907                       RESOLVE_PACKAGE_NAME_P (QUAL_WFL (list)) = 0;
8908                       list = TREE_CHAIN (list);
8909                     }
8910                 }
8911             }
8912           else
8913             {
8914               if (from_super || from_cast)
8915                 parse_error_context 
8916                   ((from_cast ? qual_wfl : wfl),
8917                    "No variable `%s' defined in class `%s'",
8918                    IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
8919                    lang_printable_name (type, 0));
8920               else
8921                 parse_error_context
8922                   (qual_wfl, "Undefined variable or class name: `%s'",
8923                    IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)));
8924               return 1;
8925             }
8926         }
8927
8928       /* We have a type name. It's been already resolved when the
8929          expression was qualified. */
8930       else if (RESOLVE_TYPE_NAME_P (qual_wfl))
8931         {
8932           if (!(decl = QUAL_RESOLUTION (q)))
8933             return 1;           /* Error reported already */
8934
8935           /* Sneak preview. If next we see a `new', we're facing a
8936              qualification with resulted in a type being selected
8937              instead of a field.  Report the error */
8938           if(TREE_CHAIN (q) 
8939              && TREE_CODE (TREE_PURPOSE (TREE_CHAIN (q))) == NEW_CLASS_EXPR)
8940             {
8941               parse_error_context (qual_wfl, "Undefined variable `%s'",
8942                                    IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
8943               return 1;
8944             }
8945
8946           if (not_accessible_p (TREE_TYPE (decl), decl, 0))
8947             {
8948               parse_error_context 
8949                 (qual_wfl, "Can't access %s field `%s.%s' from `%s'",
8950                  java_accstring_lookup (get_access_flags_from_decl (decl)),
8951                  GET_TYPE_NAME (type),
8952                  IDENTIFIER_POINTER (DECL_NAME (decl)),
8953                  IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
8954               return 1;
8955             }
8956           check_deprecation (qual_wfl, decl);
8957
8958           type = TREE_TYPE (decl);
8959           from_type = 1;
8960         }
8961       /* We resolve and expression name */
8962       else 
8963         {
8964           tree field_decl = NULL_TREE;
8965
8966           /* If there exists an early resolution, use it. That occurs
8967              only once and we know that there are more things to
8968              come. Don't do that when processing something after SUPER
8969              (we need more thing to be put in place below */
8970           if (!from_super && QUAL_RESOLUTION (q))
8971             {
8972               decl = QUAL_RESOLUTION (q);
8973               if (!type)
8974                 {
8975                   if (TREE_CODE (decl) == FIELD_DECL && !FIELD_STATIC (decl))
8976                     {
8977                       if (current_this)
8978                         *where_found = current_this;
8979                       else
8980                         {
8981                           static_ref_err (qual_wfl, DECL_NAME (decl),
8982                                           current_class);
8983                           return 1;
8984                         }
8985                     }
8986                   else
8987                     {
8988                       *where_found = TREE_TYPE (decl);
8989                       if (TREE_CODE (*where_found) == POINTER_TYPE)
8990                         *where_found = TREE_TYPE (*where_found);
8991                     }
8992                 }
8993             }
8994
8995           /* We have to search for a field, knowing the type of its
8996              container. The flag FROM_TYPE indicates that we resolved
8997              the last member of the expression as a type name, which
8998              means that for the resolution of this field, we'll look
8999              for other errors than if it was resolved as a member of
9000              an other field. */
9001           else
9002             {
9003               int is_static;
9004               tree field_decl_type; /* For layout */
9005
9006               if (!from_type && !JREFERENCE_TYPE_P (type))
9007                 {
9008                   parse_error_context 
9009                     (qual_wfl, "Attempt to reference field `%s' in `%s %s'",
9010                      IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
9011                      lang_printable_name (type, 0),
9012                      IDENTIFIER_POINTER (DECL_NAME (field_decl)));
9013                   return 1;
9014                 }
9015               
9016               field_decl = lookup_field_wrapper (type,
9017                                                  EXPR_WFL_NODE (qual_wfl));
9018               if (field_decl == NULL_TREE)
9019                 {
9020                   parse_error_context 
9021                     (qual_wfl, "No variable `%s' defined in type `%s'",
9022                      IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)), 
9023                      GET_TYPE_NAME (type));
9024                   return 1;
9025                 }
9026               if (field_decl == error_mark_node)
9027                 return 1;
9028
9029               /* Layout the type of field_decl, since we may need
9030                  it. Don't do primitive types or loaded classes. The
9031                  situation of non primitive arrays may not handled
9032                  properly here. FIXME */
9033               if (TREE_CODE (TREE_TYPE (field_decl)) == POINTER_TYPE)
9034                 field_decl_type = TREE_TYPE (TREE_TYPE (field_decl));
9035               else
9036                 field_decl_type = TREE_TYPE (field_decl);
9037               if (!JPRIMITIVE_TYPE_P (field_decl_type) 
9038                   && !CLASS_LOADED_P (field_decl_type)
9039                   && !TYPE_ARRAY_P (field_decl_type))
9040                 resolve_and_layout (field_decl_type, NULL_TREE);
9041               if (TYPE_ARRAY_P (field_decl_type))
9042                 CLASS_LOADED_P (field_decl_type) = 1;
9043               
9044               /* Check on accessibility here */
9045               if (not_accessible_p (type, field_decl, from_super))
9046                 {
9047                   parse_error_context 
9048                     (qual_wfl,
9049                      "Can't access %s field `%s.%s' from `%s'",
9050                      java_accstring_lookup 
9051                        (get_access_flags_from_decl (field_decl)),
9052                      GET_TYPE_NAME (type),
9053                      IDENTIFIER_POINTER (DECL_NAME (field_decl)),
9054                      IDENTIFIER_POINTER 
9055                        (DECL_NAME (TYPE_NAME (current_class))));
9056                   return 1;
9057                 }
9058               check_deprecation (qual_wfl, field_decl);
9059               
9060               /* There are things to check when fields are accessed
9061                  from type. There are no restrictions on a static
9062                  declaration of the field when it is accessed from an
9063                  interface */
9064               is_static = FIELD_STATIC (field_decl);
9065               if (!from_super && from_type 
9066                   && !TYPE_INTERFACE_P (type) 
9067                   && !is_static 
9068                   && (current_function_decl 
9069                       && METHOD_STATIC (current_function_decl)))
9070                 {
9071                   static_ref_err (qual_wfl, EXPR_WFL_NODE (qual_wfl), type);
9072                   return 1;
9073                 }
9074               from_cast = from_super = 0;
9075
9076               /* It's an access from a type but it isn't static, we
9077                  make it relative to `this'. */
9078               if (!is_static && from_type)
9079                 decl = current_this;
9080
9081               /* If we need to generate something to get a proper
9082                  handle on what this field is accessed from, do it
9083                  now. */
9084               if (!is_static)
9085                 {
9086                   decl = maybe_access_field (decl, *where_found, *type_found);
9087                   if (decl == error_mark_node)
9088                     return 1;
9089                 }
9090
9091               /* We want to keep the location were found it, and the type
9092                  we found. */
9093               *where_found = decl;
9094               *type_found = type;
9095
9096               /* Generate the correct expression for field access from
9097                  qualified this */
9098               if (from_qualified_this)
9099                 {
9100                   field_decl = build_outer_field_access (qual_wfl, field_decl);
9101                   from_qualified_this = 0;
9102                 }
9103
9104               /* This is the decl found and eventually the next one to
9105                  search from */
9106               decl = field_decl;
9107             }
9108           from_type = 0;
9109           type = QUAL_DECL_TYPE (decl);
9110
9111           /* Sneak preview. If decl is qualified by a `new', report
9112              the error here to be accurate on the peculiar construct */
9113           if (TREE_CHAIN (q) 
9114               && TREE_CODE (TREE_PURPOSE (TREE_CHAIN (q))) == NEW_CLASS_EXPR
9115               && !JREFERENCE_TYPE_P (type))
9116             {
9117               parse_error_context (qual_wfl, "Attempt to reference field `new' in a `%s'", 
9118                                    lang_printable_name (type, 0));
9119               return 1;
9120             }
9121         }
9122       /* `q' might have changed due to a after package resolution
9123          re-qualification */
9124       if (!q)
9125         break;
9126     }
9127   *found_decl = decl;
9128   return 0;
9129 }
9130
9131 /* 6.6 Qualified name and access control. Returns 1 if MEMBER (a decl)
9132    can't be accessed from REFERENCE (a record type). */
9133
9134 static int
9135 not_accessible_p (reference, member, from_super)
9136      tree reference, member;
9137      int from_super;
9138 {
9139   int access_flag = get_access_flags_from_decl (member);
9140
9141   /* Access always granted for members declared public */
9142   if (access_flag & ACC_PUBLIC)
9143     return 0;
9144   
9145   /* Check access on protected members */
9146   if (access_flag & ACC_PROTECTED)
9147     {
9148       /* Access granted if it occurs from within the package
9149          containing the class in which the protected member is
9150          declared */
9151       if (class_in_current_package (DECL_CONTEXT (member)))
9152         return 0;
9153
9154       /* If accessed with the form `super.member', then access is granted */
9155       if (from_super)
9156         return 0;
9157
9158       /* Otherwise, access is granted if occuring from the class where
9159          member is declared or a subclass of it */
9160       if (inherits_from_p (reference, DECL_CONTEXT (member)))
9161         return 0;
9162       return 1;
9163     }
9164
9165   /* Check access on private members. Access is granted only if it
9166      occurs from within the class in which it is declared. Exceptions
9167      are accesses from inner-classes. This section is probably not
9168      complete. FIXME */
9169   if (access_flag & ACC_PRIVATE)
9170     return (current_class == DECL_CONTEXT (member) ? 0 : 
9171             (INNER_CLASS_TYPE_P (current_class) ? 0 : 1));
9172
9173   /* Default access are permitted only when occuring within the
9174      package in which the type (REFERENCE) is declared. In other words,
9175      REFERENCE is defined in the current package */
9176   if (ctxp->package)
9177     return !class_in_current_package (reference);
9178
9179   /* Otherwise, access is granted */
9180   return 0;
9181 }
9182
9183 /* Test deprecated decl access.  */
9184 static void
9185 check_deprecation (wfl, decl)
9186      tree wfl, decl;
9187 {
9188   const char *file = DECL_SOURCE_FILE (decl);
9189   /* Complain if the field is deprecated and the file it was defined
9190      in isn't compiled at the same time the file which contains its
9191      use is */
9192   if (DECL_DEPRECATED (decl) 
9193       && !IS_A_COMMAND_LINE_FILENAME_P (get_identifier (file)))
9194     {
9195       char the [20];
9196       switch (TREE_CODE (decl))
9197         {
9198         case FUNCTION_DECL:
9199           strcpy (the, "method");
9200           break;
9201         case FIELD_DECL:
9202           strcpy (the, "field");
9203           break;
9204         case TYPE_DECL:
9205           strcpy (the, "class");
9206           break;
9207         default:
9208           fatal ("unexpected DECL code - check_deprecation");
9209         }
9210       parse_warning_context 
9211         (wfl, "The %s `%s' in class `%s' has been deprecated", 
9212          the, lang_printable_name (decl, 0),
9213          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)))));
9214     }
9215 }
9216
9217 /* Returns 1 if class was declared in the current package, 0 otherwise */
9218
9219 static int
9220 class_in_current_package (class)
9221      tree class;
9222 {
9223   static tree cache = NULL_TREE;
9224   int qualified_flag;
9225   tree left;
9226
9227   if (cache == class)
9228     return 1;
9229
9230   qualified_flag = QUALIFIED_P (DECL_NAME (TYPE_NAME (class)));
9231
9232   /* If the current package is empty and the name of CLASS is
9233      qualified, class isn't in the current package.  If there is a
9234      current package and the name of the CLASS is not qualified, class
9235      isn't in the current package */
9236   if ((!ctxp->package && qualified_flag) || (ctxp->package && !qualified_flag))
9237     return 0;
9238
9239   /* If there is not package and the name of CLASS isn't qualified,
9240      they belong to the same unnamed package */
9241   if (!ctxp->package && !qualified_flag)
9242     return 1;
9243
9244   /* Compare the left part of the name of CLASS with the package name */
9245   breakdown_qualified (&left, NULL, DECL_NAME (TYPE_NAME (class)));
9246   if (ctxp->package == left)
9247     {
9248       cache = class;
9249       return 1;
9250     }
9251   return 0;
9252 }
9253
9254 /* This function may generate code to access DECL from WHERE. This is
9255    done only if certain conditions meet.  */
9256
9257 static tree
9258 maybe_access_field (decl, where, type)
9259   tree decl, where, type;
9260 {
9261   if (TREE_CODE (decl) == FIELD_DECL && decl != current_this
9262       && !FIELD_STATIC (decl))
9263     decl = build_field_ref (where ? where : current_this, 
9264                             (type ? type : DECL_CONTEXT (decl)),
9265                             DECL_NAME (decl));
9266   return decl;
9267 }
9268
9269 /* Build a method invocation, by patching PATCH. If non NULL
9270    and according to the situation, PRIMARY and WHERE may be
9271    used. IS_STATIC is set to 1 if the invoked function is static. */
9272
9273 static tree
9274 patch_method_invocation (patch, primary, where, is_static, ret_decl)
9275      tree patch, primary, where;
9276      int *is_static;
9277      tree *ret_decl;
9278 {
9279   tree wfl = TREE_OPERAND (patch, 0);
9280   tree args = TREE_OPERAND (patch, 1);
9281   tree name = EXPR_WFL_NODE (wfl);
9282   tree list;
9283   int is_static_flag = 0;
9284   int is_super_init = 0;
9285   tree this_arg = NULL_TREE;
9286   
9287   /* Should be overriden if everything goes well. Otherwise, if
9288      something fails, it should keep this value. It stop the
9289      evaluation of a bogus assignment. See java_complete_tree,
9290      MODIFY_EXPR: for the reasons why we sometimes want to keep on
9291      evaluating an assignment */
9292   TREE_TYPE (patch) = error_mark_node;
9293
9294   /* Since lookup functions are messing with line numbers, save the
9295      context now.  */
9296   java_parser_context_save_global ();
9297
9298   /* 15.11.1: Compile-Time Step 1: Determine Class or Interface to Search */
9299
9300   /* Resolution of qualified name, excluding constructors */
9301   if (QUALIFIED_P (name) && !CALL_CONSTRUCTOR_P (patch))
9302     {
9303       tree identifier, identifier_wfl, type, resolved;
9304       /* Extract the last IDENTIFIER of the qualified
9305          expression. This is a wfl and we will use it's location
9306          data during error report. */
9307       identifier_wfl = cut_identifier_in_qualified (wfl);
9308       identifier = EXPR_WFL_NODE (identifier_wfl);
9309       
9310       /* Given the context, IDENTIFIER is syntactically qualified
9311          as a MethodName. We need to qualify what's before */
9312       qualify_ambiguous_name (wfl);
9313       resolved = resolve_field_access (wfl, NULL, NULL);
9314
9315       if (resolved == error_mark_node)
9316         PATCH_METHOD_RETURN_ERROR ();
9317
9318       type = GET_SKIP_TYPE (resolved);
9319       resolve_and_layout (type, NULL_TREE);
9320       list = lookup_method_invoke (0, identifier_wfl, type, identifier, args);
9321       args = nreverse (args);
9322
9323       /* We're resolving a call from a type */
9324       if (TREE_CODE (resolved) == TYPE_DECL)
9325         {
9326           if (CLASS_INTERFACE (resolved))
9327             {
9328               parse_error_context
9329                 (identifier_wfl,
9330                 "Can't make static reference to method `%s' in interface `%s'",
9331                  IDENTIFIER_POINTER (identifier), 
9332                  IDENTIFIER_POINTER (name));
9333               PATCH_METHOD_RETURN_ERROR ();
9334             }
9335           if (list && !METHOD_STATIC (list))
9336             {
9337               char *fct_name = xstrdup (lang_printable_name (list, 0));
9338               parse_error_context 
9339                 (identifier_wfl,
9340                  "Can't make static reference to method `%s %s' in class `%s'",
9341                  lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0), 
9342                  fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
9343               free (fct_name);
9344               PATCH_METHOD_RETURN_ERROR ();
9345             }
9346         }
9347       else
9348         this_arg = primary = resolved;
9349       
9350       /* IDENTIFIER_WFL will be used to report any problem further */
9351       wfl = identifier_wfl;
9352     }
9353   /* Resolution of simple names, names generated after a primary: or
9354      constructors */
9355   else
9356     {
9357       tree class_to_search = NULL_TREE;
9358       int lc;                   /* Looking for Constructor */
9359       
9360       /* We search constructor in their target class */
9361       if (CALL_CONSTRUCTOR_P (patch))
9362         {
9363           if (TREE_CODE (patch) == NEW_CLASS_EXPR)
9364             class_to_search = EXPR_WFL_NODE (wfl);
9365           else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) == 
9366                    this_identifier_node)
9367             class_to_search = NULL_TREE;
9368           else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) ==
9369                    super_identifier_node)
9370             {
9371               is_super_init = 1;
9372               if (CLASSTYPE_SUPER (current_class))
9373                 class_to_search = 
9374                   DECL_NAME (TYPE_NAME (CLASSTYPE_SUPER (current_class)));
9375               else
9376                 {
9377                   parse_error_context (wfl, "Can't invoke super constructor on java.lang.Object");
9378                   PATCH_METHOD_RETURN_ERROR ();
9379                 }
9380             }
9381
9382           /* Class to search is NULL if we're searching the current one */
9383           if (class_to_search)
9384             {
9385               class_to_search = resolve_and_layout (class_to_search, wfl);
9386
9387               if (!class_to_search)
9388                 {
9389                   parse_error_context 
9390                     (wfl, "Class `%s' not found in type declaration",
9391                      IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
9392                   PATCH_METHOD_RETURN_ERROR ();
9393                 }
9394               
9395               /* Can't instantiate an abstract class, but we can
9396                  invoke it's constructor. It's use within the `new'
9397                  context is denied here. */
9398               if (CLASS_ABSTRACT (class_to_search) 
9399                   && TREE_CODE (patch) == NEW_CLASS_EXPR)
9400                 {
9401                   parse_error_context 
9402                     (wfl, "Class `%s' is an abstract class. It can't be instantiated",
9403                      IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
9404                   PATCH_METHOD_RETURN_ERROR ();
9405                 }
9406
9407               class_to_search = TREE_TYPE (class_to_search);
9408             }
9409           else
9410             class_to_search = current_class;
9411           lc = 1;
9412         }
9413       /* This is a regular search in the local class, unless an
9414          alternate class is specified. */
9415       else
9416         {
9417           class_to_search = (where ? where : current_class);
9418           lc = 0;
9419         }
9420
9421       /* NAME is a simple identifier or comes from a primary. Search
9422          in the class whose declaration contain the method being
9423          invoked. */
9424       resolve_and_layout (class_to_search, NULL_TREE);
9425
9426       list = lookup_method_invoke (lc, wfl, class_to_search, name, args);
9427       /* Don't continue if no method were found, as the next statement
9428          can't be executed then. */
9429       if (!list)
9430         PATCH_METHOD_RETURN_ERROR ();
9431
9432       /* Check for static reference if non static methods */
9433       if (check_for_static_method_reference (wfl, patch, list, 
9434                                              class_to_search, primary))
9435         PATCH_METHOD_RETURN_ERROR ();
9436
9437       /* Check for inner classes creation from illegal contexts */
9438       if (lc && (INNER_CLASS_TYPE_P (class_to_search)
9439                  && !CLASS_STATIC (TYPE_NAME (class_to_search)))
9440           && INNER_ENCLOSING_SCOPE_CHECK (class_to_search))
9441         {
9442           parse_error_context 
9443             (wfl, "No enclosing instance for inner class `%s' is in scope%s",
9444              lang_printable_name (class_to_search, 0),
9445              (!current_this ? "" :
9446               "; an explicit one must be provided when creating this inner class"));
9447           PATCH_METHOD_RETURN_ERROR ();
9448         }
9449
9450       /* Non static methods are called with the current object extra
9451          argument. If patch a `new TYPE()', the argument is the value
9452          returned by the object allocator. If method is resolved as a
9453          primary, use the primary otherwise use the current THIS. */
9454       args = nreverse (args);
9455       if (TREE_CODE (patch) != NEW_CLASS_EXPR)
9456         {
9457           this_arg = primary ? primary : current_this;
9458
9459           /* If we're using an access method, things are different.
9460              There are two familly of cases:
9461
9462              1) We're not generating bytecodes:
9463
9464              - LIST is non static. It's invocation is transformed from
9465                x(a1,...,an) into this$<n>.x(a1,....an).
9466              - LIST is static. It's invocation is transformed from
9467                x(a1,...,an) into TYPE_OF(this$<n>).x(a1,....an)
9468
9469              2) We're generating bytecodes:
9470              
9471              - LIST is non static. It's invocation is transformed from
9472                x(a1,....,an) into access$<n>(this$<n>,a1,...,an).
9473              - LIST is static. It's invocation is transformed from
9474                x(a1,....,an) into TYPEOF(this$<n>).x(a1,....an).
9475
9476              Of course, this$<n> can be abitrary complex, ranging from
9477              this$0 (the immediate outer context) to 
9478              access$0(access$0(...(this$0))). 
9479              
9480              maybe_use_access_method returns a non zero value if the
9481              this_arg has to be moved into the (then generated) stub
9482              argument list. In the mean time, the selected function
9483              might have be replaced by a generated stub. */
9484           if (maybe_use_access_method (is_super_init, &list, &this_arg))
9485             args = tree_cons (NULL_TREE, this_arg, args);
9486         }
9487     }
9488
9489   /* Merge point of all resolution schemes. If we have nothing, this
9490      is an error, already signaled */
9491   if (!list) 
9492     PATCH_METHOD_RETURN_ERROR ();
9493
9494   /* Check accessibility, position the is_static flag, build and
9495      return the call */
9496   if (not_accessible_p (DECL_CONTEXT (current_function_decl), list, 0))
9497     {
9498       char *fct_name = xstrdup (lang_printable_name (list, 0));
9499       parse_error_context 
9500         (wfl, "Can't access %s method `%s %s.%s' from `%s'",
9501          java_accstring_lookup (get_access_flags_from_decl (list)),
9502          lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0), 
9503          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (list)))), 
9504          fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
9505       free (fct_name);
9506       PATCH_METHOD_RETURN_ERROR ();
9507     }
9508   check_deprecation (wfl, list);
9509
9510   /* If invoking a innerclass constructor, there are hidden parameters
9511      to pass */
9512   if (TREE_CODE (patch) == NEW_CLASS_EXPR 
9513       && PURE_INNER_CLASS_TYPE_P (DECL_CONTEXT (list)))
9514     {
9515       /* And make sure we add the accessed local variables to be saved
9516          in field aliases. */
9517       args = build_alias_initializer_parameter_list
9518         (AIPL_FUNCTION_CTOR_INVOCATION, DECL_CONTEXT (list), args, NULL);
9519
9520       /* We have to reverse things. Find out why. FIXME */
9521       if (ANONYMOUS_CLASS_P (DECL_CONTEXT (list)))
9522         args = nreverse (args);
9523       
9524       /* Secretely pass the current_this/primary as a second argument */
9525       if (primary || current_this)
9526         args = tree_cons (NULL_TREE, (primary ? primary : current_this), args);
9527       else
9528         args = tree_cons (NULL_TREE, integer_zero_node, args);
9529     }
9530
9531   is_static_flag = METHOD_STATIC (list);
9532   if (! METHOD_STATIC (list) && this_arg != NULL_TREE)
9533     args = tree_cons (NULL_TREE, this_arg, args);
9534
9535   /* In the context of an explicit constructor invocation, we can't
9536      invoke any method relying on `this'. Exceptions are: we're
9537      invoking a static function, primary exists and is not the current
9538      this, we're creating a new object. */
9539   if (ctxp->explicit_constructor_p 
9540       && !is_static_flag 
9541       && (!primary || primary == current_this)
9542       && (TREE_CODE (patch) != NEW_CLASS_EXPR))
9543     {
9544       parse_error_context (wfl, "Can't reference `this' before the superclass constructor has been called");
9545       PATCH_METHOD_RETURN_ERROR ();
9546     }
9547   java_parser_context_restore_global ();
9548   if (is_static) 
9549     *is_static = is_static_flag;
9550   /* Sometimes, we want the decl of the selected method. Such as for
9551      EH checking */
9552   if (ret_decl)
9553     *ret_decl = list;
9554   patch = patch_invoke (patch, list, args);
9555   if (is_super_init && CLASS_HAS_FINIT_P (current_class))
9556     {
9557       tree finit_parms, finit_call;
9558       
9559       /* Prepare to pass hidden parameters to $finit$, if any. */
9560       finit_parms = build_alias_initializer_parameter_list 
9561         (AIPL_FUNCTION_FINIT_INVOCATION, current_class, NULL_TREE, NULL);
9562
9563       finit_call = 
9564         build_method_invocation (build_wfl_node (finit_identifier_node),
9565                                  finit_parms);
9566
9567       /* Generate the code used to initialize fields declared with an
9568          initialization statement and build a compound statement along
9569          with the super constructor invocation. */
9570       patch = build (COMPOUND_EXPR, void_type_node, patch,
9571                      java_complete_tree (finit_call));
9572       CAN_COMPLETE_NORMALLY (patch) = 1;
9573     }
9574   return patch;
9575 }
9576
9577 /* Check that we're not trying to do a static reference to a method in
9578    non static method. Return 1 if it's the case, 0 otherwise. */
9579
9580 static int
9581 check_for_static_method_reference (wfl, node, method, where, primary)
9582      tree wfl, node, method, where, primary;
9583 {
9584   if (METHOD_STATIC (current_function_decl) 
9585       && !METHOD_STATIC (method) && !primary && !CALL_CONSTRUCTOR_P (node))
9586     {
9587       char *fct_name = xstrdup (lang_printable_name (method, 0));
9588       parse_error_context 
9589         (wfl, "Can't make static reference to method `%s %s' in class `%s'", 
9590          lang_printable_name (TREE_TYPE (TREE_TYPE (method)), 0), fct_name,
9591          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (where))));
9592       free (fct_name);
9593       return 1;
9594     }
9595   return 0;
9596 }
9597
9598 /* Fix the invocation of *MDECL if necessary in the case of a
9599    invocation from an inner class. *THIS_ARG might be modified
9600    appropriately and an alternative access to *MDECL might be
9601    returned.  */
9602
9603 static int
9604 maybe_use_access_method (is_super_init, mdecl, this_arg)
9605      int is_super_init;
9606      tree *mdecl, *this_arg;
9607 {
9608   tree ctx;
9609   tree md = *mdecl, ta = *this_arg;
9610   int to_return = 0;
9611   int non_static_context = !METHOD_STATIC (md);
9612
9613   if (is_super_init 
9614       || DECL_CONTEXT (md) == current_class
9615       || !PURE_INNER_CLASS_TYPE_P (current_class) 
9616       || DECL_FINIT_P (md))
9617     return 0;
9618   
9619   /* If we're calling a method found in an enclosing class, generate
9620      what it takes to retrieve the right this. Don't do that if we're
9621      invoking a static method. */
9622
9623   if (non_static_context)
9624     {
9625       ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class)));
9626       if (ctx == DECL_CONTEXT (md))
9627         {
9628           ta = build_current_thisn (current_class);
9629           ta = build_wfl_node (ta);
9630         }
9631       else
9632         {
9633           tree type = ctx;
9634           while (type)
9635             {
9636               maybe_build_thisn_access_method (type);
9637               if (type == DECL_CONTEXT (md))
9638                 {
9639                   ta = build_access_to_thisn (ctx, type, 0);
9640                   break;
9641                 }
9642               type = (DECL_CONTEXT (TYPE_NAME (type)) ? 
9643                       TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))) : NULL_TREE);
9644             }
9645         }
9646       ta = java_complete_tree (ta);
9647     }
9648
9649   /* We might have to use an access method to get to MD. We can
9650      break the method access rule as far as we're not generating
9651      bytecode */
9652   if (METHOD_PRIVATE (md) && flag_emit_class_files)
9653     {
9654       md = build_outer_method_access_method (md);
9655       to_return = 1;
9656     }
9657
9658   *mdecl = md;
9659   *this_arg = ta;
9660
9661   /* Returnin a non zero value indicates we were doing a non static
9662      method invokation that is now a static invocation. It will have
9663      callee displace `this' to insert it in the regular argument
9664      list. */
9665   return (non_static_context && to_return);
9666 }
9667
9668 /* Patch an invoke expression METHOD and ARGS, based on its invocation
9669    mode.  */
9670
9671 static tree
9672 patch_invoke (patch, method, args)
9673      tree patch, method, args;
9674 {
9675   tree dtable, func;
9676   tree original_call, t, ta;
9677   tree cond = NULL_TREE;
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 incoming 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_NONVIRTUAL:
9710           /* If the object for the method call is null, we throw an
9711              exception.  We don't do this if the object is the current
9712              method's `this'.  In other cases we just rely on an
9713              optimization pass to eliminate redundant checks.  */
9714           if (TREE_VALUE (args) != current_this)
9715             {
9716               /* We use a SAVE_EXPR here to make sure we only evaluate
9717                  the new `self' expression once.  */
9718               tree save_arg = save_expr (TREE_VALUE (args));
9719               TREE_VALUE (args) = save_arg;
9720               cond = build (EQ_EXPR, boolean_type_node, save_arg,
9721                             null_pointer_node);
9722             }
9723           /* Fall through.  */
9724
9725         case INVOKE_SUPER:
9726         case INVOKE_STATIC:
9727           func = build_known_method_ref (method, TREE_TYPE (method),
9728                                          DECL_CONTEXT (method),
9729                                          signature, args);
9730           break;
9731
9732         case INVOKE_INTERFACE:
9733           dtable = invoke_build_dtable (1, args);
9734           func = build_invokeinterface (dtable, method);
9735           break;
9736
9737         default:
9738           fatal ("internal error - unknown invocation_mode result");
9739         }
9740
9741       /* Ensure self_type is initialized, (invokestatic). FIXME */
9742       func = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (method)), func);
9743     }
9744
9745   TREE_TYPE (patch) = TREE_TYPE (TREE_TYPE (method));
9746   TREE_OPERAND (patch, 0) = func;
9747   TREE_OPERAND (patch, 1) = args;
9748   original_call = patch;
9749
9750   /* We're processing a `new TYPE ()' form. New is called and its
9751      returned value is the first argument to the constructor. We build
9752      a COMPOUND_EXPR and use saved expression so that the overall NEW
9753      expression value is a pointer to a newly created and initialized
9754      class. */
9755   if (TREE_CODE (original_call) == NEW_CLASS_EXPR)
9756     {
9757       tree class = DECL_CONTEXT (method);
9758       tree c1, saved_new, size, new;
9759       if (flag_emit_class_files || flag_emit_xref)
9760         {
9761           TREE_TYPE (patch) = build_pointer_type (class);
9762           return patch;
9763         }
9764       if (!TYPE_SIZE (class))
9765         safe_layout_class (class);
9766       size = size_in_bytes (class);
9767       new = build (CALL_EXPR, promote_type (class),
9768                    build_address_of (alloc_object_node),
9769                    tree_cons (NULL_TREE, build_class_ref (class),
9770                               build_tree_list (NULL_TREE, 
9771                                                size_in_bytes (class))),
9772                    NULL_TREE);
9773       saved_new = save_expr (new);
9774       c1 = build_tree_list (NULL_TREE, saved_new);
9775       TREE_CHAIN (c1) = TREE_OPERAND (original_call, 1);
9776       TREE_OPERAND (original_call, 1) = c1;
9777       TREE_SET_CODE (original_call, CALL_EXPR);
9778       patch = build (COMPOUND_EXPR, TREE_TYPE (new), patch, saved_new);
9779     }
9780
9781   /* If COND is set, then we are building a check to see if the object
9782      is NULL.  */
9783   if (cond != NULL_TREE)
9784     {
9785       /* We have to make the `then' branch a compound expression to
9786          make the types turn out right.  This seems bizarre.  */
9787       patch = build (COND_EXPR, TREE_TYPE (patch), cond,
9788                      build (COMPOUND_EXPR, TREE_TYPE (patch),
9789                             build (CALL_EXPR, void_type_node,
9790                                    build_address_of (soft_nullpointer_node),
9791                                    NULL_TREE, NULL_TREE),
9792                             (FLOAT_TYPE_P (TREE_TYPE (patch))
9793                              ? build_real (TREE_TYPE (patch), dconst0)
9794                              : build1 (CONVERT_EXPR, TREE_TYPE (patch),
9795                                        integer_zero_node))),
9796                      patch);
9797       TREE_SIDE_EFFECTS (patch) = 1;
9798     }
9799
9800   return patch;
9801 }
9802
9803 static int
9804 invocation_mode (method, super)
9805      tree method;
9806      int super;
9807 {
9808   int access = get_access_flags_from_decl (method);
9809
9810   if (super)
9811     return INVOKE_SUPER;
9812
9813   if (access & ACC_STATIC)
9814     return INVOKE_STATIC;
9815
9816   /* We have to look for a constructor before we handle nonvirtual
9817      calls; otherwise the constructor will look nonvirtual.  */
9818   if (DECL_CONSTRUCTOR_P (method))
9819     return INVOKE_STATIC;
9820
9821   if (access & ACC_FINAL || access & ACC_PRIVATE)
9822     return INVOKE_NONVIRTUAL;
9823
9824   if (CLASS_FINAL (TYPE_NAME (DECL_CONTEXT (method))))
9825     return INVOKE_NONVIRTUAL;
9826
9827   if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))))
9828     return INVOKE_INTERFACE;
9829
9830   return INVOKE_VIRTUAL;
9831 }
9832
9833 /* Retrieve a refined list of matching methods. It covers the step
9834    15.11.2 (Compile-Time Step 2) */
9835
9836 static tree
9837 lookup_method_invoke (lc, cl, class, name, arg_list)
9838      int lc;
9839      tree cl;
9840      tree class, name, arg_list;
9841 {
9842   tree atl = end_params_node;           /* Arg Type List */
9843   tree method, signature, list, node;
9844   const char *candidates;               /* Used for error report */
9845   char *dup;
9846
9847   /* Fix the arguments */
9848   for (node = arg_list; node; node = TREE_CHAIN (node))
9849     {
9850       tree current_arg = TREE_TYPE (TREE_VALUE (node));
9851       /* Non primitive type may have to be resolved */
9852       if (!JPRIMITIVE_TYPE_P (current_arg))
9853         resolve_and_layout (current_arg, NULL_TREE);
9854       /* And promoted */
9855       if (TREE_CODE (current_arg) == RECORD_TYPE)
9856         current_arg = promote_type (current_arg);
9857       atl = tree_cons (NULL_TREE, current_arg, atl);
9858     }
9859
9860   /* Presto. If we're dealing with an anonymous class and a
9861      constructor call, generate the right constructor now, since we
9862      know the arguments' types. */
9863
9864   if (lc && ANONYMOUS_CLASS_P (class))
9865     craft_constructor (TYPE_NAME (class), atl);
9866
9867   /* Find all candidates and then refine the list, searching for the
9868      most specific method. */
9869   list = find_applicable_accessible_methods_list (lc, class, name, atl);
9870   list = find_most_specific_methods_list (list);
9871   if (list && !TREE_CHAIN (list))
9872     return TREE_VALUE (list);
9873
9874   /* Issue an error. List candidates if any. Candidates are listed
9875      only if accessible (non accessible methods may end-up here for
9876      the sake of a better error report). */
9877   candidates = NULL;
9878   if (list)
9879     {
9880       tree current;
9881       obstack_grow (&temporary_obstack, ". Candidates are:\n", 18);
9882       for (current = list; current; current = TREE_CHAIN (current))
9883         {
9884           tree cm = TREE_VALUE (current);
9885           char string [4096];
9886           if (!cm || not_accessible_p (class, cm, 0))
9887             continue;
9888           sprintf 
9889             (string, "  `%s' in `%s'%s",
9890              get_printable_method_name (cm),
9891              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (cm)))),
9892              (TREE_CHAIN (current) ? "\n" : ""));
9893           obstack_grow (&temporary_obstack, string, strlen (string));
9894         }
9895       obstack_1grow (&temporary_obstack, '\0');
9896       candidates = obstack_finish (&temporary_obstack);
9897     }
9898   /* Issue the error message */
9899   method = make_node (FUNCTION_TYPE);
9900   TYPE_ARG_TYPES (method) = atl;
9901   signature = build_java_argument_signature (method);
9902   dup = xstrdup (lang_printable_name (class, 0));
9903   parse_error_context (cl, "Can't find %s `%s(%s)' in type `%s'%s",
9904                        (lc ? "constructor" : "method"),
9905                        (lc ? dup : IDENTIFIER_POINTER (name)),
9906                        IDENTIFIER_POINTER (signature), dup,
9907                        (candidates ? candidates : ""));
9908   free (dup);
9909   return NULL_TREE;
9910 }
9911
9912 /* 15.11.2.1: Find Methods that are Applicable and Accessible. LC is 1
9913    when we're looking for a constructor. */
9914
9915 static tree
9916 find_applicable_accessible_methods_list (lc, class, name, arglist)
9917      int lc;
9918      tree class, name, arglist;
9919 {
9920   static int object_done = 0;
9921   tree list = NULL_TREE, all_list = NULL_TREE;
9922
9923   if (!CLASS_LOADED_P (class) && !CLASS_FROM_SOURCE_P (class))
9924     {
9925       load_class (class, 1);
9926       safe_layout_class (class);
9927     }
9928
9929   /* Search interfaces */
9930   if (CLASS_INTERFACE (TYPE_NAME (class)))
9931     {
9932       static struct hash_table t, *searched_interfaces = NULL;
9933       static int search_not_done = 0;
9934       int i, n;
9935       tree basetype_vec = TYPE_BINFO_BASETYPES (class);
9936
9937       /* Search in the hash table, otherwise create a new one if
9938          necessary and insert the new entry. */
9939
9940       if (searched_interfaces)
9941         {
9942           if (hash_lookup (searched_interfaces, 
9943                            (const hash_table_key) class, FALSE, NULL))
9944             return NULL;
9945         }
9946       else
9947         {
9948           hash_table_init (&t, hash_newfunc, java_hash_hash_tree_node,
9949                            java_hash_compare_tree_node);
9950           searched_interfaces = &t;
9951         }
9952
9953       hash_lookup (searched_interfaces, 
9954                    (const hash_table_key) class, TRUE, NULL);
9955
9956       search_applicable_methods_list (lc, TYPE_METHODS (class), 
9957                                       name, arglist, &list, &all_list);
9958       n = TREE_VEC_LENGTH (basetype_vec);
9959       for (i = 1; i < n; i++)
9960         {
9961           tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
9962           tree rlist;
9963
9964           search_not_done++;
9965           rlist = find_applicable_accessible_methods_list (lc,  t, name, 
9966                                                            arglist);
9967           list = chainon (rlist, list);
9968           search_not_done--;
9969         }
9970
9971       /* We're done. Reset the searched interfaces list and finally search
9972          java.lang.Object */
9973       if (!search_not_done)
9974         {  
9975           if (!object_done)
9976             search_applicable_methods_list (lc, 
9977                                             TYPE_METHODS (object_type_node),
9978                                             name, arglist, &list, &all_list);
9979           hash_table_free (searched_interfaces);
9980           searched_interfaces = NULL;  
9981         }
9982     }
9983   /* Search classes */
9984   else
9985     {
9986       tree sc = class;
9987       int seen_inner_class = 0;
9988       search_applicable_methods_list (lc, TYPE_METHODS (class), 
9989                                       name, arglist, &list, &all_list);
9990
9991       /* We must search all interfaces of this class */
9992       if (!lc)
9993       {
9994         tree basetype_vec = TYPE_BINFO_BASETYPES (sc);
9995         int n = TREE_VEC_LENGTH (basetype_vec), i;
9996         object_done = 1;
9997         for (i = 1; i < n; i++)
9998           {
9999             tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
10000             tree rlist;
10001             if (t != object_type_node)
10002               rlist = find_applicable_accessible_methods_list (lc, t,
10003                                                                name, arglist);
10004             list = chainon (rlist, list);
10005           }
10006         object_done = 0;
10007       }
10008
10009       /* Search enclosing context of inner classes before looking
10010          ancestors up. */
10011       while (!lc && INNER_CLASS_TYPE_P (class))
10012         {
10013           tree rlist;
10014           seen_inner_class = 1;
10015           class = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class)));
10016           rlist = find_applicable_accessible_methods_list (lc, class, 
10017                                                            name, arglist);
10018           list = chainon (rlist, list);
10019         }
10020
10021       if (!lc && seen_inner_class 
10022           && TREE_TYPE (DECL_CONTEXT (TYPE_NAME (sc))) == CLASSTYPE_SUPER (sc))
10023         class = CLASSTYPE_SUPER (sc);
10024       else
10025         class = sc;
10026
10027       for (class = (lc ? NULL_TREE : CLASSTYPE_SUPER (class)); 
10028         class; class = CLASSTYPE_SUPER (class))
10029        search_applicable_methods_list (lc, TYPE_METHODS (class), 
10030                                        name, arglist, &list, &all_list);
10031     }
10032
10033   /* Either return the list obtained or all selected (but
10034      inaccessible) methods for better error report. */
10035   return (!list ? all_list : list);
10036 }
10037
10038 /* Effectively search for the approriate method in method */
10039
10040 static void 
10041 search_applicable_methods_list (lc, method, name, arglist, list, all_list)
10042      int lc;
10043      tree method, name, arglist;
10044      tree *list, *all_list;
10045 {
10046   for (; method; method = TREE_CHAIN (method))
10047     {
10048       /* When dealing with constructor, stop here, otherwise search
10049          other classes */
10050       if (lc && !DECL_CONSTRUCTOR_P (method))
10051         continue;
10052       else if (!lc && (DECL_CONSTRUCTOR_P (method) 
10053                        || (GET_METHOD_NAME (method) != name)))
10054         continue;
10055           
10056       if (argument_types_convertible (method, arglist))
10057         {
10058           /* Retain accessible methods only */
10059           if (!not_accessible_p (DECL_CONTEXT (current_function_decl), 
10060                                  method, 0))
10061             *list = tree_cons (NULL_TREE, method, *list);
10062           else
10063             /* Also retain all selected method here */
10064             *all_list = tree_cons (NULL_TREE, method, *list);
10065         }
10066     }
10067 }    
10068
10069 /* 15.11.2.2 Choose the Most Specific Method */
10070
10071 static tree
10072 find_most_specific_methods_list (list)
10073      tree list;
10074 {
10075   int max = 0;
10076   tree current, new_list = NULL_TREE;
10077   for (current = list; current; current = TREE_CHAIN (current))
10078     {
10079       tree method;
10080       DECL_SPECIFIC_COUNT (TREE_VALUE (current)) = 0;
10081
10082       for (method = list; method; method = TREE_CHAIN (method))
10083         {
10084           /* Don't test a method against itself */
10085           if (method == current)
10086             continue;
10087
10088           /* Compare arguments and location where method where declared */
10089           if (argument_types_convertible (TREE_VALUE (method), 
10090                                           TREE_VALUE (current))
10091               && valid_method_invocation_conversion_p 
10092                    (DECL_CONTEXT (TREE_VALUE (method)), 
10093                     DECL_CONTEXT (TREE_VALUE (current))))
10094             {
10095               int v = ++DECL_SPECIFIC_COUNT (TREE_VALUE (current));
10096               max = (v > max ? v : max);
10097             }
10098         }
10099     }
10100
10101   /* Review the list and select the maximally specific methods */
10102   for (current = list; current; current = TREE_CHAIN (current))
10103     if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
10104       new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
10105
10106   /* If we have several and they're all abstract, just pick the
10107      closest one. */
10108
10109   if (new_list && TREE_CHAIN (new_list))
10110     {
10111       tree c;
10112       for (c = new_list; c && METHOD_ABSTRACT (TREE_VALUE (c)); 
10113            c = TREE_CHAIN (c))
10114         ;
10115       if (!c)
10116         {
10117           new_list = nreverse (new_list);
10118           TREE_CHAIN (new_list) = NULL_TREE;
10119         }
10120     }
10121
10122   /* If we can't find one, lower expectations and try to gather multiple
10123      maximally specific methods */
10124   while (!new_list && max)
10125     {
10126       while (--max > 0)
10127         {
10128           if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
10129             new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
10130         }
10131     }
10132
10133   return new_list;
10134 }
10135
10136 /* Make sure that the type of each M2_OR_ARGLIST arguments can be
10137    converted by method invocation conversion (5.3) to the type of the
10138    corresponding parameter of M1. Implementation expects M2_OR_ARGLIST
10139    to change less often than M1. */
10140
10141 static int
10142 argument_types_convertible (m1, m2_or_arglist)
10143     tree m1, m2_or_arglist;
10144 {
10145   static tree m2_arg_value = NULL_TREE;
10146   static tree m2_arg_cache = NULL_TREE;
10147
10148   register tree m1_arg, m2_arg;
10149
10150   SKIP_THIS_AND_ARTIFICIAL_PARMS (m1_arg, m1)
10151
10152   if (m2_arg_value == m2_or_arglist)
10153     m2_arg = m2_arg_cache;
10154   else
10155     {
10156       /* M2_OR_ARGLIST can be a function DECL or a raw list of
10157          argument types */
10158       if (m2_or_arglist && TREE_CODE (m2_or_arglist) == FUNCTION_DECL)
10159         {
10160           m2_arg = TYPE_ARG_TYPES (TREE_TYPE (m2_or_arglist));
10161           if (!METHOD_STATIC (m2_or_arglist))
10162             m2_arg = TREE_CHAIN (m2_arg);
10163         }
10164       else
10165         m2_arg = m2_or_arglist;
10166
10167       m2_arg_value = m2_or_arglist;
10168       m2_arg_cache = m2_arg;
10169     }
10170
10171   while (m1_arg != end_params_node && m2_arg != end_params_node)
10172     {
10173       resolve_and_layout (TREE_VALUE (m1_arg), NULL_TREE);
10174       if (!valid_method_invocation_conversion_p (TREE_VALUE (m1_arg),
10175                                                  TREE_VALUE (m2_arg)))
10176         break;
10177       m1_arg = TREE_CHAIN (m1_arg);
10178       m2_arg = TREE_CHAIN (m2_arg);
10179     }
10180   return m1_arg == end_params_node && m2_arg == end_params_node;
10181 }
10182
10183 /* Qualification routines */
10184
10185 static void
10186 qualify_ambiguous_name (id)
10187      tree id;
10188 {
10189   tree qual, qual_wfl, name = NULL_TREE, decl, ptr_type = NULL_TREE,
10190     saved_current_class;
10191   int again, super_found = 0, this_found = 0, new_array_found = 0;
10192   int code;
10193
10194   /* We first qualify the first element, then derive qualification of
10195      others based on the first one. If the first element is qualified
10196      by a resolution (field or type), this resolution is stored in the
10197      QUAL_RESOLUTION of the qual element being examined. We need to
10198      save the current_class since the use of SUPER might change the
10199      its value. */
10200   saved_current_class = current_class;
10201   qual = EXPR_WFL_QUALIFICATION (id);
10202   do {
10203
10204     /* Simple qualified expression feature a qual_wfl that is a
10205        WFL. Expression derived from a primary feature more complicated
10206        things like a CALL_EXPR. Expression from primary need to be
10207        worked out to extract the part on which the qualification will
10208        take place. */
10209     qual_wfl = QUAL_WFL (qual);
10210     switch (TREE_CODE (qual_wfl))
10211       {
10212       case CALL_EXPR:
10213         qual_wfl = TREE_OPERAND (qual_wfl, 0);
10214         if (TREE_CODE (qual_wfl) != EXPR_WITH_FILE_LOCATION)
10215           {
10216             qual = EXPR_WFL_QUALIFICATION (qual_wfl);
10217             qual_wfl = QUAL_WFL (qual);
10218           }
10219         break;
10220       case NEW_ARRAY_EXPR:
10221       case NEW_ANONYMOUS_ARRAY_EXPR:
10222         qual = TREE_CHAIN (qual);
10223         again = new_array_found = 1;
10224         continue;
10225       case CONVERT_EXPR:
10226         break;
10227       case NEW_CLASS_EXPR:
10228         qual_wfl = TREE_OPERAND (qual_wfl, 0);
10229         break;
10230       case ARRAY_REF:
10231         while (TREE_CODE (qual_wfl) == ARRAY_REF)
10232           qual_wfl = TREE_OPERAND (qual_wfl, 0);
10233         break;
10234       case STRING_CST:
10235         qual = TREE_CHAIN (qual);
10236         qual_wfl = QUAL_WFL (qual);
10237         break;
10238       case CLASS_LITERAL:
10239         qual = TREE_CHAIN (qual);
10240         qual_wfl = QUAL_WFL (qual);
10241       break;
10242       default:
10243         /* Fix for -Wall. Just break doing nothing */
10244         break;
10245       }
10246
10247     ptr_type = current_class;
10248     again = 0;
10249     code = TREE_CODE (qual_wfl);
10250
10251     /* Pos evaluation: non WFL leading expression nodes */
10252     if (code == CONVERT_EXPR
10253         && TREE_CODE (TREE_TYPE (qual_wfl)) == EXPR_WITH_FILE_LOCATION)
10254       name = EXPR_WFL_NODE (TREE_TYPE (qual_wfl));
10255
10256     else if (code == INTEGER_CST)
10257       name = qual_wfl;
10258     
10259     else if ((code == ARRAY_REF || code == CALL_EXPR || code == MODIFY_EXPR) &&
10260              TREE_CODE (TREE_OPERAND (qual_wfl, 0)) == EXPR_WITH_FILE_LOCATION)
10261       name = EXPR_WFL_NODE (TREE_OPERAND (qual_wfl, 0));
10262
10263     else if (code == TREE_LIST)
10264       name = EXPR_WFL_NODE (TREE_PURPOSE (qual_wfl));
10265
10266     else if (code == STRING_CST || code == CONDITIONAL_EXPR 
10267              || code == PLUS_EXPR)
10268       {
10269         qual = TREE_CHAIN (qual);
10270         qual_wfl = QUAL_WFL (qual);
10271         again = 1;
10272       }
10273     else 
10274       {
10275         name = EXPR_WFL_NODE (qual_wfl);
10276         if (!name)
10277           {
10278             qual = EXPR_WFL_QUALIFICATION (qual_wfl);
10279             again = 1;
10280           }
10281       }
10282
10283     /* If we have a THIS (from a primary), we set the context accordingly */
10284     if (name == this_identifier_node)
10285       {
10286         qual = TREE_CHAIN (qual);
10287         qual_wfl = QUAL_WFL (qual);
10288         if (TREE_CODE (qual_wfl) == CALL_EXPR)
10289           again = 1;
10290         else
10291           name = EXPR_WFL_NODE (qual_wfl);
10292         this_found = 1;
10293       }
10294     /* If we have a SUPER, we set the context accordingly */
10295     if (name == super_identifier_node)
10296       {
10297         current_class = CLASSTYPE_SUPER (ptr_type);
10298         /* Check that there is such a thing as a super class. If not,
10299            return.  The error will be caught later on, during the
10300            resolution */
10301         if (!current_class)
10302           {
10303             current_class = saved_current_class;
10304             return;
10305           }
10306         qual = TREE_CHAIN (qual);
10307         /* Do one more interation to set things up */
10308         super_found = again = 1;
10309       }
10310   } while (again);
10311   
10312   /* If name appears within the scope of a local variable declaration
10313      or parameter declaration, then it is an expression name. We don't
10314      carry this test out if we're in the context of the use of SUPER
10315      or THIS */
10316   if (!this_found && !super_found 
10317       && TREE_CODE (name) != STRING_CST && TREE_CODE (name) != INTEGER_CST
10318       && (decl = IDENTIFIER_LOCAL_VALUE (name)))
10319     {
10320       RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
10321       QUAL_RESOLUTION (qual) = decl;
10322     }
10323
10324   /* If within the class/interface NAME was found to be used there
10325      exists a (possibly inherited) field named NAME, then this is an
10326      expression name. If we saw a NEW_ARRAY_EXPR before and want to
10327      address length, it is OK. */
10328   else if ((decl = lookup_field_wrapper (ptr_type, name))
10329            || (new_array_found && name == length_identifier_node))
10330     {
10331       RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
10332       QUAL_RESOLUTION (qual) = (new_array_found ? NULL_TREE : decl);
10333     }
10334
10335   /* We reclassify NAME as yielding to a type name resolution if:
10336      - NAME is a class/interface declared within the compilation
10337        unit containing NAME,
10338      - NAME is imported via a single-type-import declaration,
10339      - NAME is declared in an another compilation unit of the package
10340        of the compilation unit containing NAME,
10341      - NAME is declared by exactly on type-import-on-demand declaration
10342      of the compilation unit containing NAME. 
10343      - NAME is actually a STRING_CST. */
10344   else if (TREE_CODE (name) == STRING_CST || TREE_CODE (name) == INTEGER_CST
10345            || (decl = resolve_and_layout (name, NULL_TREE)))
10346     {
10347       RESOLVE_TYPE_NAME_P (qual_wfl) = 1;
10348       QUAL_RESOLUTION (qual) = decl;
10349     }
10350
10351   /* Method call, array references and cast are expression name */
10352   else if (TREE_CODE (QUAL_WFL (qual)) == CALL_EXPR
10353            || TREE_CODE (QUAL_WFL (qual)) == ARRAY_REF
10354            || TREE_CODE (QUAL_WFL (qual)) == CONVERT_EXPR)
10355     RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
10356
10357   /* Check here that NAME isn't declared by more than one
10358      type-import-on-demand declaration of the compilation unit
10359      containing NAME. FIXME */
10360
10361   /* Otherwise, NAME is reclassified as a package name */
10362   else 
10363     RESOLVE_PACKAGE_NAME_P (qual_wfl) = 1;
10364
10365   /* Propagate the qualification accross other components of the
10366      qualified name */
10367   for (qual = TREE_CHAIN (qual); qual;
10368        qual_wfl = QUAL_WFL (qual), qual = TREE_CHAIN (qual))
10369     {
10370       if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
10371         RESOLVE_PACKAGE_NAME_P (QUAL_WFL (qual)) = 1;
10372       else 
10373         RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (qual)) = 1;
10374     }
10375
10376   /* Store the global qualification for the ambiguous part of ID back
10377      into ID fields */
10378   if (RESOLVE_EXPRESSION_NAME_P (qual_wfl))
10379     RESOLVE_EXPRESSION_NAME_P (id) = 1;
10380   else if (RESOLVE_TYPE_NAME_P (qual_wfl))
10381     RESOLVE_TYPE_NAME_P (id) = 1;
10382   else if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
10383     RESOLVE_PACKAGE_NAME_P (id) = 1;
10384
10385   /* Restore the current class */
10386   current_class = saved_current_class;
10387 }
10388
10389 static int
10390 breakdown_qualified (left, right, source)
10391     tree *left, *right, source;
10392 {
10393   char *p = IDENTIFIER_POINTER (source), *base;
10394   int   l = IDENTIFIER_LENGTH (source);
10395
10396   /* Breakdown NAME into REMAINDER . IDENTIFIER */
10397   base = p;
10398   p += (l-1);
10399   while (*p != '.' && p != base)
10400     p--;
10401
10402   /* We didn't find a '.'. Return an error */
10403   if (p == base)
10404     return 1;
10405
10406   *p = '\0';
10407   if (right)
10408     *right = get_identifier (p+1);
10409   *left = get_identifier (IDENTIFIER_POINTER (source));
10410   *p = '.';
10411   
10412   return 0;
10413 }
10414
10415 /* Patch tree nodes in a function body. When a BLOCK is found, push
10416    local variable decls if present.
10417    Same as java_complete_lhs, but does resolve static finals to values. */
10418
10419 static tree
10420 java_complete_tree (node)
10421      tree node;
10422 {
10423   node = java_complete_lhs (node);
10424   if (TREE_CODE (node) == VAR_DECL && FIELD_STATIC (node)
10425       && FIELD_FINAL (node) && DECL_INITIAL (node) != NULL_TREE
10426       && !flag_emit_xref)
10427     {
10428       tree value = DECL_INITIAL (node);
10429       DECL_INITIAL (node) = NULL_TREE;
10430       push_obstacks (&permanent_obstack, &permanent_obstack);
10431       value = fold_constant_for_init (value, node);
10432       pop_obstacks ();
10433       DECL_INITIAL (node) = value;
10434       if (value != NULL_TREE)
10435         {
10436           /* fold_constant_for_init sometimes widen the original type
10437              of the constant (i.e. byte to int.) It's not desirable,
10438              especially if NODE is a function argument. */
10439           if (TREE_CODE (value) == INTEGER_CST
10440               && TREE_TYPE (node) != TREE_TYPE (value))
10441             return convert (TREE_TYPE (node), value);
10442           else
10443             return value;
10444         }
10445     }
10446   return node;
10447 }
10448
10449 static tree
10450 java_stabilize_reference (node)
10451      tree node;
10452 {
10453   if (TREE_CODE (node) == COMPOUND_EXPR)
10454     {
10455       tree op0 = TREE_OPERAND (node, 0);
10456       tree op1 = TREE_OPERAND (node, 1);
10457       TREE_OPERAND (node, 0) = save_expr (op0);
10458       TREE_OPERAND (node, 1) = java_stabilize_reference (op1);
10459       return node;
10460     }
10461   return stabilize_reference (node);
10462 }
10463
10464 /* Patch tree nodes in a function body. When a BLOCK is found, push
10465    local variable decls if present.
10466    Same as java_complete_tree, but does not resolve static finals to values. */
10467
10468 static tree
10469 java_complete_lhs (node)
10470      tree node;
10471 {
10472   tree nn, cn, wfl_op1, wfl_op2, wfl_op3;
10473   int flag;
10474
10475   /* CONVERT_EXPR always has its type set, even though it needs to be
10476      worked out. */
10477   if (TREE_TYPE (node) && TREE_CODE (node) != CONVERT_EXPR)
10478     return node;
10479
10480   /* The switch block implements cases processing container nodes
10481      first.  Contained nodes are always written back. Leaves come
10482      next and return a value. */
10483   switch (TREE_CODE (node))
10484     {
10485     case BLOCK:
10486
10487       /* 1- Block section.
10488          Set the local values on decl names so we can identify them
10489          faster when they're referenced. At that stage, identifiers
10490          are legal so we don't check for declaration errors. */
10491       for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
10492         {
10493           DECL_CONTEXT (cn) = current_function_decl;
10494           IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = cn;
10495         }
10496       if (BLOCK_EXPR_BODY (node) == NULL_TREE)
10497           CAN_COMPLETE_NORMALLY (node) = 1;
10498       else
10499         {
10500           tree stmt = BLOCK_EXPR_BODY (node);
10501           tree *ptr;
10502           int error_seen = 0;
10503           if (TREE_CODE (stmt) == COMPOUND_EXPR)
10504             {
10505               /* Re-order from (((A; B); C); ...; Z) to 
10506                  (A; (B; (C ; (...; Z)))).
10507                  This makes it easier to scan the statements left-to-right
10508                  without using recursion (which might overflow the stack
10509                  if the block has many statements. */
10510               for (;;)
10511                 {
10512                   tree left = TREE_OPERAND (stmt, 0);
10513                   if (TREE_CODE (left) != COMPOUND_EXPR)
10514                     break;
10515                   TREE_OPERAND (stmt, 0) = TREE_OPERAND (left, 1);
10516                   TREE_OPERAND (left, 1) = stmt;
10517                   stmt = left;
10518                 }
10519               BLOCK_EXPR_BODY (node) = stmt;
10520             }
10521
10522           /* Now do the actual complete, without deep recursion for
10523              long blocks. */
10524           ptr = &BLOCK_EXPR_BODY (node);
10525           while (TREE_CODE (*ptr) == COMPOUND_EXPR
10526                  && TREE_OPERAND (*ptr, 1) != empty_stmt_node)
10527             {
10528               tree cur = java_complete_tree (TREE_OPERAND (*ptr, 0));
10529               tree *next = &TREE_OPERAND (*ptr, 1);
10530               TREE_OPERAND (*ptr, 0) = cur;
10531               if (cur == empty_stmt_node)
10532                 {
10533                   /* Optimization;  makes it easier to detect empty bodies.
10534                      Most useful for <clinit> with all-constant initializer. */
10535                   *ptr = *next;
10536                   continue;
10537                 }
10538               if (TREE_CODE (cur) == ERROR_MARK)
10539                 error_seen++;
10540               else if (! CAN_COMPLETE_NORMALLY (cur))
10541                 {
10542                   wfl_op2 = *next;
10543                   for (;;)
10544                     {
10545                       if (TREE_CODE (wfl_op2) == BLOCK)
10546                         wfl_op2 = BLOCK_EXPR_BODY (wfl_op2);
10547                       else if (TREE_CODE (wfl_op2) == COMPOUND_EXPR)
10548                         wfl_op2 = TREE_OPERAND (wfl_op2, 0);
10549                       else
10550                         break;
10551                     }
10552                   if (TREE_CODE (wfl_op2) != CASE_EXPR
10553                       && TREE_CODE (wfl_op2) != DEFAULT_EXPR)
10554                     unreachable_stmt_error (*ptr);
10555                 }
10556               ptr = next;
10557             }
10558           *ptr = java_complete_tree (*ptr);
10559
10560           if (TREE_CODE (*ptr) == ERROR_MARK || error_seen > 0)
10561             return error_mark_node;
10562           CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (*ptr);
10563         }
10564       /* Turn local bindings to null */
10565       for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
10566         IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = NULL_TREE;
10567
10568       TREE_TYPE (node) = void_type_node;
10569       break;
10570
10571       /* 2- They are expressions but ultimately deal with statements */
10572
10573     case THROW_EXPR:
10574       wfl_op1 = TREE_OPERAND (node, 0);
10575       COMPLETE_CHECK_OP_0 (node);
10576       /* 14.19 A throw statement cannot complete normally. */
10577       CAN_COMPLETE_NORMALLY (node) = 0;
10578       return patch_throw_statement (node, wfl_op1);
10579
10580     case SYNCHRONIZED_EXPR:
10581       wfl_op1 = TREE_OPERAND (node, 0);
10582       return patch_synchronized_statement (node, wfl_op1);
10583
10584     case TRY_EXPR:
10585       return patch_try_statement (node);
10586
10587     case TRY_FINALLY_EXPR:
10588       COMPLETE_CHECK_OP_0 (node);
10589       COMPLETE_CHECK_OP_1 (node);
10590       CAN_COMPLETE_NORMALLY (node)
10591         = (CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0))
10592            && CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)));
10593       TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 0));
10594       return node;
10595
10596     case CLEANUP_POINT_EXPR:
10597       COMPLETE_CHECK_OP_0 (node);
10598       TREE_TYPE (node) = void_type_node;
10599       CAN_COMPLETE_NORMALLY (node) = 
10600         CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
10601       return node;
10602
10603     case WITH_CLEANUP_EXPR:
10604       COMPLETE_CHECK_OP_0 (node);
10605       COMPLETE_CHECK_OP_2 (node);
10606       CAN_COMPLETE_NORMALLY (node) = 
10607         CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
10608       TREE_TYPE (node) = void_type_node;
10609       return node;
10610
10611     case LABELED_BLOCK_EXPR:
10612       PUSH_LABELED_BLOCK (node);
10613       if (LABELED_BLOCK_BODY (node))
10614         COMPLETE_CHECK_OP_1 (node);
10615       TREE_TYPE (node) = void_type_node;
10616       POP_LABELED_BLOCK ();
10617
10618       if (LABELED_BLOCK_BODY (node) == empty_stmt_node)
10619         {
10620           LABELED_BLOCK_BODY (node) = NULL_TREE;
10621           CAN_COMPLETE_NORMALLY (node) = 1;
10622         }
10623       else if (CAN_COMPLETE_NORMALLY (LABELED_BLOCK_BODY (node)))
10624         CAN_COMPLETE_NORMALLY (node) = 1;
10625       return node;
10626
10627     case EXIT_BLOCK_EXPR:
10628       /* We don't complete operand 1, because it's the return value of
10629          the EXIT_BLOCK_EXPR which doesn't exist it Java */
10630       return patch_bc_statement (node);
10631
10632     case CASE_EXPR:
10633       cn = java_complete_tree (TREE_OPERAND (node, 0));
10634       if (cn == error_mark_node)
10635         return cn;
10636
10637       /* First, the case expression must be constant. Values of final
10638          fields are accepted. */
10639       cn = fold (cn);
10640       if ((TREE_CODE (cn) == COMPOUND_EXPR || TREE_CODE (cn) == COMPONENT_REF)
10641           && JDECL_P (TREE_OPERAND (cn, 1))
10642           && FIELD_FINAL (TREE_OPERAND (cn, 1))
10643           && DECL_INITIAL (TREE_OPERAND (cn, 1)))
10644         {
10645           push_obstacks (&permanent_obstack, &permanent_obstack);
10646           cn = fold_constant_for_init (DECL_INITIAL (TREE_OPERAND (cn, 1)),
10647                                        TREE_OPERAND (cn, 1));
10648           pop_obstacks ();
10649         }
10650
10651       if (!TREE_CONSTANT (cn) && !flag_emit_xref)
10652         {
10653           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10654           parse_error_context (node, "Constant expression required");
10655           return error_mark_node;
10656         }
10657
10658       nn = ctxp->current_loop;
10659
10660       /* It must be assignable to the type of the switch expression. */
10661       if (!try_builtin_assignconv (NULL_TREE, 
10662                                    TREE_TYPE (TREE_OPERAND (nn, 0)), cn))
10663         {
10664           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10665           parse_error_context 
10666             (wfl_operator,
10667              "Incompatible type for case. Can't convert `%s' to `int'",
10668              lang_printable_name (TREE_TYPE (cn), 0));
10669           return error_mark_node;
10670         }
10671
10672       cn = fold (convert (int_type_node, cn));
10673
10674       /* Multiple instance of a case label bearing the same
10675          value is checked during code generation. The case
10676          expression is allright so far. */
10677       TREE_OPERAND (node, 0) = cn;
10678       TREE_TYPE (node) = void_type_node;
10679       CAN_COMPLETE_NORMALLY (node) = 1;
10680       TREE_SIDE_EFFECTS (node) = 1;
10681       break;
10682
10683     case DEFAULT_EXPR:
10684       nn = ctxp->current_loop;
10685       /* Only one default label is allowed per switch statement */
10686       if (SWITCH_HAS_DEFAULT (nn))
10687         {
10688           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10689           parse_error_context (wfl_operator, 
10690                                "Duplicate case label: `default'");
10691           return error_mark_node;
10692         }
10693       else
10694         SWITCH_HAS_DEFAULT (nn) = 1;
10695       TREE_TYPE (node) = void_type_node;
10696       TREE_SIDE_EFFECTS (node) = 1;
10697       CAN_COMPLETE_NORMALLY (node) = 1;
10698       break;
10699
10700     case SWITCH_EXPR:
10701     case LOOP_EXPR:
10702       PUSH_LOOP (node);
10703       /* Check whether the loop was enclosed in a labeled
10704          statement. If not, create one, insert the loop in it and
10705          return the node */
10706       nn = patch_loop_statement (node);
10707
10708       /* Anyways, walk the body of the loop */
10709       if (TREE_CODE (node) == LOOP_EXPR)
10710         TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
10711       /* Switch statement: walk the switch expression and the cases */
10712       else
10713         node = patch_switch_statement (node);
10714
10715       if (TREE_OPERAND (node, 0) == error_mark_node)
10716         nn = error_mark_node;
10717       else
10718         {
10719           TREE_TYPE (nn) = TREE_TYPE (node) = void_type_node;
10720           /* If we returned something different, that's because we
10721              inserted a label. Pop the label too. */
10722           if (nn != node)
10723             {
10724               if (CAN_COMPLETE_NORMALLY (node))
10725                 CAN_COMPLETE_NORMALLY (nn) = 1;
10726               POP_LABELED_BLOCK ();
10727             }
10728         }
10729       POP_LOOP ();
10730       return nn;
10731
10732     case EXIT_EXPR:
10733       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
10734       return patch_exit_expr (node);
10735
10736     case COND_EXPR:
10737       /* Condition */
10738       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
10739       if (TREE_OPERAND (node, 0) == error_mark_node)
10740         return error_mark_node;
10741       /* then-else branches */
10742       TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
10743       if (TREE_OPERAND (node, 1) == error_mark_node)
10744         return error_mark_node;
10745       TREE_OPERAND (node, 2) = java_complete_tree (TREE_OPERAND (node, 2));
10746       if (TREE_OPERAND (node, 2) == error_mark_node)
10747         return error_mark_node;
10748       return patch_if_else_statement (node);
10749       break;
10750
10751     case CONDITIONAL_EXPR:
10752       /* Condition */
10753       wfl_op1 = TREE_OPERAND (node, 0);
10754       COMPLETE_CHECK_OP_0 (node);
10755       wfl_op2 = TREE_OPERAND (node, 1);
10756       COMPLETE_CHECK_OP_1 (node);
10757       wfl_op3 = TREE_OPERAND (node, 2);
10758       COMPLETE_CHECK_OP_2 (node);
10759       return patch_conditional_expr (node, wfl_op1, wfl_op2);
10760
10761       /* 3- Expression section */
10762     case COMPOUND_EXPR:
10763       wfl_op2 = TREE_OPERAND (node, 1);
10764       TREE_OPERAND (node, 0) = nn = 
10765         java_complete_tree (TREE_OPERAND (node, 0));
10766       if (wfl_op2 == empty_stmt_node)
10767         CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (nn);
10768       else
10769         {
10770           if (! CAN_COMPLETE_NORMALLY (nn) && TREE_CODE (nn) != ERROR_MARK)
10771             {
10772               /* An unreachable condition in a do-while statement
10773                  is *not* (technically) an unreachable statement. */
10774               nn = wfl_op2;
10775               if (TREE_CODE (nn) == EXPR_WITH_FILE_LOCATION)
10776                 nn = EXPR_WFL_NODE (nn);
10777               if (TREE_CODE (nn) != EXIT_EXPR)
10778                 {
10779                   SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
10780                   parse_error_context (wfl_operator, "Unreachable statement");
10781                 }
10782             }
10783           TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
10784           if (TREE_OPERAND (node, 1) == error_mark_node)
10785             return error_mark_node;
10786           CAN_COMPLETE_NORMALLY (node)
10787             = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1));
10788         }
10789       TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 1));
10790       break;
10791
10792     case RETURN_EXPR:
10793       /* CAN_COMPLETE_NORMALLY (node) = 0; */
10794       return patch_return (node);
10795
10796     case EXPR_WITH_FILE_LOCATION:
10797       if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
10798           || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
10799         {
10800           tree wfl = node;
10801           node = resolve_expression_name (node, NULL);
10802           if (node == error_mark_node)
10803             return node;
10804           /* Keep line number information somewhere were it doesn't
10805              disrupt the completion process. */
10806           if (flag_emit_xref && TREE_CODE (node) != CALL_EXPR)
10807             {
10808               EXPR_WFL_NODE (wfl) = TREE_OPERAND (node, 1);
10809               TREE_OPERAND (node, 1) = wfl;
10810             }
10811           CAN_COMPLETE_NORMALLY (node) = 1;
10812         }
10813       else
10814         {
10815           tree body;
10816           int save_lineno = lineno;
10817           lineno = EXPR_WFL_LINENO (node);
10818           body = java_complete_tree (EXPR_WFL_NODE (node));
10819           lineno = save_lineno;
10820           EXPR_WFL_NODE (node) = body;
10821           TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (body);
10822           CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (body);
10823           if (body == empty_stmt_node)
10824             {
10825               /* Optimization;  makes it easier to detect empty bodies. */
10826               return body;
10827             }
10828           if (body == error_mark_node)
10829             {
10830               /* Its important for the evaluation of assignment that
10831                  this mark on the TREE_TYPE is propagated. */
10832               TREE_TYPE (node) = error_mark_node;
10833               return error_mark_node;
10834             }
10835           else
10836             TREE_TYPE (node) = TREE_TYPE (EXPR_WFL_NODE (node));
10837           
10838         }
10839       break;
10840
10841     case NEW_ARRAY_EXPR:
10842       /* Patch all the dimensions */
10843       flag = 0;
10844       for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
10845         {
10846           int location = EXPR_WFL_LINECOL (TREE_VALUE (cn));
10847           tree dim = convert (int_type_node, 
10848                               java_complete_tree (TREE_VALUE (cn)));
10849           if (dim == error_mark_node)
10850             {
10851               flag = 1;
10852               continue;
10853             }
10854           else
10855             {
10856               TREE_VALUE (cn) = dim;
10857               /* Setup the location of the current dimension, for
10858                  later error report. */
10859               TREE_PURPOSE (cn) = 
10860                 build_expr_wfl (NULL_TREE, input_filename, 0, 0);
10861               EXPR_WFL_LINECOL (TREE_PURPOSE (cn)) = location;
10862             }
10863         }
10864       /* They complete the array creation expression, if no errors
10865          were found. */
10866       CAN_COMPLETE_NORMALLY (node) = 1;
10867       return (flag ? error_mark_node
10868               : force_evaluation_order (patch_newarray (node)));
10869
10870     case NEW_ANONYMOUS_ARRAY_EXPR:
10871       /* Create the array type if necessary. */
10872       if (ANONYMOUS_ARRAY_DIMS_SIG (node))
10873         {
10874           tree type = ANONYMOUS_ARRAY_BASE_TYPE (node);
10875           if (!(type = resolve_type_during_patch (type)))
10876             return error_mark_node;
10877           type = build_array_from_name (type, NULL_TREE,
10878                                         ANONYMOUS_ARRAY_DIMS_SIG (node), NULL);
10879           ANONYMOUS_ARRAY_BASE_TYPE (node) = build_pointer_type (type);
10880         }
10881       node = patch_new_array_init (ANONYMOUS_ARRAY_BASE_TYPE (node),
10882                                    ANONYMOUS_ARRAY_INITIALIZER (node));
10883       if (node == error_mark_node)
10884         return error_mark_node;
10885       CAN_COMPLETE_NORMALLY (node) = 1;
10886       return node;
10887
10888     case NEW_CLASS_EXPR:
10889     case CALL_EXPR:
10890       /* Complete function's argument(s) first */
10891       if (complete_function_arguments (node))
10892         return error_mark_node;
10893       else
10894         {
10895           tree decl, wfl = TREE_OPERAND (node, 0);
10896           int in_this = CALL_THIS_CONSTRUCTOR_P (node);
10897
10898           node = patch_method_invocation (node, NULL_TREE, 
10899                                           NULL_TREE, 0, &decl);
10900           if (node == error_mark_node)
10901             return error_mark_node;
10902
10903           check_thrown_exceptions (EXPR_WFL_LINECOL (node), decl);
10904           /* If we call this(...), register signature and positions */
10905           if (in_this)
10906             DECL_CONSTRUCTOR_CALLS (current_function_decl) = 
10907               tree_cons (wfl, decl, 
10908                          DECL_CONSTRUCTOR_CALLS (current_function_decl));
10909           CAN_COMPLETE_NORMALLY (node) = 1;
10910           return force_evaluation_order (node);
10911         }
10912
10913     case MODIFY_EXPR:
10914       /* Save potential wfls */
10915       wfl_op1 = TREE_OPERAND (node, 0);
10916       TREE_OPERAND (node, 0) = nn = java_complete_lhs (wfl_op1);
10917       
10918       if (MODIFY_EXPR_FROM_INITIALIZATION_P (node)
10919           && TREE_CODE (nn) == VAR_DECL && TREE_STATIC (nn)
10920           && DECL_INITIAL (nn) != NULL_TREE)
10921         {
10922           tree value;
10923           
10924           push_obstacks (&permanent_obstack, &permanent_obstack);
10925           value = fold_constant_for_init (nn, nn);
10926           pop_obstacks ();
10927
10928           if (value != NULL_TREE)
10929             {
10930               tree type = TREE_TYPE (value);
10931               if (JPRIMITIVE_TYPE_P (type) || 
10932                   (type == string_ptr_type_node && ! flag_emit_class_files))
10933                 return empty_stmt_node;
10934             }
10935           DECL_INITIAL (nn) = NULL_TREE;
10936         }
10937       wfl_op2 = TREE_OPERAND (node, 1);
10938
10939       if (TREE_OPERAND (node, 0) == error_mark_node)
10940         return error_mark_node;
10941
10942       flag = COMPOUND_ASSIGN_P (wfl_op2);
10943       if (flag)
10944         {
10945           /* This might break when accessing outer field from inner
10946              class. TESTME, FIXME */
10947           tree lvalue = java_stabilize_reference (TREE_OPERAND (node, 0)); 
10948
10949           /* Hand stablize the lhs on both places */
10950           TREE_OPERAND (node, 0) = lvalue;
10951           TREE_OPERAND (TREE_OPERAND (node, 1), 0) = 
10952             (flag_emit_class_files ? lvalue : save_expr (lvalue));
10953
10954           /* 15.25.2.a: Left hand is not an array access. FIXME */
10955           /* Now complete the RHS. We write it back later on. */
10956           nn = java_complete_tree (TREE_OPERAND (node, 1));
10957
10958           if ((cn = patch_string (nn)))
10959             nn = cn;
10960
10961           /* The last part of the rewrite for E1 op= E2 is to have 
10962              E1 = (T)(E1 op E2), with T being the type of E1. */
10963           nn = java_complete_tree (build_cast (EXPR_WFL_LINECOL (wfl_op2), 
10964                                                TREE_TYPE (lvalue), nn));
10965
10966           /* 15.25.2.b: Left hand is an array access. FIXME */
10967         }
10968
10969       /* If we're about to patch a NEW_ARRAY_INIT, we call a special
10970          function to complete this RHS. Note that a NEW_ARRAY_INIT
10971          might have been already fully expanded if created as a result
10972          of processing an anonymous array initializer. We avoid doing
10973          the operation twice by testing whether the node already bears
10974          a type. */
10975       else if (TREE_CODE (wfl_op2) == NEW_ARRAY_INIT && !TREE_TYPE (wfl_op2))
10976         nn = patch_new_array_init (TREE_TYPE (TREE_OPERAND (node, 0)),
10977                                    TREE_OPERAND (node, 1));
10978       /* Otherwise we simply complete the RHS */
10979       else
10980         nn = java_complete_tree (TREE_OPERAND (node, 1));
10981
10982       if (nn == error_mark_node)
10983         return error_mark_node;
10984
10985       /* Write back the RHS as we evaluated it. */
10986       TREE_OPERAND (node, 1) = nn;
10987
10988       /* In case we're handling = with a String as a RHS, we need to
10989          produce a String out of the RHS (it might still be a
10990          STRING_CST or a StringBuffer at this stage */
10991       if ((nn = patch_string (TREE_OPERAND (node, 1))))
10992         TREE_OPERAND (node, 1) = nn;
10993
10994       if ((nn = outer_field_access_fix (wfl_op1, TREE_OPERAND (node, 0),
10995                                         TREE_OPERAND (node, 1))))
10996         {
10997           /* We return error_mark_node if outer_field_access_fix
10998              detects we write into a final. */
10999           if (nn == error_mark_node)
11000             return error_mark_node;
11001           node = nn;
11002         }
11003       else
11004         {
11005           node = patch_assignment (node, wfl_op1, wfl_op2);
11006           /* Reorganize the tree if necessary. */
11007           if (flag && (!JREFERENCE_TYPE_P (TREE_TYPE (node)) 
11008                        || JSTRING_P (TREE_TYPE (node))))
11009             node = java_refold (node);
11010         }
11011       
11012       CAN_COMPLETE_NORMALLY (node) = 1;
11013       return node;
11014
11015     case MULT_EXPR:
11016     case PLUS_EXPR:
11017     case MINUS_EXPR:
11018     case LSHIFT_EXPR:
11019     case RSHIFT_EXPR:
11020     case URSHIFT_EXPR:
11021     case BIT_AND_EXPR:
11022     case BIT_XOR_EXPR:
11023     case BIT_IOR_EXPR:
11024     case TRUNC_MOD_EXPR:
11025     case TRUNC_DIV_EXPR:
11026     case RDIV_EXPR:
11027     case TRUTH_ANDIF_EXPR:
11028     case TRUTH_ORIF_EXPR:
11029     case EQ_EXPR: 
11030     case NE_EXPR:
11031     case GT_EXPR:
11032     case GE_EXPR:
11033     case LT_EXPR:
11034     case LE_EXPR:
11035       /* Operands 0 and 1 are WFL in certain cases only. patch_binop
11036          knows how to handle those cases. */
11037       wfl_op1 = TREE_OPERAND (node, 0);
11038       wfl_op2 = TREE_OPERAND (node, 1);
11039
11040       CAN_COMPLETE_NORMALLY (node) = 1;
11041       /* Don't complete string nodes if dealing with the PLUS operand. */
11042       if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op1))
11043         {
11044           nn = java_complete_tree (wfl_op1);
11045           if (nn == error_mark_node)
11046             return error_mark_node;
11047
11048           TREE_OPERAND (node, 0) = nn;
11049         }
11050       if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op2))
11051         {
11052           nn = java_complete_tree (wfl_op2);
11053           if (nn == error_mark_node)
11054             return error_mark_node;
11055
11056           TREE_OPERAND (node, 1) = nn;
11057         }
11058       return force_evaluation_order (patch_binop (node, wfl_op1, wfl_op2));
11059
11060     case INSTANCEOF_EXPR:
11061       wfl_op1 = TREE_OPERAND (node, 0);
11062       COMPLETE_CHECK_OP_0 (node);
11063       if (flag_emit_xref)
11064         {
11065           TREE_TYPE (node) = boolean_type_node;
11066           return node;
11067         }
11068       return patch_binop (node, wfl_op1, TREE_OPERAND (node, 1));
11069
11070     case UNARY_PLUS_EXPR:
11071     case NEGATE_EXPR:
11072     case TRUTH_NOT_EXPR:
11073     case BIT_NOT_EXPR:
11074     case PREDECREMENT_EXPR:
11075     case PREINCREMENT_EXPR:
11076     case POSTDECREMENT_EXPR:
11077     case POSTINCREMENT_EXPR:
11078     case CONVERT_EXPR:
11079       /* There are cases were wfl_op1 is a WFL. patch_unaryop knows
11080          how to handle those cases. */
11081       wfl_op1 = TREE_OPERAND (node, 0);
11082       CAN_COMPLETE_NORMALLY (node) = 1;
11083       TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
11084       if (TREE_OPERAND (node, 0) == error_mark_node)
11085         return error_mark_node;
11086       node = patch_unaryop (node, wfl_op1);
11087       CAN_COMPLETE_NORMALLY (node) = 1;
11088       break;
11089
11090     case ARRAY_REF:
11091       /* There are cases were wfl_op1 is a WFL. patch_array_ref knows
11092          how to handle those cases. */
11093       wfl_op1 = TREE_OPERAND (node, 0);
11094       TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
11095       if (TREE_OPERAND (node, 0) == error_mark_node)
11096         return error_mark_node;
11097       if (!flag_emit_class_files && !flag_emit_xref)
11098         TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
11099       /* The same applies to wfl_op2 */
11100       wfl_op2 = TREE_OPERAND (node, 1);
11101       TREE_OPERAND (node, 1) = java_complete_tree (wfl_op2);
11102       if (TREE_OPERAND (node, 1) == error_mark_node)
11103         return error_mark_node;
11104       if (!flag_emit_class_files && !flag_emit_xref)
11105         TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1));
11106       return patch_array_ref (node);
11107
11108     case RECORD_TYPE:
11109       return node;;
11110
11111     case COMPONENT_REF:
11112       /* The first step in the re-write of qualified name handling.  FIXME.
11113          So far, this is only to support PRIMTYPE.class -> PRIMCLASS.TYPE. */
11114       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
11115       if (TREE_CODE (TREE_OPERAND (node, 0)) == RECORD_TYPE)
11116         {
11117           tree name = TREE_OPERAND (node, 1);
11118           tree field = lookup_field_wrapper (TREE_OPERAND (node, 0), name);
11119           if (field == NULL_TREE)
11120             {
11121               error ("missing static field `%s'", IDENTIFIER_POINTER (name));
11122               return error_mark_node;
11123             }
11124           if (! FIELD_STATIC (field))
11125             {
11126               error ("not a static field `%s'", IDENTIFIER_POINTER (name));
11127               return error_mark_node;
11128             }
11129           return field;
11130         }
11131       else
11132         fatal ("unimplemented java_complete_tree for COMPONENT_REF");
11133       break;
11134
11135     case THIS_EXPR:
11136       /* Can't use THIS in a static environment */
11137       if (!current_this)
11138         {
11139           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11140           parse_error_context (wfl_operator,
11141                                "Keyword `this' used outside allowed context");
11142           TREE_TYPE (node) = error_mark_node;
11143           return error_mark_node;
11144         }
11145       if (ctxp->explicit_constructor_p)
11146         {
11147           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11148           parse_error_context 
11149             (wfl_operator, "Can't reference `this' or `super' before the superclass constructor has been called");
11150           TREE_TYPE (node) = error_mark_node;
11151           return error_mark_node;
11152         }
11153       return current_this;
11154       
11155     case CLASS_LITERAL:
11156       CAN_COMPLETE_NORMALLY (node) = 1;
11157       node = patch_incomplete_class_ref (node);
11158       if (node == error_mark_node)
11159         return error_mark_node;
11160       break;
11161
11162     case INSTANCE_INITIALIZERS_EXPR:
11163       in_instance_initializer++;
11164       node = java_complete_tree (TREE_OPERAND (node, 0));
11165       in_instance_initializer--;
11166       if (node != error_mark_node)
11167         TREE_TYPE (node) = void_type_node;
11168       else
11169         return error_mark_node;
11170       break;
11171
11172     default:
11173       CAN_COMPLETE_NORMALLY (node) = 1;
11174       /* Ok: may be we have a STRING_CST or a crafted `StringBuffer'
11175          and it's time to turn it into the appropriate String object */
11176       if ((nn = patch_string (node)))
11177         node = nn;
11178       else
11179         fatal ("No case for tree code `%s' - java_complete_tree\n",
11180                tree_code_name [TREE_CODE (node)]);
11181     }
11182   return node;
11183 }
11184
11185 /* Complete function call's argument. Return a non zero value is an
11186    error was found.  */
11187
11188 static int
11189 complete_function_arguments (node)
11190      tree node;
11191 {
11192   int flag = 0;
11193   tree cn;
11194
11195   ctxp->explicit_constructor_p += (CALL_EXPLICIT_CONSTRUCTOR_P (node) ? 1 : 0);
11196   for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
11197     {
11198       tree wfl = TREE_VALUE (cn), parm, temp;
11199       parm = java_complete_tree (wfl);
11200
11201       if (parm == error_mark_node)
11202         {
11203           flag = 1;
11204           continue;
11205         }
11206       /* If have a string literal that we haven't transformed yet or a
11207          crafted string buffer, as a result of use of the the String
11208          `+' operator. Build `parm.toString()' and expand it. */
11209       if ((temp = patch_string (parm)))
11210         parm = temp;
11211       /* Inline PRIMTYPE.TYPE read access */
11212       parm = maybe_build_primttype_type_ref (parm, wfl);
11213
11214       TREE_VALUE (cn) = parm;
11215     }
11216   ctxp->explicit_constructor_p -= (CALL_EXPLICIT_CONSTRUCTOR_P (node) ? 1 : 0);
11217   return flag;
11218 }
11219
11220 /* Sometimes (for loops and variable initialized during their
11221    declaration), we want to wrap a statement around a WFL and turn it
11222    debugable.  */
11223
11224 static tree
11225 build_debugable_stmt (location, stmt)
11226     int location;
11227     tree stmt;
11228 {
11229   if (TREE_CODE (stmt) != EXPR_WITH_FILE_LOCATION)
11230     {
11231       stmt = build_expr_wfl (stmt, input_filename, 0, 0);
11232       EXPR_WFL_LINECOL (stmt) = location;
11233     }
11234   JAVA_MAYBE_GENERATE_DEBUG_INFO (stmt);
11235   return stmt;
11236 }
11237
11238 static tree
11239 build_expr_block (body, decls)
11240      tree body, decls;
11241 {
11242   tree node = make_node (BLOCK);
11243   BLOCK_EXPR_DECLS (node) = decls;
11244   BLOCK_EXPR_BODY (node) = body;
11245   if (body)
11246     TREE_TYPE (node) = TREE_TYPE (body);
11247   TREE_SIDE_EFFECTS (node) = 1;
11248   return node;
11249 }
11250
11251 /* Create a new function block and link it approriately to current
11252    function block chain */
11253
11254 static tree
11255 enter_block ()
11256 {
11257   return (enter_a_block (build_expr_block (NULL_TREE, NULL_TREE)));
11258 }
11259
11260 /* Link block B supercontext to the previous block. The current
11261    function DECL is used as supercontext when enter_a_block is called
11262    for the first time for a given function. The current function body
11263    (DECL_FUNCTION_BODY) is set to be block B.  */
11264
11265 static tree
11266 enter_a_block (b)
11267      tree b;
11268 {
11269   tree fndecl = current_function_decl; 
11270
11271   if (!fndecl) {
11272     BLOCK_SUPERCONTEXT (b) = current_static_block;
11273     current_static_block = b;
11274   }
11275
11276   else if (!DECL_FUNCTION_BODY (fndecl))
11277     {
11278       BLOCK_SUPERCONTEXT (b) = fndecl;
11279       DECL_FUNCTION_BODY (fndecl) = b;
11280     }
11281   else
11282     {
11283       BLOCK_SUPERCONTEXT (b) = DECL_FUNCTION_BODY (fndecl);
11284       DECL_FUNCTION_BODY (fndecl) = b;
11285     }
11286   return b;
11287 }
11288
11289 /* Exit a block by changing the current function body
11290    (DECL_FUNCTION_BODY) to the current block super context, only if
11291    the block being exited isn't the method's top level one.  */
11292
11293 static tree
11294 exit_block ()
11295 {
11296   tree b;
11297   if (current_function_decl)
11298     {
11299       b = DECL_FUNCTION_BODY (current_function_decl);
11300       if (BLOCK_SUPERCONTEXT (b) != current_function_decl)
11301         DECL_FUNCTION_BODY (current_function_decl) = BLOCK_SUPERCONTEXT (b);
11302     }
11303   else
11304     {
11305       b = current_static_block;
11306
11307       if (BLOCK_SUPERCONTEXT (b))
11308         current_static_block = BLOCK_SUPERCONTEXT (b);
11309     }
11310   return b;
11311 }
11312
11313 /* Lookup for NAME in the nested function's blocks, all the way up to
11314    the current toplevel one. It complies with Java's local variable
11315    scoping rules.  */
11316
11317 static tree
11318 lookup_name_in_blocks (name)
11319      tree name;
11320 {
11321   tree b = GET_CURRENT_BLOCK (current_function_decl);
11322
11323   while (b != current_function_decl)
11324     {
11325       tree current;
11326
11327       /* Paranoid sanity check. To be removed */
11328       if (TREE_CODE (b) != BLOCK)
11329         fatal ("non block expr function body - lookup_name_in_blocks");
11330
11331       for (current = BLOCK_EXPR_DECLS (b); current; 
11332            current = TREE_CHAIN (current))
11333         if (DECL_NAME (current) == name)
11334           return current;
11335       b = BLOCK_SUPERCONTEXT (b);
11336     }
11337   return NULL_TREE;
11338 }
11339
11340 static void
11341 maybe_absorb_scoping_blocks ()
11342 {
11343   while (BLOCK_EXPR_ORIGIN (GET_CURRENT_BLOCK (current_function_decl)))
11344     {
11345       tree b = exit_block ();
11346       java_method_add_stmt (current_function_decl, b);
11347       SOURCE_FRONTEND_DEBUG (("Absorbing scoping block at line %d", lineno));
11348     }
11349 }
11350
11351 \f
11352 /* This section of the source is reserved to build_* functions that
11353    are building incomplete tree nodes and the patch_* functions that
11354    are completing them.  */
11355
11356 /* Wrap a non WFL node around a WFL.  */
11357 static tree
11358 build_wfl_wrap (node)
11359     tree node;
11360 {
11361   tree wfl, node_to_insert = node;
11362   
11363   /* We want to process THIS . xxx symbolicaly, to keep it consistent
11364      with the way we're processing SUPER. A THIS from a primary as a
11365      different form than a SUPER. Turn THIS into something symbolic */
11366   if (TREE_CODE (node) == THIS_EXPR)
11367     node_to_insert = wfl = build_wfl_node (this_identifier_node);
11368   else
11369     wfl = build_expr_wfl (NULL_TREE, ctxp->filename, 0, 0);
11370
11371   EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (node);
11372   EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (node_to_insert, NULL_TREE);
11373   return wfl;
11374 }
11375
11376
11377 /* Build a super() constructor invocation. Returns empty_stmt_node if
11378    we're currently dealing with the class java.lang.Object. */
11379
11380 static tree
11381 build_super_invocation (mdecl)
11382      tree mdecl;
11383 {
11384   if (DECL_CONTEXT (mdecl) == object_type_node)
11385     return empty_stmt_node;
11386   else
11387     {
11388       tree super_wfl = build_wfl_node (super_identifier_node);
11389       tree a = NULL_TREE, t;
11390       /* If we're dealing with an anonymous class, pass the arguments
11391          of the crafted constructor along. */
11392       if (ANONYMOUS_CLASS_P (DECL_CONTEXT (mdecl)))
11393         {
11394           SKIP_THIS_AND_ARTIFICIAL_PARMS (t, mdecl);
11395           for (; t != end_params_node; t = TREE_CHAIN (t))
11396             a = tree_cons (NULL_TREE, build_wfl_node (TREE_PURPOSE (t)), a);
11397         }
11398       return build_method_invocation (super_wfl, a);
11399     }
11400 }
11401
11402 /* Build a SUPER/THIS qualified method invocation.  */
11403
11404 static tree
11405 build_this_super_qualified_invocation (use_this, name, args, lloc, rloc)
11406      int use_this;
11407      tree name, args;
11408      int lloc, rloc;
11409 {
11410   tree invok;
11411   tree wfl = 
11412     build_wfl_node (use_this ? this_identifier_node : super_identifier_node);
11413   EXPR_WFL_LINECOL (wfl) = lloc;
11414   invok = build_method_invocation (name, args);
11415   return make_qualified_primary (wfl, invok, rloc);
11416 }
11417
11418 /* Build an incomplete CALL_EXPR node. */
11419
11420 static tree
11421 build_method_invocation (name, args)
11422     tree name;
11423     tree args;
11424 {
11425   tree call = build (CALL_EXPR, NULL_TREE, name, args, NULL_TREE);
11426   TREE_SIDE_EFFECTS (call) = 1;
11427   EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
11428   return call;
11429 }
11430
11431 /* Build an incomplete new xxx(...) node. */
11432
11433 static tree
11434 build_new_invocation (name, args)
11435     tree name, args;
11436 {
11437   tree call = build (NEW_CLASS_EXPR, NULL_TREE, name, args, NULL_TREE);
11438   TREE_SIDE_EFFECTS (call) = 1;
11439   EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
11440   return call;
11441 }
11442
11443 /* Build an incomplete assignment expression. */
11444
11445 static tree
11446 build_assignment (op, op_location, lhs, rhs)
11447      int op, op_location;
11448      tree lhs, rhs;
11449 {
11450   tree assignment;
11451   /* Build the corresponding binop if we deal with a Compound
11452      Assignment operator. Mark the binop sub-tree as part of a
11453      Compound Assignment expression */
11454   if (op != ASSIGN_TK)
11455     {
11456       rhs = build_binop (BINOP_LOOKUP (op), op_location, lhs, rhs);
11457       COMPOUND_ASSIGN_P (rhs) = 1;
11458     }
11459   assignment = build (MODIFY_EXPR, NULL_TREE, lhs, rhs);
11460   TREE_SIDE_EFFECTS (assignment) = 1;
11461   EXPR_WFL_LINECOL (assignment) = op_location;
11462   return assignment;
11463 }
11464
11465 /* Print an INTEGER_CST node in a static buffer, and return the buffer. */
11466
11467 char *
11468 print_int_node (node)
11469     tree node;
11470 {
11471   static char buffer [80];
11472   if (TREE_CONSTANT_OVERFLOW (node))
11473     sprintf (buffer, "<overflow>");
11474     
11475   if (TREE_INT_CST_HIGH (node) == 0)
11476     sprintf (buffer, HOST_WIDE_INT_PRINT_UNSIGNED,
11477              TREE_INT_CST_LOW (node));
11478   else if (TREE_INT_CST_HIGH (node) == -1
11479            && TREE_INT_CST_LOW (node) != 0)
11480     {
11481       buffer [0] = '-';
11482       sprintf (&buffer [1], HOST_WIDE_INT_PRINT_UNSIGNED,
11483                -TREE_INT_CST_LOW (node));
11484     }
11485   else
11486     sprintf (buffer, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
11487              TREE_INT_CST_HIGH (node), TREE_INT_CST_LOW (node));
11488
11489   return buffer;
11490 }
11491
11492 /* Return 1 if an assignment to a FINAL is attempted in a non suitable
11493    context.  */
11494
11495 static int
11496 check_final_assignment (lvalue, wfl)
11497      tree lvalue, wfl;
11498 {
11499   if (TREE_CODE (lvalue) == COMPOUND_EXPR 
11500       && JDECL_P (TREE_OPERAND (lvalue, 1)))
11501     lvalue = TREE_OPERAND (lvalue, 1);
11502
11503   /* When generating class files, references to the `length' field
11504      look a bit different.  */
11505   if ((flag_emit_class_files
11506        && TREE_CODE (lvalue) == COMPONENT_REF
11507        && TYPE_ARRAY_P (TREE_TYPE (TREE_OPERAND (lvalue, 0)))
11508        && FIELD_FINAL (TREE_OPERAND (lvalue, 1)))
11509       || (TREE_CODE (lvalue) == FIELD_DECL
11510           && FIELD_FINAL (lvalue)
11511           && !DECL_CLINIT_P (current_function_decl)
11512           && !DECL_FINIT_P (current_function_decl)))
11513     {
11514       parse_error_context 
11515         (wfl, "Can't assign a value to the final variable `%s'",
11516          IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
11517       return 1;
11518     }
11519   return 0;
11520 }
11521
11522 /* Inline references to java.lang.PRIMTYPE.TYPE when accessed in
11523    read. This is needed to avoid circularities in the implementation
11524    of these fields in libjava. */
11525
11526 static tree
11527 maybe_build_primttype_type_ref (rhs, wfl)
11528     tree rhs, wfl;
11529 {
11530   tree to_return = NULL_TREE;
11531   tree rhs_type = TREE_TYPE (rhs);
11532   if (TREE_CODE (rhs) == COMPOUND_EXPR)
11533     {
11534       tree n = TREE_OPERAND (rhs, 1);
11535       if (TREE_CODE (n) == VAR_DECL 
11536           && DECL_NAME (n) == TYPE_identifier_node
11537           && rhs_type == class_ptr_type)
11538         {
11539           const char *self_name = IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl));
11540           if (!strncmp (self_name, "java.lang.", 10))
11541             to_return = build_primtype_type_ref (self_name);
11542         }
11543     }
11544   return (to_return ? to_return : rhs );
11545 }
11546
11547 /* 15.25 Assignment operators. */
11548
11549 static tree
11550 patch_assignment (node, wfl_op1, wfl_op2)
11551      tree node;
11552      tree wfl_op1;
11553      tree wfl_op2;
11554 {
11555   tree rhs = TREE_OPERAND (node, 1);
11556   tree lvalue = TREE_OPERAND (node, 0), llvalue;
11557   tree lhs_type = NULL_TREE, rhs_type, new_rhs = NULL_TREE;
11558   int error_found = 0;
11559   int lvalue_from_array = 0;
11560
11561   /* Can't assign to a (blank) final. */
11562   if (check_final_assignment (lvalue, wfl_op1))
11563     error_found = 1;
11564
11565   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11566
11567   /* Lhs can be a named variable */
11568   if (JDECL_P (lvalue))
11569     {
11570       lhs_type = TREE_TYPE (lvalue);
11571     }
11572   /* Or Lhs can be a array acccess. Should that be lvalue ? FIXME +
11573      comment on reason why */
11574   else if (TREE_CODE (wfl_op1) == ARRAY_REF)
11575     {
11576       lhs_type = TREE_TYPE (lvalue);
11577       lvalue_from_array = 1;
11578     }
11579   /* Or a field access */
11580   else if (TREE_CODE (lvalue) == COMPONENT_REF)
11581     lhs_type = TREE_TYPE (lvalue);
11582   /* Or a function return slot */
11583   else if (TREE_CODE (lvalue) == RESULT_DECL)
11584     lhs_type = TREE_TYPE (lvalue);
11585   /* Otherwise, we might want to try to write into an optimized static
11586      final, this is an of a different nature, reported further on. */
11587   else if (TREE_CODE (wfl_op1) == EXPR_WITH_FILE_LOCATION
11588            && resolve_expression_name (wfl_op1, &llvalue))
11589     {
11590       if (!error_found && check_final_assignment (llvalue, wfl_op1))
11591         {
11592           /* What we should do instead is resetting the all the flags
11593              previously set, exchange lvalue for llvalue and continue. */
11594           error_found = 1;
11595           return error_mark_node;
11596         }
11597       else 
11598         lhs_type = TREE_TYPE (lvalue);
11599     }
11600   else 
11601     {
11602       parse_error_context (wfl_op1, "Invalid left hand side of assignment");
11603       error_found = 1;
11604     }
11605
11606   rhs_type = TREE_TYPE (rhs);
11607   /* 5.1 Try the assignment conversion for builtin type. */
11608   new_rhs = try_builtin_assignconv (wfl_op1, lhs_type, rhs);
11609
11610   /* 5.2 If it failed, try a reference conversion */
11611   if (!new_rhs && (new_rhs = try_reference_assignconv (lhs_type, rhs)))
11612     lhs_type = promote_type (rhs_type);
11613
11614   /* 15.25.2 If we have a compound assignment, convert RHS into the
11615      type of the LHS */
11616   else if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
11617     new_rhs = convert (lhs_type, rhs);
11618
11619   /* Explicit cast required. This is an error */
11620   if (!new_rhs)
11621     {
11622       char *t1 = xstrdup (lang_printable_name (TREE_TYPE (rhs), 0));
11623       char *t2 = xstrdup (lang_printable_name (lhs_type, 0));
11624       tree wfl;
11625       char operation [32];      /* Max size known */
11626
11627       /* If the assignment is part of a declaration, we use the WFL of
11628          the declared variable to point out the error and call it a
11629          declaration problem. If the assignment is a genuine =
11630          operator, we call is a operator `=' problem, otherwise we
11631          call it an assignment problem. In both of these last cases,
11632          we use the WFL of the operator to indicate the error. */
11633
11634       if (MODIFY_EXPR_FROM_INITIALIZATION_P (node))
11635         {
11636           wfl = wfl_op1;
11637           strcpy (operation, "declaration");
11638         }
11639       else
11640         {
11641           wfl = wfl_operator;
11642           if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
11643             strcpy (operation, "assignment");
11644           else if (TREE_CODE (TREE_OPERAND (node, 0)) == RESULT_DECL)
11645             strcpy (operation, "`return'");
11646           else
11647             strcpy (operation, "`='");
11648         }
11649
11650       if (!valid_cast_to_p (rhs_type, lhs_type))
11651         parse_error_context
11652           (wfl, "Incompatible type for %s. Can't convert `%s' to `%s'",
11653            operation, t1, t2);
11654       else
11655         parse_error_context (wfl, "Incompatible type for %s. Explicit cast needed to convert `%s' to `%s'",
11656                              operation, t1, t2);
11657       free (t1); free (t2);
11658       error_found = 1;
11659     }
11660
11661   /* Inline read access to java.lang.PRIMTYPE.TYPE */
11662   if (new_rhs)
11663     new_rhs = maybe_build_primttype_type_ref (new_rhs, wfl_op2);
11664
11665   if (error_found)
11666     return error_mark_node;
11667
11668   /* 10.10: Array Store Exception runtime check */
11669   if (!flag_emit_class_files
11670       && !flag_emit_xref
11671       && lvalue_from_array 
11672       && JREFERENCE_TYPE_P (TYPE_ARRAY_ELEMENT (lhs_type)))
11673     {
11674       tree check;
11675       tree base = lvalue;
11676
11677       /* We need to retrieve the right argument for _Jv_CheckArrayStore */
11678       if (TREE_CODE (lvalue) == COMPOUND_EXPR)
11679         base = TREE_OPERAND (lvalue, 0);
11680       else
11681         {
11682           if (flag_bounds_check)
11683             base = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (base, 0), 1), 0);
11684           else
11685             base = TREE_OPERAND (TREE_OPERAND (base, 0), 0);
11686         }
11687
11688       /* Build the invocation of _Jv_CheckArrayStore */
11689       new_rhs = save_expr (new_rhs);
11690       check = build (CALL_EXPR, void_type_node,
11691                      build_address_of (soft_checkarraystore_node),
11692                      tree_cons (NULL_TREE, base,
11693                                 build_tree_list (NULL_TREE, new_rhs)),
11694                      NULL_TREE);
11695       TREE_SIDE_EFFECTS (check) = 1;
11696
11697       /* We have to decide on an insertion point */
11698       if (TREE_CODE (lvalue) == COMPOUND_EXPR)
11699         {
11700           tree t;
11701           if (flag_bounds_check)
11702             {
11703               t = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (lvalue, 1), 0), 0);
11704               TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (lvalue, 1), 0), 0) =
11705                 build (COMPOUND_EXPR, void_type_node, t, check);
11706             }
11707           else
11708             TREE_OPERAND (lvalue, 1) = build (COMPOUND_EXPR, lhs_type,
11709                                               check, TREE_OPERAND (lvalue, 1));
11710         }
11711       else 
11712         {
11713           /* Make sure the bound check will happen before the store check */
11714           if (flag_bounds_check)
11715             TREE_OPERAND (TREE_OPERAND (lvalue, 0), 0) =
11716               build (COMPOUND_EXPR, void_type_node,
11717                      TREE_OPERAND (TREE_OPERAND (lvalue, 0), 0), check);
11718           else
11719             lvalue = build (COMPOUND_EXPR, lhs_type, check, lvalue);
11720         }
11721     }
11722
11723   TREE_OPERAND (node, 0) = lvalue;
11724   TREE_OPERAND (node, 1) = new_rhs;
11725   TREE_TYPE (node) = lhs_type;
11726   return node;
11727 }
11728
11729 /* Check that type SOURCE can be cast into type DEST. If the cast
11730    can't occur at all, return 0 otherwise 1. This function is used to
11731    produce accurate error messages on the reasons why an assignment
11732    failed. */
11733
11734 static tree
11735 try_reference_assignconv (lhs_type, rhs)
11736      tree lhs_type, rhs;
11737 {
11738   tree new_rhs = NULL_TREE;
11739   tree rhs_type = TREE_TYPE (rhs);
11740
11741   if (!JPRIMITIVE_TYPE_P (rhs_type) && JREFERENCE_TYPE_P (lhs_type))
11742     {
11743       /* `null' may be assigned to any reference type */
11744       if (rhs == null_pointer_node)
11745         new_rhs = null_pointer_node;
11746       /* Try the reference assignment conversion */
11747       else if (valid_ref_assignconv_cast_p (rhs_type, lhs_type, 0))
11748         new_rhs = rhs;
11749       /* This is a magic assignment that we process differently */
11750       else if (rhs == soft_exceptioninfo_call_node)
11751         new_rhs = rhs;
11752     }
11753   return new_rhs;
11754 }
11755
11756 /* Check that RHS can be converted into LHS_TYPE by the assignment
11757    conversion (5.2), for the cases of RHS being a builtin type. Return
11758    NULL_TREE if the conversion fails or if because RHS isn't of a
11759    builtin type. Return a converted RHS if the conversion is possible.  */
11760
11761 static tree
11762 try_builtin_assignconv (wfl_op1, lhs_type, rhs)
11763      tree wfl_op1, lhs_type, rhs;
11764 {
11765   tree new_rhs = NULL_TREE;
11766   tree rhs_type = TREE_TYPE (rhs);
11767
11768   /* Zero accepted everywhere */
11769   if (TREE_CODE (rhs) == INTEGER_CST 
11770       && TREE_INT_CST_HIGH (rhs) == 0 && TREE_INT_CST_LOW (rhs) == 0
11771       && JPRIMITIVE_TYPE_P (rhs_type))
11772     new_rhs = convert (lhs_type, rhs);
11773
11774   /* 5.1.1 Try Identity Conversion,
11775      5.1.2 Try Widening Primitive Conversion */
11776   else if (valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type))
11777     new_rhs = convert (lhs_type, rhs);
11778
11779   /* Try a narrowing primitive conversion (5.1.3): 
11780        - expression is a constant expression of type int AND
11781        - variable is byte, short or char AND
11782        - The value of the expression is representable in the type of the 
11783          variable */
11784   else if (rhs_type == int_type_node && TREE_CONSTANT (rhs)
11785            && (lhs_type == byte_type_node || lhs_type == char_type_node
11786                || lhs_type == short_type_node))
11787     {
11788       if (int_fits_type_p (rhs, lhs_type))
11789         new_rhs = convert (lhs_type, rhs);
11790       else if (wfl_op1)         /* Might be called with a NULL */
11791         parse_warning_context 
11792           (wfl_op1, "Constant expression `%s' to wide for narrowing primitive conversion to `%s'", 
11793            print_int_node (rhs), lang_printable_name (lhs_type, 0));
11794       /* Reported a warning that will turn into an error further
11795          down, so we don't return */
11796     }
11797
11798   return new_rhs;
11799 }
11800
11801 /* Return 1 if RHS_TYPE can be converted to LHS_TYPE by identity
11802    conversion (5.1.1) or widening primitve conversion (5.1.2).  Return
11803    0 is the conversion test fails.  This implements parts the method
11804    invocation convertion (5.3).  */
11805
11806 static int
11807 valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type)
11808      tree lhs_type, rhs_type;
11809 {
11810   /* 5.1.1: This is the identity conversion part. */
11811   if (lhs_type == rhs_type)
11812     return 1;
11813
11814   /* Reject non primitive types */
11815   if (!JPRIMITIVE_TYPE_P (lhs_type) || !JPRIMITIVE_TYPE_P (rhs_type))
11816     return 0;
11817
11818   /* 5.1.2: widening primitive conversion. byte, even if it's smaller
11819      than a char can't be converted into a char. Short can't too, but
11820      the < test below takes care of that */
11821   if (lhs_type == char_type_node && rhs_type == byte_type_node)
11822     return 0;
11823
11824   /* Accept all promoted type here. Note, we can't use <= in the test
11825      below, because we still need to bounce out assignments of short
11826      to char and the likes */
11827   if (lhs_type == int_type_node
11828       && (rhs_type == promoted_byte_type_node
11829           || rhs_type == promoted_short_type_node
11830           || rhs_type == promoted_char_type_node
11831           || rhs_type == promoted_boolean_type_node))
11832     return 1;
11833
11834   /* From here, an integral is widened if its precision is smaller
11835      than the precision of the LHS or if the LHS is a floating point
11836      type, or the RHS is a float and the RHS a double. */
11837   if ((JINTEGRAL_TYPE_P (rhs_type) && JINTEGRAL_TYPE_P (lhs_type) 
11838        && (TYPE_PRECISION (rhs_type) < TYPE_PRECISION (lhs_type)))
11839       || (JINTEGRAL_TYPE_P (rhs_type) && JFLOAT_TYPE_P (lhs_type))
11840       || (rhs_type == float_type_node && lhs_type == double_type_node))
11841     return 1;
11842
11843   return 0;
11844 }
11845
11846 /* Check that something of SOURCE type can be assigned or cast to
11847    something of DEST type at runtime. Return 1 if the operation is
11848    valid, 0 otherwise. If CAST is set to 1, we're treating the case
11849    were SOURCE is cast into DEST, which borrows a lot of the
11850    assignment check. */
11851
11852 static int
11853 valid_ref_assignconv_cast_p (source, dest, cast)
11854      tree source;
11855      tree dest;
11856      int cast;
11857 {
11858   /* SOURCE or DEST might be null if not from a declared entity. */
11859   if (!source || !dest)
11860     return 0;
11861   if (JNULLP_TYPE_P (source))
11862     return 1;
11863   if (TREE_CODE (source) == POINTER_TYPE)
11864     source = TREE_TYPE (source);
11865   if (TREE_CODE (dest) == POINTER_TYPE)
11866     dest = TREE_TYPE (dest);
11867   /* Case where SOURCE is a class type */
11868   if (TYPE_CLASS_P (source))
11869     {
11870       if (TYPE_CLASS_P (dest))
11871         return  (source == dest 
11872                  || inherits_from_p (source, dest)
11873                  || enclosing_context_p (dest, source /*source, dest*/)
11874                  || (cast && inherits_from_p (dest, source)));
11875       if (TYPE_INTERFACE_P (dest))
11876         {
11877           /* If doing a cast and SOURCE is final, the operation is
11878              always correct a compile time (because even if SOURCE
11879              does not implement DEST, a subclass of SOURCE might). */
11880           if (cast && !CLASS_FINAL (TYPE_NAME (source)))
11881             return 1;
11882           /* Otherwise, SOURCE must implement DEST */
11883           return interface_of_p (dest, source);
11884         }
11885       /* DEST is an array, cast permited if SOURCE is of Object type */
11886       return (cast && source == object_type_node ? 1 : 0);
11887     }
11888   if (TYPE_INTERFACE_P (source))
11889     {
11890       if (TYPE_CLASS_P (dest))
11891         {
11892           /* If not casting, DEST must be the Object type */
11893           if (!cast)
11894             return dest == object_type_node;
11895           /* We're doing a cast. The cast is always valid is class
11896              DEST is not final, otherwise, DEST must implement SOURCE */
11897           else if (!CLASS_FINAL (TYPE_NAME (dest)))
11898             return 1;
11899           else
11900             return interface_of_p (source, dest);
11901         }
11902       if (TYPE_INTERFACE_P (dest))
11903         {
11904           /* If doing a cast, then if SOURCE and DEST contain method
11905              with the same signature but different return type, then
11906              this is a (compile time) error */
11907           if (cast)
11908             {
11909               tree method_source, method_dest;
11910               tree source_type;
11911               tree source_sig;
11912               tree source_name;
11913               for (method_source = TYPE_METHODS (source); method_source; 
11914                    method_source = TREE_CHAIN (method_source))
11915                 {
11916                   source_sig = 
11917                     build_java_argument_signature (TREE_TYPE (method_source));
11918                   source_type = TREE_TYPE (TREE_TYPE (method_source));
11919                   source_name = DECL_NAME (method_source);
11920                   for (method_dest = TYPE_METHODS (dest);
11921                        method_dest; method_dest = TREE_CHAIN (method_dest))
11922                     if (source_sig == 
11923                         build_java_argument_signature (TREE_TYPE (method_dest))
11924                         && source_name == DECL_NAME (method_dest)
11925                         && source_type != TREE_TYPE (TREE_TYPE (method_dest)))
11926                       return 0;
11927                 }
11928               return 1;
11929             }
11930           else
11931             return source == dest || interface_of_p (dest, source);
11932         }
11933       else                      /* Array */
11934         return (cast ? 
11935                 (DECL_NAME (TYPE_NAME (source)) == java_lang_cloneable) : 0);
11936     }
11937   if (TYPE_ARRAY_P (source))
11938     {
11939       if (TYPE_CLASS_P (dest))
11940         return dest == object_type_node;
11941       /* Can't cast an array to an interface unless the interface is
11942          java.lang.Cloneable */
11943       if (TYPE_INTERFACE_P (dest))
11944         return (DECL_NAME (TYPE_NAME (dest)) == java_lang_cloneable ? 1 : 0);
11945       else                      /* Arrays */
11946         {
11947           tree source_element_type = TYPE_ARRAY_ELEMENT (source);
11948           tree dest_element_type = TYPE_ARRAY_ELEMENT (dest);
11949           
11950           /* In case of severe errors, they turn out null */
11951           if (!dest_element_type || !source_element_type)
11952             return 0;
11953           if (source_element_type == dest_element_type)
11954             return 1;
11955           return valid_ref_assignconv_cast_p (source_element_type,
11956                                               dest_element_type, cast);
11957         }
11958       return 0;
11959     }
11960   return 0;
11961 }
11962
11963 static int
11964 valid_cast_to_p (source, dest)
11965      tree source;
11966      tree dest;
11967 {
11968   if (TREE_CODE (source) == POINTER_TYPE)
11969     source = TREE_TYPE (source);
11970   if (TREE_CODE (dest) == POINTER_TYPE)
11971     dest = TREE_TYPE (dest);
11972
11973   if (TREE_CODE (source) == RECORD_TYPE && TREE_CODE (dest) == RECORD_TYPE)
11974     return valid_ref_assignconv_cast_p (source, dest, 1);
11975
11976   else if (JNUMERIC_TYPE_P (source) && JNUMERIC_TYPE_P (dest))
11977     return 1;
11978
11979   return 0;
11980 }
11981
11982 /* Method invocation conversion test. Return 1 if type SOURCE can be
11983    converted to type DEST through the methond invocation conversion
11984    process (5.3) */
11985
11986 static tree
11987 do_unary_numeric_promotion (arg)
11988      tree arg;
11989 {
11990   tree type = TREE_TYPE (arg);
11991   if (TREE_CODE (type) == INTEGER_TYPE ? TYPE_PRECISION (type) < 32
11992       : TREE_CODE (type) == CHAR_TYPE)
11993     arg = convert (int_type_node, arg);
11994   return arg;
11995 }
11996
11997 /* Return a non zero value if SOURCE can be converted into DEST using
11998    the method invocation conversion rule (5.3).  */
11999 static int
12000 valid_method_invocation_conversion_p (dest, source)
12001      tree dest, source;
12002 {
12003   return ((JPRIMITIVE_TYPE_P (source) && JPRIMITIVE_TYPE_P (dest)
12004            && valid_builtin_assignconv_identity_widening_p (dest, source))
12005           || ((JREFERENCE_TYPE_P (source) || JNULLP_TYPE_P (source))
12006               && (JREFERENCE_TYPE_P (dest) || JNULLP_TYPE_P (dest))
12007               && valid_ref_assignconv_cast_p (source, dest, 0)));
12008 }
12009
12010 /* Build an incomplete binop expression. */
12011
12012 static tree
12013 build_binop (op, op_location, op1, op2)
12014      enum tree_code op;
12015      int op_location;
12016      tree op1, op2;
12017 {
12018   tree binop = build (op, NULL_TREE, op1, op2);
12019   TREE_SIDE_EFFECTS (binop) = 1;
12020   /* Store the location of the operator, for better error report. The
12021      string of the operator will be rebuild based on the OP value. */
12022   EXPR_WFL_LINECOL (binop) = op_location;
12023   return binop;
12024 }
12025
12026 /* Build the string of the operator retained by NODE. If NODE is part
12027    of a compound expression, add an '=' at the end of the string. This
12028    function is called when an error needs to be reported on an
12029    operator. The string is returned as a pointer to a static character
12030    buffer. */
12031
12032 static char *
12033 operator_string (node)
12034      tree node;
12035 {
12036 #define BUILD_OPERATOR_STRING(S)                                        \
12037   {                                                                     \
12038     sprintf (buffer, "%s%s", S, (COMPOUND_ASSIGN_P (node) ? "=" : "")); \
12039     return buffer;                                                      \
12040   }
12041   
12042   static char buffer [10];
12043   switch (TREE_CODE (node))
12044     {
12045     case MULT_EXPR: BUILD_OPERATOR_STRING ("*");
12046     case RDIV_EXPR: BUILD_OPERATOR_STRING ("/");
12047     case TRUNC_MOD_EXPR: BUILD_OPERATOR_STRING ("%");
12048     case PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
12049     case MINUS_EXPR: BUILD_OPERATOR_STRING ("-");
12050     case LSHIFT_EXPR: BUILD_OPERATOR_STRING ("<<");
12051     case RSHIFT_EXPR: BUILD_OPERATOR_STRING (">>");
12052     case URSHIFT_EXPR: BUILD_OPERATOR_STRING (">>>");
12053     case BIT_AND_EXPR: BUILD_OPERATOR_STRING ("&");
12054     case BIT_XOR_EXPR: BUILD_OPERATOR_STRING ("^");
12055     case BIT_IOR_EXPR: BUILD_OPERATOR_STRING ("|");
12056     case TRUTH_ANDIF_EXPR: BUILD_OPERATOR_STRING ("&&");
12057     case TRUTH_ORIF_EXPR: BUILD_OPERATOR_STRING ("||");
12058     case EQ_EXPR: BUILD_OPERATOR_STRING ("==");
12059     case NE_EXPR: BUILD_OPERATOR_STRING ("!=");
12060     case GT_EXPR: BUILD_OPERATOR_STRING (">");
12061     case GE_EXPR: BUILD_OPERATOR_STRING (">=");
12062     case LT_EXPR: BUILD_OPERATOR_STRING ("<");
12063     case LE_EXPR: BUILD_OPERATOR_STRING ("<=");
12064     case UNARY_PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
12065     case NEGATE_EXPR: BUILD_OPERATOR_STRING ("-");
12066     case TRUTH_NOT_EXPR: BUILD_OPERATOR_STRING ("!");
12067     case BIT_NOT_EXPR: BUILD_OPERATOR_STRING ("~");
12068     case PREINCREMENT_EXPR:     /* Fall through */
12069     case POSTINCREMENT_EXPR: BUILD_OPERATOR_STRING ("++");
12070     case PREDECREMENT_EXPR:     /* Fall through */
12071     case POSTDECREMENT_EXPR: BUILD_OPERATOR_STRING ("--");
12072     default:
12073       fatal ("unregistered operator %s - operator_string",
12074              tree_code_name [TREE_CODE (node)]);
12075     }
12076   return NULL;
12077 #undef BUILD_OPERATOR_STRING
12078 }
12079
12080 /* Return 1 if VAR_ACCESS1 is equivalent to VAR_ACCESS2.  */
12081
12082 static int
12083 java_decl_equiv (var_acc1, var_acc2)
12084      tree var_acc1, var_acc2;
12085 {
12086   if (JDECL_P (var_acc1))
12087     return (var_acc1 == var_acc2);
12088   
12089   return (TREE_CODE (var_acc1) == COMPONENT_REF
12090           && TREE_CODE (var_acc2) == COMPONENT_REF
12091           && TREE_OPERAND (TREE_OPERAND (var_acc1, 0), 0)
12092              == TREE_OPERAND (TREE_OPERAND (var_acc2, 0), 0)
12093           && TREE_OPERAND (var_acc1, 1) == TREE_OPERAND (var_acc2, 1));
12094 }
12095
12096 /* Return a non zero value if CODE is one of the operators that can be
12097    used in conjunction with the `=' operator in a compound assignment.  */
12098
12099 static int
12100 binop_compound_p (code)
12101     enum tree_code code;
12102 {
12103   int i;
12104   for (i = 0; i < BINOP_COMPOUND_CANDIDATES; i++)
12105     if (binop_lookup [i] == code)
12106       break;
12107
12108   return i < BINOP_COMPOUND_CANDIDATES;
12109 }
12110
12111 /* Reorganize after a fold to get SAVE_EXPR to generate what we want.  */
12112
12113 static tree
12114 java_refold (t)
12115      tree t;
12116 {
12117   tree c, b, ns, decl;
12118
12119   if (TREE_CODE (t) != MODIFY_EXPR)
12120     return t;
12121
12122   c = TREE_OPERAND (t, 1);
12123   if (! (c && TREE_CODE (c) == COMPOUND_EXPR
12124          && TREE_CODE (TREE_OPERAND (c, 0)) == MODIFY_EXPR
12125          && binop_compound_p (TREE_CODE (TREE_OPERAND (c, 1)))))
12126     return t;
12127
12128   /* Now the left branch of the binary operator. */
12129   b = TREE_OPERAND (TREE_OPERAND (c, 1), 0);
12130   if (! (b && TREE_CODE (b) == NOP_EXPR 
12131          && TREE_CODE (TREE_OPERAND (b, 0)) == SAVE_EXPR))
12132     return t;
12133
12134   ns = TREE_OPERAND (TREE_OPERAND (b, 0), 0);
12135   if (! (ns && TREE_CODE (ns) == NOP_EXPR
12136          && TREE_CODE (TREE_OPERAND (ns, 0)) == SAVE_EXPR))
12137     return t;
12138
12139   decl = TREE_OPERAND (TREE_OPERAND (ns, 0), 0);
12140   if ((JDECL_P (decl) || TREE_CODE (decl) == COMPONENT_REF)
12141       /* It's got to be the an equivalent decl */
12142       && java_decl_equiv (decl, TREE_OPERAND (TREE_OPERAND (c, 0), 0)))
12143     {
12144       /* Shorten the NOP_EXPR/SAVE_EXPR path. */
12145       TREE_OPERAND (TREE_OPERAND (c, 1), 0) = TREE_OPERAND (ns, 0);
12146       /* Substitute the COMPOUND_EXPR by the BINOP_EXPR */
12147       TREE_OPERAND (t, 1) = TREE_OPERAND (c, 1);
12148       /* Change the right part of the BINOP_EXPR */
12149       TREE_OPERAND (TREE_OPERAND (t, 1), 1) = TREE_OPERAND (c, 0);
12150     }
12151
12152   return t;
12153 }
12154
12155 /* Binary operators (15.16 up to 15.18). We return error_mark_node on
12156    errors but we modify NODE so that it contains the type computed
12157    according to the expression, when it's fixed. Otherwise, we write
12158    error_mark_node as the type. It allows us to further the analysis
12159    of remaining nodes and detects more errors in certain cases.  */
12160
12161 static tree
12162 patch_binop (node, wfl_op1, wfl_op2)
12163      tree node;
12164      tree wfl_op1;
12165      tree wfl_op2;
12166 {
12167   tree op1 = TREE_OPERAND (node, 0);
12168   tree op2 = TREE_OPERAND (node, 1);
12169   tree op1_type = TREE_TYPE (op1);
12170   tree op2_type = TREE_TYPE (op2);
12171   tree prom_type = NULL_TREE, cn;
12172   int code = TREE_CODE (node);
12173
12174   /* If 1, tell the routine that we have to return error_mark_node
12175      after checking for the initialization of the RHS */
12176   int error_found = 0;
12177
12178   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
12179
12180   switch (code)
12181     {
12182     /* 15.16 Multiplicative operators */
12183     case MULT_EXPR:             /* 15.16.1 Multiplication Operator * */
12184     case RDIV_EXPR:             /* 15.16.2 Division Operator / */
12185     case TRUNC_DIV_EXPR:        /* 15.16.2 Integral type Division Operator / */
12186     case TRUNC_MOD_EXPR:        /* 15.16.3 Remainder operator % */
12187       if (!JPRIMITIVE_TYPE_P (op1_type) || !JPRIMITIVE_TYPE_P (op2_type))
12188         {
12189           if (!JPRIMITIVE_TYPE_P (op1_type))
12190             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
12191           if (!JPRIMITIVE_TYPE_P (op2_type) && (op1_type != op2_type))
12192             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
12193           TREE_TYPE (node) = error_mark_node;
12194           error_found = 1;
12195           break;
12196         }
12197       prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12198       /* Change the division operator if necessary */
12199       if (code == RDIV_EXPR && TREE_CODE (prom_type) == INTEGER_TYPE)
12200         TREE_SET_CODE (node, TRUNC_DIV_EXPR);
12201
12202       if (TREE_CODE (prom_type) == INTEGER_TYPE
12203           && flag_use_divide_subroutine
12204           && ! flag_emit_class_files
12205           && (code == RDIV_EXPR || code == TRUNC_MOD_EXPR))
12206         return build_java_soft_divmod (TREE_CODE (node), prom_type, op1, op2);
12207  
12208       /* This one is more complicated. FLOATs are processed by a
12209          function call to soft_fmod. Duplicate the value of the
12210          COMPOUND_ASSIGN_P flag. */
12211       if (code == TRUNC_MOD_EXPR)
12212         {
12213           tree mod = build_java_binop (TRUNC_MOD_EXPR, prom_type, op1, op2);
12214           COMPOUND_ASSIGN_P (mod) = COMPOUND_ASSIGN_P (node);
12215           TREE_SIDE_EFFECTS (mod)
12216             = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
12217           return mod;
12218         }
12219       break;
12220
12221     /* 15.17 Additive Operators */
12222     case PLUS_EXPR:             /* 15.17.1 String Concatenation Operator + */
12223
12224       /* Operation is valid if either one argument is a string
12225          constant, a String object or a StringBuffer crafted for the
12226          purpose of the a previous usage of the String concatenation
12227          operator */
12228
12229       if (TREE_CODE (op1) == STRING_CST 
12230           || TREE_CODE (op2) == STRING_CST
12231           || JSTRING_TYPE_P (op1_type)
12232           || JSTRING_TYPE_P (op2_type)
12233           || IS_CRAFTED_STRING_BUFFER_P (op1)
12234           || IS_CRAFTED_STRING_BUFFER_P (op2))
12235         return build_string_concatenation (op1, op2);
12236
12237     case MINUS_EXPR:            /* 15.17.2 Additive Operators (+ and -) for
12238                                    Numeric Types */
12239       if (!JPRIMITIVE_TYPE_P (op1_type) || !JPRIMITIVE_TYPE_P (op2_type))
12240         {
12241           if (!JPRIMITIVE_TYPE_P (op1_type))
12242             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
12243           if (!JPRIMITIVE_TYPE_P (op2_type) && (op1_type != op2_type))
12244             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
12245           TREE_TYPE (node) = error_mark_node;
12246           error_found = 1;
12247           break;
12248         }
12249       prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12250       break;
12251
12252     /* 15.18 Shift Operators */
12253     case LSHIFT_EXPR:
12254     case RSHIFT_EXPR:
12255     case URSHIFT_EXPR:
12256       if (!JINTEGRAL_TYPE_P (op1_type) || !JINTEGRAL_TYPE_P (op2_type))
12257         {
12258           if (!JINTEGRAL_TYPE_P (op1_type))
12259             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
12260           else
12261             {
12262               if (JPRIMITIVE_TYPE_P (op2_type))
12263                 parse_error_context (wfl_operator,
12264                                      "Incompatible type for `%s'. Explicit cast needed to convert shift distance from `%s' to integral",
12265                                      operator_string (node),
12266                                      lang_printable_name (op2_type, 0));
12267               else
12268                 parse_error_context (wfl_operator,
12269                                      "Incompatible type for `%s'. Can't convert shift distance from `%s' to integral", 
12270                                      operator_string (node),
12271                                      lang_printable_name (op2_type, 0));
12272             }
12273           TREE_TYPE (node) = error_mark_node;
12274           error_found = 1;
12275           break;
12276         }
12277
12278       /* Unary numeric promotion (5.6.1) is performed on each operand
12279          separatly */
12280       op1 = do_unary_numeric_promotion (op1);
12281       op2 = do_unary_numeric_promotion (op2);
12282
12283       /* The type of the shift expression is the type of the promoted
12284          type of the left-hand operand */
12285       prom_type = TREE_TYPE (op1);
12286
12287       /* Shift int only up to 0x1f and long up to 0x3f */
12288       if (prom_type == int_type_node)
12289         op2 = fold (build (BIT_AND_EXPR, int_type_node, op2, 
12290                            build_int_2 (0x1f, 0)));
12291       else
12292         op2 = fold (build (BIT_AND_EXPR, int_type_node, op2, 
12293                            build_int_2 (0x3f, 0)));
12294
12295       /* The >>> operator is a >> operating on unsigned quantities */
12296       if (code == URSHIFT_EXPR && ! flag_emit_class_files)
12297         {
12298           tree to_return;
12299           tree utype = unsigned_type (prom_type);
12300           op1 = convert (utype, op1);
12301           TREE_SET_CODE (node, RSHIFT_EXPR);
12302           TREE_OPERAND (node, 0) = op1;
12303           TREE_OPERAND (node, 1) = op2;
12304           TREE_TYPE (node) = utype;
12305           to_return = convert (prom_type, node);
12306           /* Copy the original value of the COMPOUND_ASSIGN_P flag */
12307           COMPOUND_ASSIGN_P (to_return) = COMPOUND_ASSIGN_P (node);
12308           TREE_SIDE_EFFECTS (to_return)
12309             = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
12310           return to_return;
12311         }
12312       break;
12313
12314       /* 15.19.1 Type Comparison Operator instaceof */
12315     case INSTANCEOF_EXPR:
12316
12317       TREE_TYPE (node) = boolean_type_node;
12318
12319       if (!(op2_type = resolve_type_during_patch (op2)))
12320         return error_mark_node;
12321
12322       /* The first operand must be a reference type or the null type */
12323       if (!JREFERENCE_TYPE_P (op1_type) && op1 != null_pointer_node)
12324         error_found = 1;        /* Error reported further below */
12325
12326       /* The second operand must be a reference type */
12327       if (!JREFERENCE_TYPE_P (op2_type))
12328         {
12329           SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
12330           parse_error_context
12331             (wfl_operator, "Invalid argument `%s' for `instanceof'",
12332              lang_printable_name (op2_type, 0));
12333           error_found = 1;
12334         }
12335
12336       if (!error_found && valid_ref_assignconv_cast_p (op1_type, op2_type, 1))
12337         {
12338           /* If the first operand is null, the result is always false */
12339           if (op1 == null_pointer_node)
12340             return boolean_false_node;
12341           else if (flag_emit_class_files)
12342             {
12343               TREE_OPERAND (node, 1) = op2_type;
12344               TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1);
12345               return node;
12346             }
12347           /* Otherwise we have to invoke instance of to figure it out */
12348           else
12349             return build_instanceof (op1, op2_type);
12350         }
12351       /* There is no way the expression operand can be an instance of
12352          the type operand. This is a compile time error. */
12353       else
12354         {
12355           char *t1 = xstrdup (lang_printable_name (op1_type, 0));
12356           SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
12357           parse_error_context 
12358             (wfl_operator, "Impossible for `%s' to be instance of `%s'",
12359              t1, lang_printable_name (op2_type, 0));
12360           free (t1);
12361           error_found = 1;
12362         }
12363       
12364       break;
12365
12366       /* 15.21 Bitwise and Logical Operators */
12367     case BIT_AND_EXPR:
12368     case BIT_XOR_EXPR:
12369     case BIT_IOR_EXPR:
12370       if (JINTEGRAL_TYPE_P (op1_type) && JINTEGRAL_TYPE_P (op2_type))
12371         /* Binary numeric promotion is performed on both operand and the
12372            expression retain that type */
12373         prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12374
12375       else if (TREE_CODE (op1_type) == BOOLEAN_TYPE 
12376                && TREE_CODE (op1_type) == BOOLEAN_TYPE)
12377         /* The type of the bitwise operator expression is BOOLEAN */
12378         prom_type = boolean_type_node;
12379       else
12380         {
12381           if (!JINTEGRAL_TYPE_P (op1_type))
12382             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
12383           if (!JINTEGRAL_TYPE_P (op2_type) && (op1_type != op2_type))
12384             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op2_type);
12385           TREE_TYPE (node) = error_mark_node;
12386           error_found = 1;
12387           /* Insert a break here if adding thing before the switch's
12388              break for this case */
12389         }
12390       break;
12391
12392       /* 15.22 Conditional-And Operator */
12393     case TRUTH_ANDIF_EXPR:
12394       /* 15.23 Conditional-Or Operator */
12395     case TRUTH_ORIF_EXPR:
12396       /* Operands must be of BOOLEAN type */
12397       if (TREE_CODE (op1_type) != BOOLEAN_TYPE || 
12398           TREE_CODE (op2_type) != BOOLEAN_TYPE)
12399         {
12400           if (TREE_CODE (op1_type) != BOOLEAN_TYPE)
12401             ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op1_type);
12402           if (TREE_CODE (op2_type) != BOOLEAN_TYPE && (op1_type != op2_type))
12403             ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op2_type);
12404           TREE_TYPE (node) = boolean_type_node;
12405           error_found = 1;
12406           break;
12407         }
12408       /* The type of the conditional operators is BOOLEAN */
12409       prom_type = boolean_type_node;
12410       break;
12411
12412       /* 15.19.1 Numerical Comparison Operators <, <=, >, >= */
12413     case LT_EXPR:
12414     case GT_EXPR:
12415     case LE_EXPR:
12416     case GE_EXPR:
12417       /* The type of each of the operands must be a primitive numeric
12418          type */
12419       if (!JNUMERIC_TYPE_P (op1_type) || ! JNUMERIC_TYPE_P (op2_type))
12420         {
12421           if (!JNUMERIC_TYPE_P (op1_type))
12422             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
12423           if (!JNUMERIC_TYPE_P (op2_type) && (op1_type != op2_type))
12424             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
12425           TREE_TYPE (node) = boolean_type_node;
12426           error_found = 1;
12427           break;
12428         }
12429       /* Binary numeric promotion is performed on the operands */
12430       binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12431       /* The type of the relation expression is always BOOLEAN */
12432       prom_type = boolean_type_node;
12433       break;
12434
12435       /* 15.20 Equality Operator */
12436     case EQ_EXPR:
12437     case NE_EXPR:
12438       /* It's time for us to patch the strings. */
12439       if ((cn = patch_string (op1))) 
12440        {
12441          op1 = cn;
12442          op1_type = TREE_TYPE (op1);
12443        }
12444       if ((cn = patch_string (op2))) 
12445        {
12446          op2 = cn;
12447          op2_type = TREE_TYPE (op2);
12448        }
12449       
12450       /* 15.20.1 Numerical Equality Operators == and != */
12451       /* Binary numeric promotion is performed on the operands */
12452       if (JNUMERIC_TYPE_P (op1_type) && JNUMERIC_TYPE_P (op2_type))
12453         binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12454       
12455       /* 15.20.2 Boolean Equality Operators == and != */
12456       else if (TREE_CODE (op1_type) == BOOLEAN_TYPE &&
12457           TREE_CODE (op2_type) == BOOLEAN_TYPE)
12458         ;                       /* Nothing to do here */
12459       
12460       /* 15.20.3 Reference Equality Operators == and != */
12461       /* Types have to be either references or the null type. If
12462          they're references, it must be possible to convert either
12463          type to the other by casting conversion. */
12464       else if (op1 == null_pointer_node || op2 == null_pointer_node 
12465                || (JREFERENCE_TYPE_P (op1_type) && JREFERENCE_TYPE_P (op2_type)
12466                    && (valid_ref_assignconv_cast_p (op1_type, op2_type, 1)
12467                        || valid_ref_assignconv_cast_p (op2_type, 
12468                                                        op1_type, 1))))
12469         ;                       /* Nothing to do here */
12470           
12471       /* Else we have an error figure what can't be converted into
12472          what and report the error */
12473       else
12474         {
12475           char *t1;
12476           t1 = xstrdup (lang_printable_name (op1_type, 0));
12477           parse_error_context 
12478             (wfl_operator,
12479              "Incompatible type for `%s'. Can't convert `%s' to `%s'",
12480              operator_string (node), t1, 
12481              lang_printable_name (op2_type, 0));
12482           free (t1);
12483           TREE_TYPE (node) = boolean_type_node;
12484           error_found = 1;
12485           break;
12486         }
12487       prom_type = boolean_type_node;
12488       break;
12489     }
12490
12491   if (error_found)
12492     return error_mark_node;
12493
12494   TREE_OPERAND (node, 0) = op1;
12495   TREE_OPERAND (node, 1) = op2;
12496   TREE_TYPE (node) = prom_type;
12497   TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
12498   
12499   if (flag_emit_xref)
12500     return node;
12501
12502   /* fold does not respect side-effect order as required for Java but not C.
12503    * Also, it sometimes create SAVE_EXPRs which are bad when emitting
12504    * bytecode.
12505    */
12506   if (flag_emit_class_files ? (TREE_CONSTANT (op1) && TREE_CONSTANT (op2))
12507       : ! TREE_SIDE_EFFECTS (node))
12508     node = fold (node);
12509   return node;
12510 }
12511
12512 /* Concatenate the STRING_CST CSTE and STRING. When AFTER is a non
12513    zero value, the value of CSTE comes after the valude of STRING */
12514
12515 static tree
12516 do_merge_string_cste (cste, string, string_len, after)
12517      tree cste;
12518      const char *string;
12519      int string_len, after;
12520 {
12521   int len = TREE_STRING_LENGTH (cste) + string_len;
12522   const char *old = TREE_STRING_POINTER (cste);
12523   TREE_STRING_LENGTH (cste) = len;
12524   TREE_STRING_POINTER (cste) = obstack_alloc (expression_obstack, len+1);
12525   if (after)
12526     {
12527       strcpy (TREE_STRING_POINTER (cste), string);
12528       strcat (TREE_STRING_POINTER (cste), old);
12529     }
12530   else
12531     {
12532       strcpy (TREE_STRING_POINTER (cste), old);
12533       strcat (TREE_STRING_POINTER (cste), string);
12534     }
12535   return cste;
12536 }
12537
12538 /* Tries to merge OP1 (a STRING_CST) and OP2 (if suitable). Return a
12539    new STRING_CST on success, NULL_TREE on failure */
12540
12541 static tree
12542 merge_string_cste (op1, op2, after)
12543      tree op1, op2;
12544      int after;
12545 {
12546   /* Handle two string constants right away */
12547   if (TREE_CODE (op2) == STRING_CST)
12548     return do_merge_string_cste (op1, TREE_STRING_POINTER (op2), 
12549                                  TREE_STRING_LENGTH (op2), after);
12550   
12551   /* Reasonable integer constant can be treated right away */
12552   if (TREE_CODE (op2) == INTEGER_CST && !TREE_CONSTANT_OVERFLOW (op2))
12553     {
12554       static const char *boolean_true = "true";
12555       static const char *boolean_false = "false";
12556       static const char *null_pointer = "null";
12557       char ch[3];
12558       const char *string;
12559       
12560       if (op2 == boolean_true_node)
12561         string = boolean_true;
12562       else if (op2 == boolean_false_node)
12563         string = boolean_false;
12564       else if (op2 == null_pointer_node)
12565         string = null_pointer;
12566       else if (TREE_TYPE (op2) == char_type_node)
12567         {
12568           ch[0] = (char )TREE_INT_CST_LOW (op2);
12569           ch[1] = '\0';
12570           string = ch;
12571         }
12572       else
12573           string = print_int_node (op2);
12574       
12575       return do_merge_string_cste (op1, string, strlen (string), after);
12576     }
12577   return NULL_TREE;
12578 }
12579
12580 /* Tries to statically concatenate OP1 and OP2 if possible. Either one
12581    has to be a STRING_CST and the other part must be a STRING_CST or a
12582    INTEGRAL constant. Return a new STRING_CST if the operation
12583    succeed, NULL_TREE otherwise.
12584
12585    If the case we want to optimize for space, we might want to return
12586    NULL_TREE for each invocation of this routine. FIXME */
12587
12588 static tree
12589 string_constant_concatenation (op1, op2)
12590      tree op1, op2;
12591 {
12592   if (TREE_CODE (op1) == STRING_CST || (TREE_CODE (op2) == STRING_CST))
12593     {
12594       tree string, rest;
12595       int invert;
12596       
12597       string = (TREE_CODE (op1) == STRING_CST ? op1 : op2);
12598       rest   = (string == op1 ? op2 : op1);
12599       invert = (string == op1 ? 0 : 1 );
12600       
12601       /* Walk REST, only if it looks reasonable */
12602       if (TREE_CODE (rest) != STRING_CST
12603           && !IS_CRAFTED_STRING_BUFFER_P (rest)
12604           && !JSTRING_TYPE_P (TREE_TYPE (rest))
12605           && TREE_CODE (rest) == EXPR_WITH_FILE_LOCATION)
12606         {
12607           rest = java_complete_tree (rest);
12608           if (rest == error_mark_node)
12609             return error_mark_node;
12610           rest = fold (rest);
12611         }
12612       return merge_string_cste (string, rest, invert);
12613     }
12614   return NULL_TREE;
12615 }
12616
12617 /* Implement the `+' operator. Does static optimization if possible,
12618    otherwise create (if necessary) and append elements to a
12619    StringBuffer. The StringBuffer will be carried around until it is
12620    used for a function call or an assignment. Then toString() will be
12621    called on it to turn it into a String object. */
12622
12623 static tree
12624 build_string_concatenation (op1, op2)
12625      tree op1, op2;
12626 {
12627   tree result;
12628   int side_effects = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
12629
12630   if (flag_emit_xref)
12631     return build (PLUS_EXPR, string_type_node, op1, op2);
12632   
12633   /* Try to do some static optimization */
12634   if ((result = string_constant_concatenation (op1, op2)))
12635     return result;
12636
12637   /* Discard empty strings on either side of the expression */
12638   if (TREE_CODE (op1) == STRING_CST && TREE_STRING_LENGTH (op1) == 0)
12639     {
12640       op1 = op2;
12641       op2 = NULL_TREE;
12642     }
12643   else if (TREE_CODE (op2) == STRING_CST && TREE_STRING_LENGTH (op2) == 0)
12644     op2 = NULL_TREE;
12645
12646   /* If operands are string constant, turn then into object references */
12647   if (TREE_CODE (op1) == STRING_CST)
12648     op1 = patch_string_cst (op1);
12649   if (op2 && TREE_CODE (op2) == STRING_CST)
12650     op2 = patch_string_cst (op2);
12651
12652   /* If either one of the constant is null and the other non null
12653      operand is a String object, return it. */
12654   if (JSTRING_TYPE_P (TREE_TYPE (op1)) && !op2)
12655     return op1;
12656
12657   /* If OP1 isn't already a StringBuffer, create and
12658      initialize a new one */
12659   if (!IS_CRAFTED_STRING_BUFFER_P (op1))
12660     {
12661       /* Two solutions here: 
12662          1) OP1 is a constant string reference, we call new StringBuffer(OP1)
12663          2) OP1 is something else, we call new StringBuffer().append(OP1).  */
12664       if (TREE_CONSTANT (op1) && JSTRING_TYPE_P (TREE_TYPE (op1)))
12665         op1 = BUILD_STRING_BUFFER (op1);
12666       else
12667         {
12668           tree aNew = BUILD_STRING_BUFFER (NULL_TREE);
12669           op1 = make_qualified_primary (aNew, BUILD_APPEND (op1), 0);
12670         }
12671     }
12672
12673   if (op2)
12674     {
12675       /* OP1 is no longer the last node holding a crafted StringBuffer */
12676       IS_CRAFTED_STRING_BUFFER_P (op1) = 0;
12677       /* Create a node for `{new...,xxx}.append (op2)' */
12678       if (op2)
12679         op1 = make_qualified_primary (op1, BUILD_APPEND (op2), 0);
12680     }
12681
12682   /* Mark the last node holding a crafted StringBuffer */
12683   IS_CRAFTED_STRING_BUFFER_P (op1) = 1;
12684
12685   TREE_SIDE_EFFECTS (op1) = side_effects;
12686   return op1;
12687 }
12688
12689 /* Patch the string node NODE. NODE can be a STRING_CST of a crafted
12690    StringBuffer. If no string were found to be patched, return
12691    NULL. */
12692
12693 static tree
12694 patch_string (node)
12695     tree node;
12696 {
12697   if (node == error_mark_node)
12698     return error_mark_node;
12699   if (TREE_CODE (node) == STRING_CST)
12700     return patch_string_cst (node);
12701   else if (IS_CRAFTED_STRING_BUFFER_P (node))
12702     {
12703       int saved = ctxp->explicit_constructor_p;
12704       tree invoke = build_method_invocation (wfl_to_string, NULL_TREE);
12705       tree ret;
12706       /* Temporary disable forbid the use of `this'. */
12707       ctxp->explicit_constructor_p = 0;
12708       ret = java_complete_tree (make_qualified_primary (node, invoke, 0));
12709       /* String concatenation arguments must be evaluated in order too. */
12710       ret = force_evaluation_order (ret);
12711       /* Restore it at its previous value */
12712       ctxp->explicit_constructor_p = saved;
12713       return ret;
12714     }
12715   return NULL_TREE;
12716 }
12717
12718 /* Build the internal representation of a string constant.  */
12719
12720 static tree
12721 patch_string_cst (node)
12722      tree node;
12723 {
12724   int location;
12725   if (! flag_emit_class_files)
12726     {
12727       push_obstacks (&permanent_obstack, &permanent_obstack);
12728       node = get_identifier (TREE_STRING_POINTER (node));
12729       location = alloc_name_constant (CONSTANT_String, node);
12730       node = build_ref_from_constant_pool (location);
12731       pop_obstacks ();
12732     }
12733   TREE_TYPE (node) = string_ptr_type_node;
12734   TREE_CONSTANT (node) = 1;
12735   return node;
12736 }
12737
12738 /* Build an incomplete unary operator expression. */
12739
12740 static tree
12741 build_unaryop (op_token, op_location, op1)
12742      int op_token, op_location;
12743      tree op1;
12744 {
12745   enum tree_code op;
12746   tree unaryop;
12747   switch (op_token)
12748     {
12749     case PLUS_TK: op = UNARY_PLUS_EXPR; break;
12750     case MINUS_TK: op = NEGATE_EXPR; break;
12751     case NEG_TK: op = TRUTH_NOT_EXPR; break;
12752     case NOT_TK: op = BIT_NOT_EXPR; break;
12753     default: fatal ("Unknown token `%d' for unary operator - build_unaryop",
12754                     op_token);
12755     }
12756
12757   unaryop = build1 (op, NULL_TREE, op1);
12758   TREE_SIDE_EFFECTS (unaryop) = 1;
12759   /* Store the location of the operator, for better error report. The
12760      string of the operator will be rebuild based on the OP value. */
12761   EXPR_WFL_LINECOL (unaryop) = op_location;
12762   return unaryop;
12763 }
12764
12765 /* Special case for the ++/-- operators, since they require an extra
12766    argument to build, which is set to NULL and patched
12767    later. IS_POST_P is 1 if the operator, 0 otherwise.  */
12768
12769 static tree
12770 build_incdec (op_token, op_location, op1, is_post_p)
12771      int op_token, op_location;
12772      tree op1;
12773      int is_post_p;
12774 {
12775   static enum tree_code lookup [2][2] = 
12776     {
12777       { PREDECREMENT_EXPR, PREINCREMENT_EXPR, },
12778       { POSTDECREMENT_EXPR, POSTINCREMENT_EXPR, },
12779     };
12780   tree node = build (lookup [is_post_p][(op_token - DECR_TK)], 
12781                      NULL_TREE, op1, NULL_TREE);
12782   TREE_SIDE_EFFECTS (node) = 1;
12783   /* Store the location of the operator, for better error report. The
12784      string of the operator will be rebuild based on the OP value. */
12785   EXPR_WFL_LINECOL (node) = op_location;
12786   return node;
12787 }     
12788
12789 /* Build an incomplete cast operator, based on the use of the
12790    CONVERT_EXPR. Note that TREE_TYPE of the constructed node is
12791    set. java_complete_tree is trained to walk a CONVERT_EXPR even
12792    though its type is already set.  */
12793
12794 static tree
12795 build_cast (location, type, exp)
12796      int location;
12797      tree type, exp;
12798 {
12799   tree node = build1 (CONVERT_EXPR, type, exp);
12800   EXPR_WFL_LINECOL (node) = location;
12801   return node;
12802 }
12803
12804 /* Build an incomplete class reference operator.  */
12805 static tree
12806 build_incomplete_class_ref (location, class_name)
12807     int location;
12808     tree class_name;
12809 {
12810   tree node = build1 (CLASS_LITERAL, NULL_TREE, class_name);
12811   EXPR_WFL_LINECOL (node) = location;
12812   return node;
12813 }
12814
12815 /* Complete an incomplete class reference operator.  */
12816 static tree
12817 patch_incomplete_class_ref (node)
12818     tree node;
12819 {
12820   tree type = TREE_OPERAND (node, 0);
12821   tree ref_type;
12822
12823   if (!(ref_type = resolve_type_during_patch (type)))
12824     return error_mark_node;
12825
12826   if (!flag_emit_class_files || JPRIMITIVE_TYPE_P (ref_type))
12827     return build_class_ref (ref_type);
12828
12829   /* If we're emitting class files and we have to deal with non
12830      primitive types, we invoke (and consider generating) the
12831      synthetic static method `class$'. */
12832   if (!TYPE_DOT_CLASS (current_class))
12833       build_dot_class_method (current_class);
12834   ref_type = 
12835     build_dot_class_method_invocation (DECL_NAME (TYPE_NAME (ref_type)));
12836   return java_complete_tree (ref_type);
12837 }
12838
12839 /* 15.14 Unary operators. We return error_mark_node in case of error,
12840    but preserve the type of NODE if the type is fixed.  */
12841
12842 static tree
12843 patch_unaryop (node, wfl_op)
12844      tree node;
12845      tree wfl_op;
12846 {
12847   tree op = TREE_OPERAND (node, 0);
12848   tree op_type = TREE_TYPE (op);
12849   tree prom_type = NULL_TREE, value, decl;
12850   int outer_field_flag = 0;
12851   int code = TREE_CODE (node);
12852   int error_found = 0;
12853
12854   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
12855
12856   switch (code)
12857     {
12858       /* 15.13.2 Postfix Increment Operator ++ */
12859     case POSTINCREMENT_EXPR:
12860       /* 15.13.3 Postfix Increment Operator -- */
12861     case POSTDECREMENT_EXPR:
12862       /* 15.14.1 Prefix Increment Operator ++ */
12863     case PREINCREMENT_EXPR:
12864       /* 15.14.2 Prefix Decrement Operator -- */
12865     case PREDECREMENT_EXPR:
12866       op = decl = strip_out_static_field_access_decl (op);
12867       outer_field_flag = outer_field_expanded_access_p (op, NULL, NULL, NULL);
12868       /* We might be trying to change an outer field accessed using
12869          access method. */
12870       if (outer_field_flag)
12871         {
12872           /* Retrieve the decl of the field we're trying to access. We
12873              do that by first retrieving the function we would call to
12874              access the field. It has been already verified that this
12875              field isn't final */
12876           if (flag_emit_class_files)
12877             decl = TREE_OPERAND (op, 0);
12878           else
12879             decl = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (op, 0), 0), 0);
12880           decl = DECL_FUNCTION_ACCESS_DECL (decl);
12881         }
12882       /* We really should have a JAVA_ARRAY_EXPR to avoid this */
12883       else if (!JDECL_P (decl) 
12884           && TREE_CODE (decl) != COMPONENT_REF
12885           && !(flag_emit_class_files && TREE_CODE (decl) == ARRAY_REF)
12886           && TREE_CODE (decl) != INDIRECT_REF
12887           && !(TREE_CODE (decl) == COMPOUND_EXPR
12888                && TREE_OPERAND (decl, 1)
12889                && (TREE_CODE (TREE_OPERAND (decl, 1)) == INDIRECT_REF)))
12890         {
12891           tree lvalue;
12892           /* Before screaming, check that we're not in fact trying to
12893              increment a optimized static final access, in which case
12894              we issue an different error message. */
12895           if (!(TREE_CODE (wfl_op) == EXPR_WITH_FILE_LOCATION
12896                 && resolve_expression_name (wfl_op, &lvalue)
12897                 && check_final_assignment (lvalue, wfl_op)))
12898             parse_error_context (wfl_operator, "Invalid argument to `%s'",
12899                                  operator_string (node));
12900           TREE_TYPE (node) = error_mark_node;
12901           error_found = 1;
12902         }
12903       
12904       if (check_final_assignment (op, wfl_op))
12905         error_found = 1;
12906
12907       /* From now on, we know that op if a variable and that it has a
12908          valid wfl. We use wfl_op to locate errors related to the
12909          ++/-- operand. */
12910       else if (!JNUMERIC_TYPE_P (op_type))
12911         {
12912           parse_error_context
12913             (wfl_op, "Invalid argument type `%s' to `%s'",
12914              lang_printable_name (op_type, 0), operator_string (node));
12915           TREE_TYPE (node) = error_mark_node;
12916           error_found = 1;
12917         }
12918       else
12919         {
12920           /* Before the addition, binary numeric promotion is performed on
12921              both operands, if really necessary */
12922           if (JINTEGRAL_TYPE_P (op_type))
12923             {
12924               value = build_int_2 (1, 0);
12925               TREE_TYPE (value) = TREE_TYPE (node) = op_type;
12926             }
12927           else
12928             {
12929               value = build_int_2 (1, 0);
12930               TREE_TYPE (node) = 
12931                 binary_numeric_promotion (op_type, 
12932                                           TREE_TYPE (value), &op, &value);
12933             }
12934
12935           /* We remember we might be accessing an outer field */
12936           if (outer_field_flag)
12937             {
12938               /* We re-generate an access to the field */
12939               value = build (PLUS_EXPR, TREE_TYPE (op), 
12940                              build_outer_field_access (wfl_op, decl), value);
12941                                                     
12942               /* And we patch the original access$() into a write 
12943                  with plus_op as a rhs */
12944               return outer_field_access_fix (node, op, value);
12945             }
12946
12947           /* And write back into the node. */
12948           TREE_OPERAND (node, 0) = op;
12949           TREE_OPERAND (node, 1) = value;
12950           /* Convert the overall back into its original type, if
12951              necessary, and return */
12952           if (JINTEGRAL_TYPE_P (op_type))
12953             return fold (node);
12954           else
12955             return fold (convert (op_type, node));
12956         }
12957       break;
12958
12959       /* 15.14.3 Unary Plus Operator + */
12960     case UNARY_PLUS_EXPR:
12961       /* 15.14.4 Unary Minus Operator - */
12962     case NEGATE_EXPR:
12963       if (!JNUMERIC_TYPE_P (op_type))
12964         {
12965           ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op_type);
12966           TREE_TYPE (node) = error_mark_node;
12967           error_found = 1;
12968         }
12969       /* Unary numeric promotion is performed on operand */
12970       else
12971         {
12972           op = do_unary_numeric_promotion (op);
12973           prom_type = TREE_TYPE (op);
12974           if (code == UNARY_PLUS_EXPR)
12975             return fold (op);
12976         }
12977       break;
12978
12979       /* 15.14.5 Bitwise Complement Operator ~ */
12980     case BIT_NOT_EXPR:
12981       if (!JINTEGRAL_TYPE_P (op_type))
12982         {
12983           ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op_type);
12984           TREE_TYPE (node) = error_mark_node;
12985           error_found = 1;
12986         }
12987       else
12988         {
12989           op = do_unary_numeric_promotion (op);
12990           prom_type = TREE_TYPE (op);
12991         }
12992       break;
12993
12994       /* 15.14.6 Logical Complement Operator ! */
12995     case TRUTH_NOT_EXPR:
12996       if (TREE_CODE (op_type) != BOOLEAN_TYPE)
12997         {
12998           ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op_type);
12999           /* But the type is known. We will report an error if further
13000              attempt of a assignment is made with this rhs */
13001           TREE_TYPE (node) = boolean_type_node;
13002           error_found = 1;
13003         }
13004       else
13005         prom_type = boolean_type_node;
13006       break;
13007
13008       /* 15.15 Cast Expression */
13009     case CONVERT_EXPR:
13010       value = patch_cast (node, wfl_operator);
13011       if (value == error_mark_node)
13012         {
13013           /* If this cast is part of an assignment, we tell the code
13014              that deals with it not to complain about a mismatch,
13015              because things have been cast, anyways */
13016           TREE_TYPE (node) = error_mark_node;
13017           error_found = 1;
13018         }
13019       else
13020         {
13021           value = fold (value);
13022           TREE_SIDE_EFFECTS (value) = TREE_SIDE_EFFECTS (op);
13023           return value;
13024         }
13025       break;
13026     }
13027   
13028   if (error_found)
13029     return error_mark_node;
13030
13031   /* There are cases where node has been replaced by something else
13032      and we don't end up returning here: UNARY_PLUS_EXPR,
13033      CONVERT_EXPR, {POST,PRE}{INCR,DECR}EMENT_EXPR. */
13034   TREE_OPERAND (node, 0) = fold (op);
13035   TREE_TYPE (node) = prom_type;
13036   TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op);
13037   return fold (node);
13038 }
13039
13040 /* Generic type resolution that sometimes takes place during node
13041    patching. Returned the resolved type or generate an error
13042    message. Return the resolved type or NULL_TREE.  */
13043
13044 static tree
13045 resolve_type_during_patch (type)
13046      tree type;
13047 {
13048   if (unresolved_type_p (type, NULL))
13049     {
13050       tree type_decl = resolve_no_layout (EXPR_WFL_NODE (type), NULL_TREE);
13051       if (!type_decl)
13052         {
13053           parse_error_context (type, 
13054                                "Class `%s' not found in type declaration",
13055                                IDENTIFIER_POINTER (EXPR_WFL_NODE (type)));
13056           return NULL_TREE;
13057         }
13058       else
13059         {
13060           CLASS_LOADED_P (TREE_TYPE (type_decl)) = 1;
13061           return TREE_TYPE (type_decl);
13062         }
13063     }
13064   return type;
13065 }
13066 /* 5.5 Casting Conversion. error_mark_node is returned if an error is
13067    found. Otherwise NODE or something meant to replace it is returned.  */
13068
13069 static tree
13070 patch_cast (node, wfl_operator)
13071      tree node;
13072      tree wfl_operator;
13073 {
13074   tree op = TREE_OPERAND (node, 0);
13075   tree op_type = TREE_TYPE (op);
13076   tree cast_type = TREE_TYPE (node);
13077   char *t1;
13078
13079   /* First resolve OP_TYPE if unresolved */
13080   if (!(cast_type = resolve_type_during_patch (cast_type)))
13081     return error_mark_node;
13082
13083   /* Check on cast that are proven correct at compile time */
13084   if (JNUMERIC_TYPE_P (cast_type) && JNUMERIC_TYPE_P (op_type))
13085     {
13086       /* Same type */
13087       if (cast_type == op_type)
13088         return node;
13089
13090       /* float and double type are converted to the original type main
13091          variant and then to the target type. */
13092       if (JFLOAT_TYPE_P (op_type) && TREE_CODE (cast_type) == CHAR_TYPE)
13093         op = convert (integer_type_node, op);
13094
13095       /* Try widening/narowwing convertion. Potentially, things need
13096          to be worked out in gcc so we implement the extreme cases
13097          correctly. fold_convert() needs to be fixed. */
13098       return convert (cast_type, op);
13099     }
13100
13101   /* It's also valid to cast a boolean into a boolean */
13102   if (op_type == boolean_type_node && cast_type == boolean_type_node)
13103     return node;
13104
13105   /* null can be casted to references */
13106   if (op == null_pointer_node && JREFERENCE_TYPE_P (cast_type))
13107     return build_null_of_type (cast_type);
13108
13109   /* The remaining legal casts involve conversion between reference
13110      types. Check for their compile time correctness. */
13111   if (JREFERENCE_TYPE_P (op_type) && JREFERENCE_TYPE_P (cast_type) 
13112       && valid_ref_assignconv_cast_p (op_type, cast_type, 1))
13113     {
13114       TREE_TYPE (node) = promote_type (cast_type);
13115       /* Now, the case can be determined correct at compile time if
13116          OP_TYPE can be converted into CAST_TYPE by assignment
13117          conversion (5.2) */
13118
13119       if (valid_ref_assignconv_cast_p (op_type, cast_type, 0))
13120         {
13121           TREE_SET_CODE (node, NOP_EXPR);
13122           return node;
13123         }
13124
13125       if (flag_emit_class_files)
13126         {
13127           TREE_SET_CODE (node, CONVERT_EXPR);
13128           return node;
13129         }
13130
13131       /* The cast requires a run-time check */
13132       return build (CALL_EXPR, promote_type (cast_type),
13133                     build_address_of (soft_checkcast_node),
13134                     tree_cons (NULL_TREE, build_class_ref (cast_type),
13135                                build_tree_list (NULL_TREE, op)),
13136                     NULL_TREE);
13137     }
13138
13139   /* Any other casts are proven incorrect at compile time */
13140   t1 = xstrdup (lang_printable_name (op_type, 0));
13141   parse_error_context (wfl_operator, "Invalid cast from `%s' to `%s'",
13142                        t1, lang_printable_name (cast_type, 0));
13143   free (t1);
13144   return error_mark_node;
13145 }
13146
13147 /* Build a null constant and give it the type TYPE.  */
13148
13149 static tree
13150 build_null_of_type (type)
13151      tree type;
13152 {
13153   tree node = build_int_2 (0, 0);
13154   TREE_TYPE (node) = promote_type (type);
13155   return node;
13156 }
13157
13158 /* Build an ARRAY_REF incomplete tree node. Note that operand 1 isn't
13159    a list of indices. */
13160 static tree
13161 build_array_ref (location, array, index)
13162      int location;
13163      tree array, index;
13164 {
13165   tree node = build (ARRAY_REF, NULL_TREE, array, index);
13166   EXPR_WFL_LINECOL (node) = location;
13167   return node;
13168 }
13169
13170 /* 15.12 Array Access Expression */
13171
13172 static tree
13173 patch_array_ref (node)
13174      tree node;
13175 {
13176   tree array = TREE_OPERAND (node, 0);
13177   tree array_type  = TREE_TYPE (array);
13178   tree index = TREE_OPERAND (node, 1);
13179   tree index_type = TREE_TYPE (index);
13180   int error_found = 0;
13181
13182   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13183
13184   if (TREE_CODE (array_type) == POINTER_TYPE)
13185     array_type = TREE_TYPE (array_type);
13186
13187   /* The array reference must be an array */
13188   if (!TYPE_ARRAY_P (array_type))
13189     {
13190       parse_error_context 
13191         (wfl_operator,
13192          "`[]' can only be applied to arrays. It can't be applied to `%s'",
13193          lang_printable_name (array_type, 0));
13194       TREE_TYPE (node) = error_mark_node;
13195       error_found = 1;
13196     }
13197
13198   /* The array index undergoes unary numeric promotion. The promoted
13199      type must be int */
13200   index = do_unary_numeric_promotion (index);
13201   if (TREE_TYPE (index) != int_type_node)
13202     {
13203       if (valid_cast_to_p (index_type, int_type_node))
13204         parse_error_context (wfl_operator,
13205    "Incompatible type for `[]'. Explicit cast needed to convert `%s' to `int'",
13206                              lang_printable_name (index_type, 0));
13207       else
13208         parse_error_context (wfl_operator,
13209           "Incompatible type for `[]'. Can't convert `%s' to `int'",
13210                              lang_printable_name (index_type, 0));
13211       TREE_TYPE (node) = error_mark_node;
13212       error_found = 1;
13213     }
13214
13215   if (error_found)
13216     return error_mark_node;
13217
13218   array_type = TYPE_ARRAY_ELEMENT (array_type);
13219
13220   if (flag_emit_class_files || flag_emit_xref)
13221     {
13222       TREE_OPERAND (node, 0) = array;
13223       TREE_OPERAND (node, 1) = index;
13224     }
13225   else
13226     {
13227       /* The save_expr is for correct evaluation order.  It would be cleaner
13228          to use force_evaluation_order (see comment there), but that is
13229          difficult when we also have to deal with bounds checking. */
13230       if (TREE_SIDE_EFFECTS (index))
13231         array = save_expr (array);
13232       node = build_java_arrayaccess (array, array_type, index);
13233       if (TREE_SIDE_EFFECTS (index))
13234         node = build (COMPOUND_EXPR, array_type, array, node);
13235     }
13236   TREE_TYPE (node) = array_type;
13237   return node;
13238 }
13239
13240 /* 15.9 Array Creation Expressions */
13241
13242 static tree
13243 build_newarray_node (type, dims, extra_dims)
13244      tree type;
13245      tree dims;
13246      int extra_dims;
13247 {
13248   tree node =
13249     build (NEW_ARRAY_EXPR, NULL_TREE, type, nreverse (dims), 
13250            build_int_2 (extra_dims, 0));
13251   return node;
13252 }
13253
13254 static tree
13255 patch_newarray (node)
13256      tree node;
13257 {
13258   tree type = TREE_OPERAND (node, 0);
13259   tree dims = TREE_OPERAND (node, 1);
13260   tree cdim, array_type;
13261   int error_found = 0;
13262   int ndims = 0;
13263   int xdims = TREE_INT_CST_LOW (TREE_OPERAND (node, 2));
13264
13265   /* Dimension types are verified. It's better for the types to be
13266      verified in order. */
13267   for (cdim = dims, ndims = 0; cdim; cdim = TREE_CHAIN (cdim), ndims++ )
13268     {
13269       int dim_error = 0;
13270       tree dim = TREE_VALUE (cdim);
13271
13272       /* Dim might have been saved during its evaluation */
13273       dim = (TREE_CODE (dim) == SAVE_EXPR ? dim = TREE_OPERAND (dim, 0) : dim);
13274
13275       /* The type of each specified dimension must be an integral type. */
13276       if (!JINTEGRAL_TYPE_P (TREE_TYPE (dim)))
13277         dim_error = 1;
13278
13279       /* Each expression undergoes an unary numeric promotion (5.6.1) and the
13280          promoted type must be int. */
13281       else
13282         {
13283           dim = do_unary_numeric_promotion (dim);
13284           if (TREE_TYPE (dim) != int_type_node)
13285             dim_error = 1;
13286         }
13287
13288       /* Report errors on types here */
13289       if (dim_error)
13290         {
13291           parse_error_context 
13292             (TREE_PURPOSE (cdim), 
13293              "Incompatible type for dimension in array creation expression. %s convert `%s' to `int'", 
13294              (valid_cast_to_p (TREE_TYPE (dim), int_type_node) ?
13295               "Explicit cast needed to" : "Can't"),
13296              lang_printable_name (TREE_TYPE (dim), 0));
13297           error_found = 1;
13298         }
13299
13300       TREE_PURPOSE (cdim) = NULL_TREE;
13301     }
13302
13303   /* Resolve array base type if unresolved */
13304   if (!(type = resolve_type_during_patch (type)))
13305     error_found = 1;
13306
13307   if (error_found)
13308     {
13309       /* We don't want further evaluation of this bogus array creation
13310          operation */
13311       TREE_TYPE (node) = error_mark_node;
13312       return error_mark_node;
13313     }
13314
13315   /* Set array_type to the actual (promoted) array type of the result. */
13316   if (TREE_CODE (type) == RECORD_TYPE)
13317     type = build_pointer_type (type);
13318   while (--xdims >= 0)
13319     {
13320       type = promote_type (build_java_array_type (type, -1));
13321     }
13322   dims = nreverse (dims);
13323   array_type = type;
13324   for (cdim = dims; cdim; cdim = TREE_CHAIN (cdim))
13325     {
13326       type = array_type;
13327       array_type
13328         = build_java_array_type (type,
13329                                  TREE_CODE (cdim) == INTEGER_CST
13330                                  ? (HOST_WIDE_INT) TREE_INT_CST_LOW (cdim)
13331                                  : -1);
13332       array_type = promote_type (array_type);
13333     }
13334   dims = nreverse (dims);
13335
13336   /* The node is transformed into a function call. Things are done
13337      differently according to the number of dimensions. If the number
13338      of dimension is equal to 1, then the nature of the base type
13339      (primitive or not) matters. */
13340   if (ndims == 1)
13341     return build_new_array (type, TREE_VALUE (dims));
13342   
13343   /* Can't reuse what's already written in expr.c because it uses the
13344      JVM stack representation. Provide a build_multianewarray. FIXME */
13345   return build (CALL_EXPR, array_type,
13346                 build_address_of (soft_multianewarray_node),
13347                 tree_cons (NULL_TREE, build_class_ref (TREE_TYPE (array_type)),
13348                            tree_cons (NULL_TREE, 
13349                                       build_int_2 (ndims, 0), dims )),
13350                 NULL_TREE);
13351 }
13352
13353 /* 10.6 Array initializer.  */
13354
13355 /* Build a wfl for array element that don't have one, so we can
13356    pin-point errors.  */
13357
13358 static tree
13359 maybe_build_array_element_wfl (node)
13360      tree node;
13361 {
13362   if (TREE_CODE (node) != EXPR_WITH_FILE_LOCATION)
13363     return build_expr_wfl (NULL_TREE, ctxp->filename,
13364                            ctxp->elc.line, ctxp->elc.prev_col);
13365   else
13366     return NULL_TREE;
13367 }
13368
13369 /* Build a NEW_ARRAY_INIT that features a CONSTRUCTOR node. This makes
13370    identification of initialized arrays easier to detect during walk
13371    and expansion.  */
13372
13373 static tree
13374 build_new_array_init (location, values)
13375      int location;
13376      tree values;
13377 {
13378   tree constructor = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, values);
13379   tree to_return = build1 (NEW_ARRAY_INIT, NULL_TREE, constructor);
13380   EXPR_WFL_LINECOL (to_return) = location;
13381   return to_return;
13382 }
13383
13384 /* Expand a NEW_ARRAY_INIT node. Return error_mark_node if an error
13385    occurred.  Otherwise return NODE after having set its type
13386    appropriately.  */
13387
13388 static tree
13389 patch_new_array_init (type, node)
13390      tree type, node;
13391 {
13392   int error_seen = 0;
13393   tree current, element_type;
13394   HOST_WIDE_INT length;
13395   int all_constant = 1;
13396   tree init = TREE_OPERAND (node, 0);
13397
13398   if (TREE_CODE (type) != POINTER_TYPE || ! TYPE_ARRAY_P (TREE_TYPE (type)))
13399     {
13400       parse_error_context (node,
13401                            "Invalid array initializer for non-array type `%s'",
13402                            lang_printable_name (type, 1));
13403       return error_mark_node;
13404     }
13405   type = TREE_TYPE (type);
13406   element_type = TYPE_ARRAY_ELEMENT (type);
13407
13408   CONSTRUCTOR_ELTS (init) = nreverse (CONSTRUCTOR_ELTS (init));
13409
13410   for (length = 0, current = CONSTRUCTOR_ELTS (init);
13411        current;  length++, current = TREE_CHAIN (current))
13412     {
13413       tree elt = TREE_VALUE (current);
13414       if (elt == NULL_TREE || TREE_CODE (elt) != NEW_ARRAY_INIT)
13415         {
13416           error_seen |= array_constructor_check_entry (element_type, current);
13417           elt = TREE_VALUE (current);
13418           /* When compiling to native code, STRING_CST is converted to
13419              INDIRECT_REF, but still with a TREE_CONSTANT flag. */
13420           if (! TREE_CONSTANT (elt) || TREE_CODE (elt) == INDIRECT_REF)
13421             all_constant = 0;
13422         }
13423       else
13424         {
13425           TREE_VALUE (current) = patch_new_array_init (element_type, elt);
13426           TREE_PURPOSE (current) = NULL_TREE;
13427           all_constant = 0;
13428         }
13429       if (elt && TREE_VALUE (elt) == error_mark_node)
13430         error_seen = 1;
13431     }
13432
13433   if (error_seen)
13434     return error_mark_node;
13435
13436   /* Create a new type. We can't reuse the one we have here by
13437      patching its dimension because it originally is of dimension -1
13438      hence reused by gcc. This would prevent triangular arrays. */
13439   type = build_java_array_type (element_type, length);
13440   TREE_TYPE (init) = TREE_TYPE (TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (type))));
13441   TREE_TYPE (node) = promote_type (type);
13442   TREE_CONSTANT (init) = all_constant;
13443   TREE_CONSTANT (node) = all_constant;
13444   return node;
13445 }
13446
13447 /* Verify that one entry of the initializer element list can be
13448    assigned to the array base type. Report 1 if an error occurred, 0
13449    otherwise.  */
13450
13451 static int
13452 array_constructor_check_entry (type, entry)
13453      tree type, entry;
13454 {
13455   char *array_type_string = NULL;       /* For error reports */
13456   tree value, type_value, new_value, wfl_value, patched;
13457   int error_seen = 0;
13458
13459   new_value = NULL_TREE;
13460   wfl_value = TREE_VALUE (entry);
13461
13462   push_obstacks (&permanent_obstack, &permanent_obstack);
13463   value = java_complete_tree (TREE_VALUE (entry));
13464   /* patch_string return error_mark_node if arg is error_mark_node */
13465   if ((patched = patch_string (value)))
13466     value = patched;
13467   if (value == error_mark_node)
13468     return 1;
13469   
13470   type_value = TREE_TYPE (value);
13471   
13472   /* At anytime, try_builtin_assignconv can report a warning on
13473      constant overflow during narrowing. */
13474   SET_WFL_OPERATOR (wfl_operator, TREE_PURPOSE (entry), wfl_value);
13475   new_value = try_builtin_assignconv (wfl_operator, type, value);
13476   if (!new_value && (new_value = try_reference_assignconv (type, value)))
13477     type_value = promote_type (type);
13478
13479   pop_obstacks ();
13480   /* Check and report errors */
13481   if (!new_value)
13482     {
13483       const char *msg = (!valid_cast_to_p (type_value, type) ?
13484                    "Can't" : "Explicit cast needed to");
13485       if (!array_type_string)
13486         array_type_string = xstrdup (lang_printable_name (type, 1));
13487       parse_error_context 
13488         (wfl_operator, "Incompatible type for array. %s convert `%s' to `%s'",
13489          msg, lang_printable_name (type_value, 1), array_type_string);
13490       error_seen = 1;
13491     }
13492   
13493   if (new_value)
13494     {
13495       new_value = maybe_build_primttype_type_ref (new_value, wfl_operator);
13496       TREE_VALUE (entry) = new_value;
13497     }
13498
13499   if (array_type_string)
13500     free (array_type_string);
13501
13502   TREE_PURPOSE (entry) = NULL_TREE;
13503   return error_seen;
13504 }
13505
13506 static tree
13507 build_this (location)
13508      int location;
13509 {
13510   tree node = build_wfl_node (this_identifier_node);
13511   TREE_SET_CODE (node, THIS_EXPR);
13512   EXPR_WFL_LINECOL (node) = location;
13513   return node;
13514 }
13515
13516 /* 14.15 The return statement. It builds a modify expression that
13517    assigns the returned value to the RESULT_DECL that hold the value
13518    to be returned. */
13519
13520 static tree
13521 build_return (location, op)
13522      int location;
13523      tree op;
13524 {
13525   tree node = build1 (RETURN_EXPR, NULL_TREE, op);
13526   EXPR_WFL_LINECOL (node) = location;
13527   node = build_debugable_stmt (location, node);
13528   return node;
13529 }
13530
13531 static tree
13532 patch_return (node)
13533      tree node;
13534 {
13535   tree return_exp = TREE_OPERAND (node, 0);
13536   tree meth = current_function_decl;
13537   tree mtype = TREE_TYPE (TREE_TYPE (current_function_decl));
13538   int error_found = 0;
13539
13540   TREE_TYPE (node) = error_mark_node;
13541   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13542
13543   /* It's invalid to have a return value within a function that is
13544      declared with the keyword void or that is a constructor */
13545   if (return_exp && (mtype == void_type_node || DECL_CONSTRUCTOR_P (meth)))
13546     error_found = 1;
13547
13548   /* It's invalid to use a return statement in a static block */
13549   if (DECL_CLINIT_P (current_function_decl))
13550     error_found = 1;
13551
13552   /* It's invalid to have a no return value within a function that
13553      isn't declared with the keyword `void' */
13554   if (!return_exp && (mtype != void_type_node && !DECL_CONSTRUCTOR_P (meth)))
13555     error_found = 2;
13556   
13557   if (in_instance_initializer)
13558     error_found = 1;
13559
13560   if (error_found)
13561     {
13562       if (in_instance_initializer)
13563         parse_error_context (wfl_operator,
13564                              "`return' inside instance initializer");
13565         
13566       else if (DECL_CLINIT_P (current_function_decl))
13567         parse_error_context (wfl_operator,
13568                              "`return' inside static initializer");
13569
13570       else if (!DECL_CONSTRUCTOR_P (meth))
13571         {
13572           char *t = xstrdup (lang_printable_name (mtype, 0));
13573           parse_error_context (wfl_operator, 
13574                                "`return' with%s value from `%s %s'",
13575                                (error_found == 1 ? "" : "out"), 
13576                                t, lang_printable_name (meth, 0));
13577           free (t);
13578         }
13579       else
13580         parse_error_context (wfl_operator, 
13581                              "`return' with value from constructor `%s'",
13582                              lang_printable_name (meth, 0));
13583       return error_mark_node;
13584     }
13585
13586   /* If we have a return_exp, build a modify expression and expand
13587      it. Note: at that point, the assignment is declared valid, but we
13588      may want to carry some more hacks */
13589   if (return_exp)
13590     {
13591       tree exp = java_complete_tree (return_exp);
13592       tree modify, patched;
13593
13594       /* If the function returned value and EXP are booleans, EXP has
13595       to be converted into the type of DECL_RESULT, which is integer
13596       (see complete_start_java_method) */
13597       if (TREE_TYPE (exp) == boolean_type_node &&
13598           TREE_TYPE (TREE_TYPE (meth)) == boolean_type_node)
13599         exp = convert_to_integer (TREE_TYPE (DECL_RESULT (meth)), exp);
13600
13601       /* `null' can be assigned to a function returning a reference */
13602       if (JREFERENCE_TYPE_P (TREE_TYPE (TREE_TYPE (meth))) &&
13603           exp == null_pointer_node)
13604         exp = build_null_of_type (TREE_TYPE (TREE_TYPE (meth)));
13605
13606       if ((patched = patch_string (exp)))
13607         exp = patched;
13608       
13609       modify = build (MODIFY_EXPR, NULL_TREE, DECL_RESULT (meth), exp);
13610       EXPR_WFL_LINECOL (modify) = EXPR_WFL_LINECOL (node);
13611       modify = java_complete_tree (modify);
13612
13613       if (modify != error_mark_node)
13614         {
13615           TREE_SIDE_EFFECTS (modify) = 1;
13616           TREE_OPERAND (node, 0) = modify;
13617         }
13618       else
13619         return error_mark_node;
13620     }
13621   TREE_TYPE (node) = void_type_node;
13622   TREE_SIDE_EFFECTS (node) = 1;
13623   return node;
13624 }
13625
13626 /* 14.8 The if Statement */
13627
13628 static tree
13629 build_if_else_statement (location, expression, if_body, else_body)
13630      int location;
13631      tree expression, if_body, else_body;
13632 {
13633   tree node;
13634   if (!else_body)
13635     else_body = empty_stmt_node;
13636   node = build (COND_EXPR, NULL_TREE, expression, if_body, else_body);
13637   EXPR_WFL_LINECOL (node) = location;
13638   node = build_debugable_stmt (location, node);
13639   return node;
13640 }
13641
13642 static tree
13643 patch_if_else_statement (node)
13644      tree node;
13645 {
13646   tree expression = TREE_OPERAND (node, 0);
13647
13648   TREE_TYPE (node) = error_mark_node;
13649   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13650
13651   /* The type of expression must be boolean */
13652   if (TREE_TYPE (expression) != boolean_type_node
13653       && TREE_TYPE (expression) != promoted_boolean_type_node)
13654     {
13655       parse_error_context 
13656         (wfl_operator, 
13657          "Incompatible type for `if'. Can't convert `%s' to `boolean'", 
13658          lang_printable_name (TREE_TYPE (expression), 0));
13659       return error_mark_node;
13660     }
13661   
13662   TREE_TYPE (node) = void_type_node;
13663   TREE_SIDE_EFFECTS (node) = 1;
13664   CAN_COMPLETE_NORMALLY (node)
13665     = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1))
13666     | CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 2));
13667   return node;
13668 }
13669
13670 /* 14.6 Labeled Statements */
13671
13672 /* Action taken when a lableled statement is parsed. a new
13673    LABELED_BLOCK_EXPR is created. No statement is attached to the
13674    label, yet.  LABEL can be NULL_TREE for artificially-generated blocks. */
13675
13676 static tree
13677 build_labeled_block (location, label)
13678      int location;
13679      tree label;
13680 {
13681   tree label_name ;
13682   tree label_decl, node;
13683   if (label == NULL_TREE || label == continue_identifier_node)
13684     label_name = label;
13685   else
13686     {
13687       label_name = merge_qualified_name (label_id, label);
13688       /* Issue an error if we try to reuse a label that was previously
13689          declared */
13690       if (IDENTIFIER_LOCAL_VALUE (label_name))
13691         {
13692           EXPR_WFL_LINECOL (wfl_operator) = location;
13693           parse_error_context (wfl_operator,
13694             "Declaration of `%s' shadows a previous label declaration",
13695                                IDENTIFIER_POINTER (label));
13696           EXPR_WFL_LINECOL (wfl_operator) = 
13697             EXPR_WFL_LINECOL (IDENTIFIER_LOCAL_VALUE (label_name));
13698           parse_error_context (wfl_operator,
13699             "This is the location of the previous declaration of label `%s'",
13700                                IDENTIFIER_POINTER (label));
13701           java_error_count--;
13702         }
13703     }
13704
13705   label_decl = create_label_decl (label_name);
13706   node = build (LABELED_BLOCK_EXPR, NULL_TREE, label_decl, NULL_TREE);
13707   EXPR_WFL_LINECOL (node) = location;
13708   TREE_SIDE_EFFECTS (node) = 1;
13709   return node;
13710 }
13711
13712 /* A labeled statement LBE is attached a statement.  */
13713
13714 static tree
13715 finish_labeled_statement (lbe, statement)
13716      tree lbe;                  /* Labeled block expr */
13717      tree statement;
13718 {
13719   /* In anyways, tie the loop to its statement */
13720   LABELED_BLOCK_BODY (lbe) = statement;
13721   pop_labeled_block ();
13722   POP_LABELED_BLOCK ();
13723   return lbe;
13724 }
13725
13726 /* 14.10, 14.11, 14.12 Loop Statements */
13727
13728 /* Create an empty LOOP_EXPR and make it the last in the nested loop
13729    list. */
13730
13731 static tree
13732 build_new_loop (loop_body)
13733      tree loop_body;
13734 {
13735   tree loop =  build (LOOP_EXPR, NULL_TREE, loop_body);
13736   TREE_SIDE_EFFECTS (loop) = 1;
13737   PUSH_LOOP (loop);
13738   return loop;
13739 }
13740
13741 /* Create a loop body according to the following structure:
13742      COMPOUND_EXPR
13743        COMPOUND_EXPR            (loop main body)
13744          EXIT_EXPR              (this order is for while/for loops.
13745          LABELED_BLOCK_EXPR      the order is reversed for do loops)
13746            LABEL_DECL           (a continue occuring here branches at the 
13747            BODY                  end of this labeled block)
13748        INCREMENT                (if any)
13749
13750   REVERSED, if non zero, tells that the loop condition expr comes
13751   after the body, like in the do-while loop.
13752
13753   To obtain a loop, the loop body structure described above is
13754   encapsulated within a LOOP_EXPR surrounded by a LABELED_BLOCK_EXPR:
13755
13756    LABELED_BLOCK_EXPR
13757      LABEL_DECL                   (use this label to exit the loop)
13758      LOOP_EXPR
13759        <structure described above> */
13760
13761 static tree
13762 build_loop_body (location, condition, reversed)
13763      int location;
13764      tree condition;
13765      int reversed;
13766 {
13767   tree first, second, body;
13768
13769   condition = build (EXIT_EXPR, NULL_TREE, condition); /* Force walk */
13770   EXPR_WFL_LINECOL (condition) = location; /* For accurate error report */
13771   condition = build_debugable_stmt (location, condition);
13772   TREE_SIDE_EFFECTS (condition) = 1;
13773
13774   body = build_labeled_block (0, continue_identifier_node);
13775   first = (reversed ? body : condition);
13776   second = (reversed ? condition : body);
13777   return 
13778     build (COMPOUND_EXPR, NULL_TREE, 
13779            build (COMPOUND_EXPR, NULL_TREE, first, second), empty_stmt_node);
13780 }
13781
13782 /* Install CONDITION (if any) and loop BODY (using REVERSED to tell
13783    their order) on the current loop. Unlink the current loop from the
13784    loop list.  */
13785
13786 static tree
13787 finish_loop_body (location, condition, body, reversed)
13788      int location;
13789      tree condition, body;
13790      int reversed;
13791 {
13792   tree to_return = ctxp->current_loop;
13793   tree loop_body = LOOP_EXPR_BODY (to_return);
13794   if (condition)
13795     {
13796       tree cnode = LOOP_EXPR_BODY_CONDITION_EXPR (loop_body, reversed);
13797       /* We wrapped the EXIT_EXPR around a WFL so we can debug it.
13798          The real EXIT_EXPR is one operand further. */
13799       EXPR_WFL_LINECOL (cnode) = location;
13800       /* This one is for accurate error reports */
13801       EXPR_WFL_LINECOL (TREE_OPERAND (cnode, 0)) = location;
13802       TREE_OPERAND (TREE_OPERAND (cnode, 0), 0) = condition;
13803     }
13804   LOOP_EXPR_BODY_BODY_EXPR (loop_body, reversed) = body;
13805   POP_LOOP ();
13806   return to_return;
13807 }
13808
13809 /* Tailored version of finish_loop_body for FOR loops, when FOR
13810    loops feature the condition part */
13811
13812 static tree
13813 finish_for_loop (location, condition, update, body)
13814     int location;
13815     tree condition, update, body;
13816 {
13817   /* Put the condition and the loop body in place */
13818   tree loop = finish_loop_body (location, condition, body, 0);
13819   /* LOOP is the current loop which has been now popped of the loop
13820      stack. Install the update block */
13821   LOOP_EXPR_BODY_UPDATE_BLOCK (LOOP_EXPR_BODY (loop)) = update;
13822   return loop;
13823 }
13824
13825 /* Try to find the loop a block might be related to. This comprises
13826    the case where the LOOP_EXPR is found as the second operand of a
13827    COMPOUND_EXPR, because the loop happens to have an initialization
13828    part, then expressed as the first operand of the COMPOUND_EXPR. If
13829    the search finds something, 1 is returned. Otherwise, 0 is
13830    returned. The search is assumed to start from a
13831    LABELED_BLOCK_EXPR's block.  */
13832
13833 static tree
13834 search_loop (statement)
13835     tree statement;
13836 {
13837   if (TREE_CODE (statement) == LOOP_EXPR)
13838     return statement;
13839
13840   if (TREE_CODE (statement) == BLOCK)
13841     statement = BLOCK_SUBBLOCKS (statement);
13842   else
13843     return NULL_TREE;
13844
13845   if (statement && TREE_CODE (statement) == COMPOUND_EXPR)
13846     while (statement && TREE_CODE (statement) == COMPOUND_EXPR)
13847       statement = TREE_OPERAND (statement, 1);
13848
13849   return (TREE_CODE (statement) == LOOP_EXPR
13850           && FOR_LOOP_P (statement) ? statement : NULL_TREE);
13851 }
13852
13853 /* Return 1 if LOOP can be found in the labeled block BLOCK. 0 is
13854    returned otherwise.  */
13855
13856 static int
13857 labeled_block_contains_loop_p (block, loop)
13858     tree block, loop;
13859 {
13860   if (!block)
13861     return 0;
13862
13863   if (LABELED_BLOCK_BODY (block) == loop)
13864     return 1;
13865
13866   if (FOR_LOOP_P (loop) && search_loop (LABELED_BLOCK_BODY (block)) == loop)
13867     return 1;
13868
13869   return 0;
13870 }
13871
13872 /* If the loop isn't surrounded by a labeled statement, create one and
13873    insert LOOP as its body.  */
13874
13875 static tree
13876 patch_loop_statement (loop)
13877      tree loop;
13878 {
13879   tree loop_label;
13880
13881   TREE_TYPE (loop) = void_type_node;
13882   if (labeled_block_contains_loop_p (ctxp->current_labeled_block, loop))
13883     return loop;
13884
13885   loop_label = build_labeled_block (0, NULL_TREE);
13886   /* LOOP is an EXPR node, so it should have a valid EXPR_WFL_LINECOL
13887      that LOOP_LABEL could enquire about, for a better accuracy. FIXME */
13888   LABELED_BLOCK_BODY (loop_label) = loop;
13889   PUSH_LABELED_BLOCK (loop_label);
13890   return loop_label;
13891 }
13892
13893 /* 14.13, 14.14: break and continue Statements */
13894
13895 /* Build a break or a continue statement. a null NAME indicates an
13896    unlabeled break/continue statement.  */
13897
13898 static tree
13899 build_bc_statement (location, is_break, name)
13900      int location, is_break;
13901      tree name;
13902 {
13903   tree break_continue, label_block_expr = NULL_TREE;
13904
13905   if (name)
13906     {
13907       if (!(label_block_expr = IDENTIFIER_LOCAL_VALUE 
13908             (merge_qualified_name (label_id, EXPR_WFL_NODE (name)))))
13909         /* Null means that we don't have a target for this named
13910            break/continue. In this case, we make the target to be the
13911            label name, so that the error can be reported accuratly in
13912            patch_bc_statement. */
13913         label_block_expr = EXPR_WFL_NODE (name);
13914     }
13915   /* Unlabeled break/continue will be handled during the
13916      break/continue patch operation */
13917   break_continue 
13918     = build (EXIT_BLOCK_EXPR, NULL_TREE, label_block_expr, NULL_TREE);
13919
13920   IS_BREAK_STMT_P (break_continue) = is_break;
13921   TREE_SIDE_EFFECTS (break_continue) = 1;
13922   EXPR_WFL_LINECOL (break_continue) = location;
13923   break_continue = build_debugable_stmt (location, break_continue);
13924   return break_continue;
13925 }
13926
13927 /* Verification of a break/continue statement. */
13928
13929 static tree
13930 patch_bc_statement (node)
13931      tree node;
13932 {
13933   tree bc_label = EXIT_BLOCK_LABELED_BLOCK (node), target_stmt;
13934   tree labeled_block = ctxp->current_labeled_block;
13935   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13936  
13937   /* Having an identifier here means that the target is unknown. */
13938   if (bc_label != NULL_TREE && TREE_CODE (bc_label) == IDENTIFIER_NODE)
13939     {
13940       parse_error_context (wfl_operator, "No label definition found for `%s'",
13941                            IDENTIFIER_POINTER (bc_label));
13942       return error_mark_node;
13943     }
13944   if (! IS_BREAK_STMT_P (node))
13945     {
13946       /* It's a continue statement. */
13947       for (;; labeled_block = TREE_CHAIN (labeled_block))
13948         {
13949           if (labeled_block == NULL_TREE)
13950             {
13951               if (bc_label == NULL_TREE)
13952                 parse_error_context (wfl_operator,
13953                                      "`continue' must be in loop");
13954               else
13955                 parse_error_context 
13956                   (wfl_operator, "continue label `%s' does not name a loop",
13957                    IDENTIFIER_POINTER (bc_label));
13958               return error_mark_node;
13959             }
13960           if ((DECL_NAME (LABELED_BLOCK_LABEL (labeled_block))
13961                == continue_identifier_node)
13962               && (bc_label == NULL_TREE
13963                   || TREE_CHAIN (labeled_block) == bc_label))
13964             {
13965               bc_label = labeled_block;
13966               break;
13967             }
13968         }
13969     }
13970   else if (!bc_label)
13971     { 
13972       for (;; labeled_block = TREE_CHAIN (labeled_block))
13973         {
13974           if (labeled_block == NULL_TREE)
13975             {
13976               parse_error_context (wfl_operator,
13977                                      "`break' must be in loop or switch");
13978               return error_mark_node;
13979             }
13980           target_stmt = LABELED_BLOCK_BODY (labeled_block);
13981           if (TREE_CODE (target_stmt) == SWITCH_EXPR
13982               || search_loop (target_stmt))
13983             {
13984               bc_label = labeled_block;
13985               break;
13986             }
13987         }
13988     }
13989
13990   EXIT_BLOCK_LABELED_BLOCK (node) = bc_label;
13991   CAN_COMPLETE_NORMALLY (bc_label) = 1;
13992
13993   /* Our break/continue don't return values. */
13994   TREE_TYPE (node) = void_type_node;
13995   /* Encapsulate the break within a compound statement so that it's
13996      expanded all the times by expand_expr (and not clobbered
13997      sometimes, like after a if statement) */
13998   node = add_stmt_to_compound (NULL_TREE, void_type_node, node);
13999   TREE_SIDE_EFFECTS (node) = 1;
14000   return node;
14001 }
14002
14003 /* Process the exit expression belonging to a loop. Its type must be
14004    boolean.  */
14005
14006 static tree
14007 patch_exit_expr (node)
14008      tree node;
14009 {
14010   tree expression = TREE_OPERAND (node, 0);
14011   TREE_TYPE (node) = error_mark_node;
14012   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14013
14014   /* The type of expression must be boolean */
14015   if (TREE_TYPE (expression) != boolean_type_node)
14016     {
14017       parse_error_context 
14018         (wfl_operator, 
14019     "Incompatible type for loop conditional. Can't convert `%s' to `boolean'", 
14020          lang_printable_name (TREE_TYPE (expression), 0));
14021       return error_mark_node;
14022     }
14023   /* Now we know things are allright, invert the condition, fold and
14024      return */
14025   TREE_OPERAND (node, 0) = 
14026     fold (build1 (TRUTH_NOT_EXPR, boolean_type_node, expression));
14027
14028   if (! integer_zerop (TREE_OPERAND (node, 0))
14029       && ctxp->current_loop != NULL_TREE
14030       && TREE_CODE (ctxp->current_loop) == LOOP_EXPR)
14031     CAN_COMPLETE_NORMALLY (ctxp->current_loop) = 1;
14032   if (! integer_onep (TREE_OPERAND (node, 0)))
14033     CAN_COMPLETE_NORMALLY (node) = 1;
14034
14035
14036   TREE_TYPE (node) = void_type_node;
14037   return node;
14038 }
14039
14040 /* 14.9 Switch statement */
14041
14042 static tree
14043 patch_switch_statement (node)
14044      tree node;
14045 {
14046   tree se = TREE_OPERAND (node, 0), se_type;
14047
14048   /* Complete the switch expression */
14049   se = TREE_OPERAND (node, 0) = java_complete_tree (se);
14050   se_type = TREE_TYPE (se);
14051   /* The type of the switch expression must be char, byte, short or
14052      int */
14053   if (!JINTEGRAL_TYPE_P (se_type))
14054     {
14055       EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14056       parse_error_context (wfl_operator,
14057           "Incompatible type for `switch'. Can't convert `%s' to `int'",
14058                            lang_printable_name (se_type, 0));
14059       /* This is what java_complete_tree will check */
14060       TREE_OPERAND (node, 0) = error_mark_node;
14061       return error_mark_node;
14062     }
14063
14064   TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
14065
14066   /* Ready to return */
14067   if (TREE_CODE (TREE_OPERAND (node, 1)) == ERROR_MARK)
14068     {
14069       TREE_TYPE (node) = error_mark_node;
14070       return error_mark_node;
14071     }
14072   TREE_TYPE (node) = void_type_node;
14073   TREE_SIDE_EFFECTS (node) = 1;
14074   CAN_COMPLETE_NORMALLY (node)
14075     = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)) 
14076       || ! SWITCH_HAS_DEFAULT (node);
14077   return node;
14078 }
14079
14080 /* 14.18 The try/catch statements */
14081
14082 static tree
14083 build_try_statement (location, try_block, catches)
14084      int location;
14085      tree try_block, catches;
14086 {
14087   tree node = build (TRY_EXPR, NULL_TREE, try_block, catches);
14088   EXPR_WFL_LINECOL (node) = location;
14089   return node;
14090 }
14091
14092 static tree
14093 build_try_finally_statement (location, try_block, finally)
14094      int location;
14095      tree try_block, finally;
14096 {
14097   tree node = build (TRY_FINALLY_EXPR, NULL_TREE, try_block, finally);
14098   EXPR_WFL_LINECOL (node) = location;
14099   return node;
14100 }
14101
14102 static tree
14103 patch_try_statement (node)
14104      tree node;
14105 {
14106   int error_found = 0;
14107   tree try = TREE_OPERAND (node, 0);
14108   /* Exception handlers are considered in left to right order */
14109   tree catch = nreverse (TREE_OPERAND (node, 1));
14110   tree current, caught_type_list = NULL_TREE;
14111
14112   /* Check catch clauses, if any. Every time we find an error, we try
14113      to process the next catch clause. We process the catch clause before
14114      the try block so that when processing the try block we can check thrown
14115      exceptions againts the caught type list. */
14116   for (current = catch; current; current = TREE_CHAIN (current))
14117     {
14118       tree carg_decl, carg_type;
14119       tree sub_current, catch_block, catch_clause;
14120       int unreachable;
14121
14122       /* At this point, the structure of the catch clause is
14123            CATCH_EXPR           (catch node)
14124              BLOCK              (with the decl of the parameter)
14125                COMPOUND_EXPR
14126                  MODIFY_EXPR   (assignment of the catch parameter)
14127                  BLOCK          (catch clause block)
14128        */
14129       catch_clause = TREE_OPERAND (current, 0);
14130       carg_decl = BLOCK_EXPR_DECLS (catch_clause);
14131       carg_type = TREE_TYPE (TREE_TYPE (carg_decl));
14132
14133       /* Catch clauses can't have more than one parameter declared,
14134          but it's already enforced by the grammar. Make sure that the
14135          only parameter of the clause statement in of class Throwable
14136          or a subclass of Throwable, but that was done earlier. The
14137          catch clause parameter type has also been resolved. */
14138       
14139       /* Just make sure that the catch clause parameter type inherits
14140          from java.lang.Throwable */
14141       if (!inherits_from_p (carg_type, throwable_type_node))
14142         {
14143           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
14144           parse_error_context (wfl_operator,
14145                                "Can't catch class `%s'. Catch clause parameter type must be a subclass of class `java.lang.Throwable'",
14146                                lang_printable_name (carg_type, 0));
14147           error_found = 1;
14148           continue;
14149         }
14150       
14151       /* Partial check for unreachable catch statement: The catch
14152          clause is reachable iff is no earlier catch block A in
14153          the try statement such that the type of the catch
14154          clause's parameter is the same as or a subclass of the
14155          type of A's parameter */
14156       unreachable = 0;
14157       for (sub_current = catch;
14158            sub_current != current; sub_current = TREE_CHAIN (sub_current))
14159         {
14160           tree sub_catch_clause, decl;
14161           sub_catch_clause = TREE_OPERAND (sub_current, 0);
14162           decl = BLOCK_EXPR_DECLS (sub_catch_clause);
14163
14164           if (inherits_from_p (carg_type, TREE_TYPE (TREE_TYPE (decl))))
14165             {
14166               EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
14167               parse_error_context 
14168                 (wfl_operator,
14169                  "`catch' not reached because of the catch clause at line %d",
14170                  EXPR_WFL_LINENO (sub_current));
14171               unreachable = error_found = 1;
14172               break;
14173             }
14174         }
14175       /* Complete the catch clause block */
14176       catch_block = java_complete_tree (TREE_OPERAND (current, 0));
14177       if (catch_block == error_mark_node)
14178         {
14179           error_found = 1;
14180           continue;
14181         }
14182       if (CAN_COMPLETE_NORMALLY (catch_block))
14183         CAN_COMPLETE_NORMALLY (node) = 1;
14184       TREE_OPERAND (current, 0) = catch_block;
14185
14186       if (unreachable)
14187         continue;
14188
14189       /* Things to do here: the exception must be thrown */
14190
14191       /* Link this type to the caught type list */
14192       caught_type_list = tree_cons (NULL_TREE, carg_type, caught_type_list);
14193     }
14194
14195   PUSH_EXCEPTIONS (caught_type_list);
14196   if ((try = java_complete_tree (try)) == error_mark_node)
14197     error_found = 1;
14198   if (CAN_COMPLETE_NORMALLY (try))
14199     CAN_COMPLETE_NORMALLY (node) = 1;
14200   POP_EXCEPTIONS ();
14201
14202   /* Verification ends here */
14203   if (error_found) 
14204     return error_mark_node;
14205
14206   TREE_OPERAND (node, 0) = try;
14207   TREE_OPERAND (node, 1) = catch;
14208   TREE_TYPE (node) = void_type_node;
14209   return node;
14210 }
14211
14212 /* 14.17 The synchronized Statement */
14213
14214 static tree
14215 patch_synchronized_statement (node, wfl_op1)
14216     tree node, wfl_op1;
14217 {
14218   tree expr = java_complete_tree (TREE_OPERAND (node, 0));
14219   tree block = TREE_OPERAND (node, 1);
14220
14221   tree enter, exit, expr_decl, assignment;
14222
14223   if (expr == error_mark_node)
14224     {
14225       block = java_complete_tree (block);
14226       return expr;
14227     }
14228
14229   /* The TYPE of expr must be a reference type */
14230   if (!JREFERENCE_TYPE_P (TREE_TYPE (expr)))
14231     {
14232       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
14233       parse_error_context (wfl_operator, "Incompatible type for `synchronized'. Can't convert `%s' to `java.lang.Object'",
14234                            lang_printable_name (TREE_TYPE (expr), 0));
14235       return error_mark_node;
14236     }
14237
14238   if (flag_emit_xref)
14239     {
14240       TREE_OPERAND (node, 0) = expr;
14241       TREE_OPERAND (node, 1) = java_complete_tree (block);
14242       CAN_COMPLETE_NORMALLY (node) = 1;
14243       return node;
14244     }
14245
14246   /* Generate a try-finally for the synchronized statement, except
14247      that the handler that catches all throw exception calls
14248      _Jv_MonitorExit and then rethrow the exception.
14249      The synchronized statement is then implemented as:
14250      TRY 
14251        {
14252          _Jv_MonitorEnter (expression)
14253          synchronized_block
14254          _Jv_MonitorExit (expression)
14255        }
14256      CATCH_ALL
14257        {
14258          e = _Jv_exception_info ();
14259          _Jv_MonitorExit (expression)
14260          Throw (e);
14261        } */
14262
14263   expr_decl = build_decl (VAR_DECL, generate_name (), TREE_TYPE (expr));
14264   BUILD_MONITOR_ENTER (enter, expr_decl);
14265   BUILD_MONITOR_EXIT (exit, expr_decl);
14266   CAN_COMPLETE_NORMALLY (enter) = 1;
14267   CAN_COMPLETE_NORMALLY (exit) = 1;
14268   assignment = build (MODIFY_EXPR, NULL_TREE, expr_decl, expr);
14269   TREE_SIDE_EFFECTS (assignment) = 1;
14270   node = build1 (CLEANUP_POINT_EXPR, NULL_TREE,
14271                  build (COMPOUND_EXPR, NULL_TREE,
14272                         build (WITH_CLEANUP_EXPR, NULL_TREE,
14273                                build (COMPOUND_EXPR, NULL_TREE,
14274                                       assignment, enter),
14275                                NULL_TREE, exit),
14276                         block));
14277   node = build_expr_block (node, expr_decl);
14278
14279   return java_complete_tree (node);
14280 }
14281
14282 /* 14.16 The throw Statement */
14283
14284 static tree
14285 patch_throw_statement (node, wfl_op1)
14286     tree node, wfl_op1;
14287 {
14288   tree expr = TREE_OPERAND (node, 0);
14289   tree type = TREE_TYPE (expr);
14290   int unchecked_ok = 0, tryblock_throws_ok = 0;
14291
14292   /* Thrown expression must be assignable to java.lang.Throwable */
14293   if (!try_reference_assignconv (throwable_type_node, expr))
14294     {
14295       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
14296       parse_error_context (wfl_operator,
14297     "Can't throw `%s'; it must be a subclass of class `java.lang.Throwable'",
14298                            lang_printable_name (type, 0));
14299       /* If the thrown expression was a reference, we further the
14300          compile-time check. */
14301       if (!JREFERENCE_TYPE_P (type))
14302         return error_mark_node;
14303     }
14304
14305   /* At least one of the following must be true */
14306
14307   /* The type of the throw expression is a not checked exception,
14308      i.e. is a unchecked expression. */
14309   unchecked_ok = IS_UNCHECKED_EXCEPTION_P (TREE_TYPE (type));
14310
14311   SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
14312   /* An instance can't throw a checked excetion unless that exception
14313      is explicitely declared in the `throws' clause of each
14314      constructor. This doesn't apply to anonymous classes, since they
14315      don't have declared constructors. */
14316   if (!unchecked_ok 
14317       && in_instance_initializer && !ANONYMOUS_CLASS_P (current_class))
14318     {
14319       tree current;
14320       for (current = TYPE_METHODS (current_class); current; 
14321            current = TREE_CHAIN (current))
14322         if (DECL_CONSTRUCTOR_P (current) 
14323             && !check_thrown_exceptions_do (TREE_TYPE (expr)))
14324           {
14325             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)", 
14326                                  lang_printable_name (TREE_TYPE (expr), 0));
14327             return error_mark_node;
14328           }
14329     }
14330
14331   /* Throw is contained in a try statement and at least one catch
14332      clause can receive the thrown expression or the current method is
14333      declared to throw such an exception. Or, the throw statement is
14334      contained in a method or constructor declaration and the type of
14335      the Expression is assignable to at least one type listed in the
14336      throws clause the declaration. */
14337   if (!unchecked_ok)
14338     tryblock_throws_ok = check_thrown_exceptions_do (TREE_TYPE (expr));
14339   if (!(unchecked_ok || tryblock_throws_ok))
14340     {
14341       /* If there is a surrounding try block that has no matching
14342          clatch clause, report it first. A surrounding try block exits
14343          only if there is something after the list of checked
14344          exception thrown by the current function (if any). */
14345       if (IN_TRY_BLOCK_P ())
14346         parse_error_context (wfl_operator, "Checked exception `%s' can't be caught by any of the catch clause(s) of the surrounding `try' block",
14347                              lang_printable_name (type, 0));
14348       /* If we have no surrounding try statement and the method doesn't have
14349          any throws, report it now. FIXME */
14350
14351       /* We report that the exception can't be throw from a try block
14352          in all circumstances but when the `throw' is inside a static
14353          block. */
14354       else if (!EXCEPTIONS_P (currently_caught_type_list) 
14355                && !tryblock_throws_ok)
14356         {
14357           if (DECL_CLINIT_P (current_function_decl))
14358             parse_error_context (wfl_operator,
14359                    "Checked exception `%s' can't be thrown in initializer",
14360                                  lang_printable_name (type, 0));
14361           else
14362             parse_error_context (wfl_operator,
14363                    "Checked exception `%s' isn't thrown from a `try' block", 
14364                                  lang_printable_name (type, 0));
14365         }
14366       /* Otherwise, the current method doesn't have the appropriate
14367          throws declaration */
14368       else
14369         parse_error_context (wfl_operator, "Checked exception `%s' doesn't match any of current method's `throws' declaration(s)", 
14370                              lang_printable_name (type, 0));
14371       return error_mark_node;
14372     }
14373
14374   if (! flag_emit_class_files && ! flag_emit_xref)
14375     BUILD_THROW (node, expr);
14376
14377   /* If doing xrefs, keep the location where the `throw' was seen. */
14378   if (flag_emit_xref)
14379     EXPR_WFL_LINECOL (node) = EXPR_WFL_LINECOL (wfl_op1);
14380   return node;
14381 }
14382
14383 /* Check that exception said to be thrown by method DECL can be
14384    effectively caught from where DECL is invoked.  */
14385
14386 static void
14387 check_thrown_exceptions (location, decl)
14388      int location;
14389      tree decl;
14390 {
14391   tree throws;
14392   /* For all the unchecked exceptions thrown by DECL */
14393   for (throws = DECL_FUNCTION_THROWS (decl); throws; 
14394        throws = TREE_CHAIN (throws)) 
14395     if (!check_thrown_exceptions_do (TREE_VALUE (throws)))
14396       {
14397 #if 1
14398         /* Temporary hack to suppresses errors about cloning arrays. FIXME */
14399         if (DECL_NAME (decl) == get_identifier ("clone"))
14400           continue;
14401 #endif
14402         EXPR_WFL_LINECOL (wfl_operator) = location;
14403         if (DECL_FINIT_P (current_function_decl))
14404           parse_error_context
14405             (wfl_operator, "Exception `%s' can't be thrown in initializer",
14406              lang_printable_name (TREE_VALUE (throws), 0));
14407         else 
14408           {
14409             parse_error_context 
14410               (wfl_operator, "Exception `%s' must be caught, or it must be declared in the `throws' clause of `%s'", 
14411                lang_printable_name (TREE_VALUE (throws), 0),
14412                (DECL_INIT_P (current_function_decl) ?
14413                 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))) :
14414                 IDENTIFIER_POINTER (DECL_NAME (current_function_decl))));
14415           }
14416       }
14417 }
14418
14419 /* Return 1 if checked EXCEPTION is caught at the current nesting level of
14420    try-catch blocks, OR is listed in the `throws' clause of the
14421    current method.  */
14422
14423 static int
14424 check_thrown_exceptions_do (exception)
14425      tree exception;
14426 {
14427   tree list = currently_caught_type_list;
14428   resolve_and_layout (exception, NULL_TREE);
14429   /* First, all the nested try-catch-finally at that stage. The
14430      last element contains `throws' clause exceptions, if any. */
14431   if (IS_UNCHECKED_EXCEPTION_P (exception))
14432     return 1;
14433   while (list)
14434     {
14435       tree caught;
14436       for (caught = TREE_VALUE (list); caught; caught = TREE_CHAIN (caught))
14437         if (valid_ref_assignconv_cast_p (exception, TREE_VALUE (caught), 0))
14438           return 1;
14439       list = TREE_CHAIN (list);
14440     }
14441   return 0;
14442 }
14443
14444 static void
14445 purge_unchecked_exceptions (mdecl)
14446      tree mdecl;
14447 {
14448   tree throws = DECL_FUNCTION_THROWS (mdecl);
14449   tree new = NULL_TREE;
14450
14451   while (throws)
14452     {
14453       tree next = TREE_CHAIN (throws);
14454       if (!IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (throws)))
14455         {
14456           TREE_CHAIN (throws) = new;
14457           new = throws;
14458         }
14459       throws = next;
14460     }
14461   /* List is inverted here, but it doesn't matter */
14462   DECL_FUNCTION_THROWS (mdecl) = new;
14463 }
14464
14465 /* 15.24 Conditional Operator ?: */
14466
14467 static tree
14468 patch_conditional_expr (node, wfl_cond, wfl_op1)
14469      tree node, wfl_cond, wfl_op1;
14470 {
14471   tree cond = TREE_OPERAND (node, 0);
14472   tree op1 = TREE_OPERAND (node, 1);
14473   tree op2 = TREE_OPERAND (node, 2);
14474   tree resulting_type = NULL_TREE;
14475   tree t1, t2, patched;
14476   int error_found = 0;
14477
14478   /* Operands of ?: might be StringBuffers crafted as a result of a
14479      string concatenation. Obtain a descent operand here.  */
14480   if ((patched = patch_string (op1)))
14481     TREE_OPERAND (node, 1) = op1 = patched;
14482   if ((patched = patch_string (op2)))
14483     TREE_OPERAND (node, 2) = op2 = patched;
14484
14485   t1 = TREE_TYPE (op1);
14486   t2 = TREE_TYPE (op2);
14487
14488   /* The first expression must be a boolean */
14489   if (TREE_TYPE (cond) != boolean_type_node)
14490     {
14491       SET_WFL_OPERATOR (wfl_operator, node, wfl_cond);
14492       parse_error_context (wfl_operator,
14493                "Incompatible type for `?:'. Can't convert `%s' to `boolean'",
14494                            lang_printable_name (TREE_TYPE (cond), 0));
14495       error_found = 1;
14496     }
14497
14498   /* Second and third can be numeric, boolean (i.e. primitive),
14499      references or null. Anything else results in an error */
14500   if (!((JNUMERIC_TYPE_P (t1) && JNUMERIC_TYPE_P (t2))
14501         || ((JREFERENCE_TYPE_P (t1) || op1 == null_pointer_node) 
14502             && (JREFERENCE_TYPE_P (t2) || op2 == null_pointer_node))
14503         || (t1 == boolean_type_node && t2 == boolean_type_node)))
14504     error_found = 1;
14505
14506   /* Determine the type of the conditional expression. Same types are
14507      easy to deal with */
14508   else if (t1 == t2)
14509     resulting_type = t1;
14510
14511   /* There are different rules for numeric types */
14512   else if (JNUMERIC_TYPE_P (t1))
14513     {
14514       /* if byte/short found, the resulting type is short */
14515       if ((t1 == byte_type_node && t2 == short_type_node)
14516           || (t1 == short_type_node && t2 == byte_type_node))
14517         resulting_type = short_type_node;
14518
14519       /* If t1 is a constant int and t2 is of type byte, short or char
14520          and t1's value fits in t2, then the resulting type is t2 */
14521       else if ((t1 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 1)))
14522           && JBSC_TYPE_P (t2) && int_fits_type_p (TREE_OPERAND (node, 1), t2))
14523         resulting_type = t2;
14524
14525       /* If t2 is a constant int and t1 is of type byte, short or char
14526          and t2's value fits in t1, then the resulting type is t1 */
14527       else if ((t2 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 2)))
14528           && JBSC_TYPE_P (t1) && int_fits_type_p (TREE_OPERAND (node, 2), t1))
14529         resulting_type = t1;
14530
14531       /* Otherwise, binary numeric promotion is applied and the
14532          resulting type is the promoted type of operand 1 and 2 */
14533       else 
14534         resulting_type = binary_numeric_promotion (t1, t2, 
14535                                                    &TREE_OPERAND (node, 1), 
14536                                                    &TREE_OPERAND (node, 2));
14537     }
14538
14539   /* Cases of a reference and a null type */
14540   else if (JREFERENCE_TYPE_P (t1) && op2 == null_pointer_node)
14541     resulting_type = t1;
14542
14543   else if (JREFERENCE_TYPE_P (t2) && op1 == null_pointer_node)
14544     resulting_type = t2;
14545
14546   /* Last case: different reference types. If a type can be converted
14547      into the other one by assignment conversion, the latter
14548      determines the type of the expression */
14549   else if ((resulting_type = try_reference_assignconv (t1, op2)))
14550     resulting_type = promote_type (t1);
14551
14552   else if ((resulting_type = try_reference_assignconv (t2, op1)))
14553     resulting_type = promote_type (t2);
14554
14555   /* If we don't have any resulting type, we're in trouble */
14556   if (!resulting_type)
14557     {
14558       char *t = xstrdup (lang_printable_name (t1, 0));
14559       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
14560       parse_error_context (wfl_operator,
14561                  "Incompatible type for `?:'. Can't convert `%s' to `%s'",
14562                            t, lang_printable_name (t2, 0));
14563       free (t);
14564       error_found = 1;
14565     }
14566
14567   if (error_found)
14568     {
14569       TREE_TYPE (node) = error_mark_node;
14570       return error_mark_node;
14571     }
14572
14573   TREE_TYPE (node) = resulting_type;
14574   TREE_SET_CODE (node, COND_EXPR);
14575   CAN_COMPLETE_NORMALLY (node) = 1;
14576   return node;
14577 }
14578
14579 /* Try to constant fold NODE.
14580    If NODE is not a constant expression, return NULL_EXPR.
14581    CONTEXT is a static final VAR_DECL whose initializer we are folding. */
14582
14583 static tree
14584 fold_constant_for_init (node, context)
14585      tree node;
14586      tree context;
14587 {
14588   tree op0, op1, val;
14589   enum tree_code code = TREE_CODE (node);
14590
14591   if (code == STRING_CST)
14592     return node;
14593
14594   if (code == INTEGER_CST || code == REAL_CST)
14595     return convert (TREE_TYPE (context), node);
14596
14597   switch (code)
14598     {
14599     case PLUS_EXPR:
14600     case MINUS_EXPR:
14601     case MULT_EXPR:
14602     case TRUNC_MOD_EXPR:
14603     case RDIV_EXPR:
14604     case LSHIFT_EXPR:
14605     case RSHIFT_EXPR:
14606     case URSHIFT_EXPR:
14607     case BIT_AND_EXPR:
14608     case BIT_XOR_EXPR:
14609     case BIT_IOR_EXPR:
14610     case TRUTH_ANDIF_EXPR:
14611     case TRUTH_ORIF_EXPR:
14612     case EQ_EXPR: 
14613     case NE_EXPR:
14614     case GT_EXPR:
14615     case GE_EXPR:
14616     case LT_EXPR:
14617     case LE_EXPR:
14618       op0 = TREE_OPERAND (node, 0);
14619       op1 = TREE_OPERAND (node, 1);
14620       val = fold_constant_for_init (op0, context);
14621       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14622         return NULL_TREE;
14623       TREE_OPERAND (node, 0) = val;
14624       val = fold_constant_for_init (op1, context);
14625       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14626         return NULL_TREE;
14627       TREE_OPERAND (node, 1) = val;
14628       return patch_binop (node, op0, op1);
14629
14630     case UNARY_PLUS_EXPR:
14631     case NEGATE_EXPR:
14632     case TRUTH_NOT_EXPR:
14633     case BIT_NOT_EXPR:
14634     case CONVERT_EXPR:
14635       op0 = TREE_OPERAND (node, 0);
14636       val = fold_constant_for_init (op0, context);
14637       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14638         return NULL_TREE;
14639       TREE_OPERAND (node, 0) = val;
14640       return patch_unaryop (node, op0);
14641       break;
14642
14643     case COND_EXPR:
14644       val = fold_constant_for_init (TREE_OPERAND (node, 0), context);
14645       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14646         return NULL_TREE;
14647       TREE_OPERAND (node, 0) = val;
14648       val = fold_constant_for_init (TREE_OPERAND (node, 1), context);
14649       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14650         return NULL_TREE;
14651       TREE_OPERAND (node, 1) = val;
14652       val = fold_constant_for_init (TREE_OPERAND (node, 2), context);
14653       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14654         return NULL_TREE;
14655       TREE_OPERAND (node, 2) = val;
14656       return integer_zerop (TREE_OPERAND (node, 0)) ? TREE_OPERAND (node, 1)
14657         : TREE_OPERAND (node, 2);
14658
14659     case VAR_DECL:
14660     case FIELD_DECL:
14661       if (! FIELD_FINAL (node)
14662           || DECL_INITIAL (node) == NULL_TREE)
14663         return NULL_TREE;
14664       val = DECL_INITIAL (node);
14665       /* Guard against infinite recursion. */
14666       DECL_INITIAL (node) = NULL_TREE;
14667       val = fold_constant_for_init (val, node);
14668       DECL_INITIAL (node) = val;
14669       return val;
14670
14671     case EXPR_WITH_FILE_LOCATION:
14672       /* Compare java_complete_tree and resolve_expression_name. */
14673       if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
14674           || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
14675         {
14676           tree name = EXPR_WFL_NODE (node);
14677           tree decl;
14678           if (PRIMARY_P (node))
14679             return NULL_TREE;
14680           else if (! QUALIFIED_P (name))
14681             {
14682               decl = lookup_field_wrapper (DECL_CONTEXT (context), name);
14683               if (decl == NULL_TREE 
14684                   || (! FIELD_STATIC (decl) && ! FIELD_FINAL (decl)))
14685                 return NULL_TREE;
14686               return fold_constant_for_init (decl, decl);
14687             }
14688           else
14689             {
14690               /* Wait until the USE_COMPONENT_REF re-write.  FIXME. */
14691               qualify_ambiguous_name (node);
14692               if (resolve_field_access (node, &decl, NULL)
14693                   && decl != NULL_TREE)
14694                 return fold_constant_for_init (decl, decl);
14695               return NULL_TREE;
14696             }
14697         }
14698       else
14699         {
14700           op0 = TREE_OPERAND (node, 0);
14701           val = fold_constant_for_init (op0, context);
14702           if (val == NULL_TREE || ! TREE_CONSTANT (val))
14703             return NULL_TREE;
14704           TREE_OPERAND (node, 0) = val;
14705           return val;
14706         }
14707
14708 #ifdef USE_COMPONENT_REF
14709     case IDENTIFIER:
14710     case COMPONENT_REF:
14711       ?;
14712 #endif
14713
14714     default:
14715       return NULL_TREE;
14716     }
14717 }
14718
14719 #ifdef USE_COMPONENT_REF
14720 /* Context is 'T' for TypeName, 'P' for PackageName,
14721    'M' for MethodName, 'E' for ExpressionName, and 'A' for AmbiguousName. */
14722
14723 tree
14724 resolve_simple_name (name, context)
14725      tree name;
14726      int context;
14727 {
14728 }
14729
14730 tree
14731 resolve_qualified_name (name, context)
14732      tree name;
14733      int context;
14734 {
14735 }
14736 #endif