OSDN Git Service

(This trying to counter the effect of the PR 195 check in -- this should
[pf3gnuchains/gcc-fork.git] / gcc / java / parse.y
1 /* Source code parsing and tree node generation for the GNU compiler
2    for the Java(TM) language.
3    Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
4    Contributed by Alexandre Petit-Bianco (apbianco@cygnus.com)
5
6 This file is part of GNU CC.
7
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING.  If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
22
23 Java and all Java-based marks are trademarks or registered trademarks
24 of Sun Microsystems, Inc. in the United States and other countries.
25 The Free Software Foundation is independent of Sun Microsystems, Inc.  */
26
27 /* This file parses java source code and issues a tree node image
28 suitable for code generation (byte code and targeted CPU assembly
29 language).
30
31 The grammar conforms to the Java grammar described in "The Java(TM)
32 Language Specification. J. Gosling, B. Joy, G. Steele. Addison Wesley
33 1996, ISBN 0-201-63451-1"
34
35 The following modifications were brought to the original grammar:
36
37 method_body: added the rule '| block SC_TK'
38 static_initializer: added the rule 'static block SC_TK'. 
39
40 Note: All the extra rules described above should go away when the
41       empty_statement rule will work.
42
43 statement_nsi: 'nsi' should be read no_short_if.
44
45 Some rules have been modified to support JDK1.1 inner classes
46 definitions and other extensions.  */
47
48 %{
49 #include "config.h"
50 #include "system.h"
51 #include <dirent.h>
52 #include "tree.h"
53 #include "rtl.h"
54 #include "obstack.h"
55 #include "toplev.h"
56 #include "flags.h"
57 #include "java-tree.h"
58 #include "jcf.h"
59 #include "lex.h"
60 #include "parse.h"
61 #include "zipfile.h"
62 #include "convert.h"
63 #include "buffer.h"
64 #include "xref.h"
65 #include "function.h"
66 #include "except.h"
67 #include "defaults.h"
68
69 #ifndef DIR_SEPARATOR
70 #define DIR_SEPARATOR '/'
71 #endif
72
73 /* Local function prototypes */
74 static char *java_accstring_lookup PARAMS ((int));
75 static void  classitf_redefinition_error PARAMS ((const char *,tree, tree, tree));
76 static void  variable_redefinition_error PARAMS ((tree, tree, tree, int));
77 static tree  create_class PARAMS ((int, tree, tree, tree));
78 static tree  create_interface PARAMS ((int, tree, tree));
79 static void  end_class_declaration PARAMS ((int));
80 static tree  find_field PARAMS ((tree, tree));
81 static tree lookup_field_wrapper PARAMS ((tree, tree));
82 static int   duplicate_declaration_error_p PARAMS ((tree, tree, tree));
83 static void  register_fields PARAMS ((int, tree, tree));
84 static tree parser_qualified_classname PARAMS ((int, tree));
85 static int  parser_check_super PARAMS ((tree, tree, tree));
86 static int  parser_check_super_interface PARAMS ((tree, tree, tree));
87 static void check_modifiers_consistency PARAMS ((int));
88 static tree lookup_cl PARAMS ((tree));
89 static tree lookup_java_method2 PARAMS ((tree, tree, int));
90 static tree method_header PARAMS ((int, tree, tree, tree));
91 static void fix_method_argument_names PARAMS ((tree ,tree));
92 static tree method_declarator PARAMS ((tree, tree));
93 static void parse_warning_context PARAMS ((tree cl, const char *msg, ...))
94   ATTRIBUTE_PRINTF_2;
95 static void issue_warning_error_from_context PARAMS ((tree, const char *msg, va_list));
96 static void parse_ctor_invocation_error PARAMS ((void));
97 static tree parse_jdk1_1_error PARAMS ((const char *));
98 static void complete_class_report_errors PARAMS ((jdep *));
99 static int process_imports PARAMS ((void));
100 static void read_import_dir PARAMS ((tree));
101 static int find_in_imports_on_demand PARAMS ((tree));
102 static int find_in_imports PARAMS ((tree));
103 static int check_pkg_class_access PARAMS ((tree, tree));
104 static tree resolve_package PARAMS ((tree, tree *));
105 static tree lookup_package_type PARAMS ((const char *, int));
106 static tree lookup_package_type_and_set_next PARAMS ((const char *, int, tree *));
107 static tree resolve_class PARAMS ((tree, tree, tree, tree));
108 static void declare_local_variables PARAMS ((int, tree, tree));
109 static void source_start_java_method PARAMS ((tree));
110 static void source_end_java_method PARAMS ((void));
111 static void expand_start_java_method PARAMS ((tree));
112 static tree find_name_in_single_imports PARAMS ((tree));
113 static void check_abstract_method_header PARAMS ((tree));
114 static tree lookup_java_interface_method2 PARAMS ((tree, tree));
115 static tree resolve_expression_name PARAMS ((tree, tree *));
116 static tree maybe_create_class_interface_decl PARAMS ((tree, tree, tree, tree));
117 static int check_class_interface_creation PARAMS ((int, int, tree, 
118                                                   tree, tree, tree));
119 static tree patch_method_invocation PARAMS ((tree, tree, tree, 
120                                             int *, tree *));
121 static int breakdown_qualified PARAMS ((tree *, tree *, tree));
122 static tree resolve_and_layout PARAMS ((tree, tree));
123 static tree resolve_no_layout PARAMS ((tree, tree));
124 static int invocation_mode PARAMS ((tree, int));
125 static tree find_applicable_accessible_methods_list PARAMS ((int, tree, 
126                                                             tree, tree));
127 static void search_applicable_methods_list PARAMS ((int, tree, tree, tree, 
128                                                    tree *, tree *));
129 static tree find_most_specific_methods_list PARAMS ((tree));
130 static int argument_types_convertible PARAMS ((tree, tree));
131 static tree patch_invoke PARAMS ((tree, tree, tree));
132 static int maybe_use_access_method PARAMS ((int, tree *, tree *));
133 static tree lookup_method_invoke PARAMS ((int, tree, tree, tree, tree));
134 static tree register_incomplete_type PARAMS ((int, tree, tree, tree));
135 static tree obtain_incomplete_type PARAMS ((tree));
136 static tree java_complete_lhs PARAMS ((tree));
137 static tree java_complete_tree PARAMS ((tree));
138 static tree maybe_generate_pre_expand_clinit PARAMS ((tree));
139 static void java_complete_expand_method PARAMS ((tree));
140 static int  unresolved_type_p PARAMS ((tree, tree *));
141 static void create_jdep_list PARAMS ((struct parser_ctxt *));
142 static tree build_expr_block PARAMS ((tree, tree));
143 static tree enter_block PARAMS ((void));
144 static tree enter_a_block PARAMS ((tree));
145 static tree exit_block PARAMS ((void));
146 static tree lookup_name_in_blocks PARAMS ((tree));
147 static void maybe_absorb_scoping_blocks PARAMS ((void));
148 static tree build_method_invocation PARAMS ((tree, tree));
149 static tree build_new_invocation PARAMS ((tree, tree));
150 static tree build_assignment PARAMS ((int, int, tree, tree));
151 static tree build_binop PARAMS ((enum tree_code, int, tree, tree));
152 static int check_final_assignment PARAMS ((tree ,tree));
153 static tree patch_assignment PARAMS ((tree, tree, tree ));
154 static tree patch_binop PARAMS ((tree, tree, tree));
155 static tree build_unaryop PARAMS ((int, int, tree));
156 static tree build_incdec PARAMS ((int, int, tree, int));
157 static tree patch_unaryop PARAMS ((tree, tree));
158 static tree build_cast PARAMS ((int, tree, tree));
159 static tree build_null_of_type PARAMS ((tree));
160 static tree patch_cast PARAMS ((tree, tree));
161 static int valid_ref_assignconv_cast_p PARAMS ((tree, tree, int));
162 static int valid_builtin_assignconv_identity_widening_p PARAMS ((tree, tree));
163 static int valid_cast_to_p PARAMS ((tree, tree));
164 static int valid_method_invocation_conversion_p PARAMS ((tree, tree));
165 static tree try_builtin_assignconv PARAMS ((tree, tree, tree));
166 static tree try_reference_assignconv PARAMS ((tree, tree));
167 static tree build_unresolved_array_type PARAMS ((tree));
168 static tree build_array_from_name PARAMS ((tree, tree, tree, tree *));
169 static tree build_array_ref PARAMS ((int, tree, tree));
170 static tree patch_array_ref PARAMS ((tree));
171 static tree make_qualified_name PARAMS ((tree, tree, int));
172 static tree merge_qualified_name PARAMS ((tree, tree));
173 static tree make_qualified_primary PARAMS ((tree, tree, int));
174 static int resolve_qualified_expression_name PARAMS ((tree, tree *, 
175                                                      tree *, tree *));
176 static void qualify_ambiguous_name PARAMS ((tree));
177 static tree resolve_field_access PARAMS ((tree, tree *, tree *));
178 static tree build_newarray_node PARAMS ((tree, tree, int));
179 static tree patch_newarray PARAMS ((tree));
180 static tree resolve_type_during_patch PARAMS ((tree));
181 static tree build_this PARAMS ((int));
182 static tree build_wfl_wrap PARAMS ((tree));
183 static tree build_return PARAMS ((int, tree));
184 static tree patch_return PARAMS ((tree));
185 static tree maybe_access_field PARAMS ((tree, tree, tree));
186 static int complete_function_arguments PARAMS ((tree));
187 static int check_for_static_method_reference PARAMS ((tree, tree, tree, 
188                                                       tree, tree));
189 static int not_accessible_p PARAMS ((tree, tree, int));
190 static void check_deprecation PARAMS ((tree, tree));
191 static int class_in_current_package PARAMS ((tree));
192 static tree build_if_else_statement PARAMS ((int, tree, tree, tree));
193 static tree patch_if_else_statement PARAMS ((tree));
194 static tree add_stmt_to_compound PARAMS ((tree, tree, tree));
195 static tree add_stmt_to_block PARAMS ((tree, tree, tree));
196 static tree patch_exit_expr PARAMS ((tree));
197 static tree build_labeled_block PARAMS ((int, tree));
198 static tree finish_labeled_statement PARAMS ((tree, tree));
199 static tree build_bc_statement PARAMS ((int, int, tree));
200 static tree patch_bc_statement PARAMS ((tree));
201 static tree patch_loop_statement PARAMS ((tree));
202 static tree build_new_loop PARAMS ((tree));
203 static tree build_loop_body PARAMS ((int, tree, int));
204 static tree finish_loop_body PARAMS ((int, tree, tree, int));
205 static tree build_debugable_stmt PARAMS ((int, tree));
206 static tree finish_for_loop PARAMS ((int, tree, tree, tree));
207 static tree patch_switch_statement PARAMS ((tree));
208 static tree string_constant_concatenation PARAMS ((tree, tree));
209 static tree build_string_concatenation PARAMS ((tree, tree));
210 static tree patch_string_cst PARAMS ((tree));
211 static tree patch_string PARAMS ((tree));
212 static tree build_try_statement PARAMS ((int, tree, tree));
213 static tree build_try_finally_statement PARAMS ((int, tree, tree));
214 static tree patch_try_statement PARAMS ((tree));
215 static tree patch_synchronized_statement PARAMS ((tree, tree));
216 static tree patch_throw_statement PARAMS ((tree, tree));
217 static void check_thrown_exceptions PARAMS ((int, tree));
218 static int check_thrown_exceptions_do PARAMS ((tree));
219 static void purge_unchecked_exceptions PARAMS ((tree));
220 static void check_throws_clauses PARAMS ((tree, tree, tree));
221 static void finish_method_declaration PARAMS ((tree));
222 static tree build_super_invocation PARAMS ((tree));
223 static int verify_constructor_circularity PARAMS ((tree, tree));
224 static char *constructor_circularity_msg PARAMS ((tree, tree));
225 static tree build_this_super_qualified_invocation PARAMS ((int, tree, tree,
226                                                           int, int));
227 static const char *get_printable_method_name PARAMS ((tree));
228 static tree patch_conditional_expr PARAMS ((tree, tree, tree));
229 static tree generate_finit PARAMS ((tree));
230 static void add_instance_initializer PARAMS ((tree));
231 static void fix_constructors PARAMS ((tree));
232 static tree build_alias_initializer_parameter_list PARAMS ((int, tree,
233                                                             tree, int *));
234 static void craft_constructor PARAMS ((tree, tree));
235 static int verify_constructor_super PARAMS ((tree));
236 static tree create_artificial_method PARAMS ((tree, int, tree, tree, tree));
237 static void start_artificial_method_body PARAMS ((tree));
238 static void end_artificial_method_body PARAMS ((tree));
239 static int check_method_redefinition PARAMS ((tree, tree));
240 static int reset_method_name PARAMS ((tree));
241 static int check_method_types_complete PARAMS ((tree));
242 static void java_check_regular_methods PARAMS ((tree));
243 static void java_check_abstract_methods PARAMS ((tree));
244 static tree maybe_build_primttype_type_ref PARAMS ((tree, tree));
245 static void unreachable_stmt_error PARAMS ((tree));
246 static tree find_expr_with_wfl PARAMS ((tree));
247 static void missing_return_error PARAMS ((tree));
248 static tree build_new_array_init PARAMS ((int, tree));
249 static tree patch_new_array_init PARAMS ((tree, tree));
250 static tree maybe_build_array_element_wfl PARAMS ((tree));
251 static int array_constructor_check_entry PARAMS ((tree, tree));
252 static const char *purify_type_name PARAMS ((const char *));
253 static tree fold_constant_for_init PARAMS ((tree, tree));
254 static tree strip_out_static_field_access_decl PARAMS ((tree));
255 static jdeplist *reverse_jdep_list PARAMS ((struct parser_ctxt *));
256 static void static_ref_err PARAMS ((tree, tree, tree));
257 static void parser_add_interface PARAMS ((tree, tree, tree));
258 static void add_superinterfaces PARAMS ((tree, tree));
259 static tree jdep_resolve_class PARAMS ((jdep *));
260 static int note_possible_classname PARAMS ((const char *, int));
261 static void java_complete_expand_classes PARAMS ((void));
262 static void java_complete_expand_class PARAMS ((tree));
263 static void java_complete_expand_methods PARAMS ((tree));
264 static tree cut_identifier_in_qualified PARAMS ((tree));
265 static tree java_stabilize_reference PARAMS ((tree));
266 static tree do_unary_numeric_promotion PARAMS ((tree));
267 static char * operator_string PARAMS ((tree));
268 static tree do_merge_string_cste PARAMS ((tree, const char *, int, int));
269 static tree merge_string_cste PARAMS ((tree, tree, int));
270 static tree java_refold PARAMS ((tree));
271 static int java_decl_equiv PARAMS ((tree, tree));
272 static int binop_compound_p PARAMS ((enum tree_code));
273 static tree search_loop PARAMS ((tree));
274 static int labeled_block_contains_loop_p PARAMS ((tree, tree));
275 static void check_abstract_method_definitions PARAMS ((int, tree, tree));
276 static void java_check_abstract_method_definitions PARAMS ((tree));
277 static void java_debug_context_do PARAMS ((int));
278 static void java_parser_context_push_initialized_field PARAMS ((void));
279 static void java_parser_context_pop_initialized_field PARAMS ((void));
280 static tree reorder_static_initialized PARAMS ((tree));
281 static void java_parser_context_suspend PARAMS ((void));
282 static void java_parser_context_resume PARAMS ((void));
283
284 /* JDK 1.1 work. FIXME */
285
286 static tree maybe_make_nested_class_name PARAMS ((tree));
287 static void make_nested_class_name PARAMS ((tree));
288 static void set_nested_class_simple_name_value PARAMS ((tree, int));
289 static void link_nested_class_to_enclosing PARAMS ((void));
290 static tree find_as_inner_class PARAMS ((tree, tree, tree));
291 static tree find_as_inner_class_do PARAMS ((tree, tree));
292 static int check_inner_class_redefinition PARAMS ((tree, tree));
293
294 static tree build_thisn_assign PARAMS ((void));
295 static tree build_current_thisn PARAMS ((tree));
296 static tree build_access_to_thisn PARAMS ((tree, tree, int));
297 static tree maybe_build_thisn_access_method PARAMS ((tree));
298
299 static tree build_outer_field_access PARAMS ((tree, tree));
300 static tree build_outer_field_access_methods PARAMS ((tree));
301 static tree build_outer_field_access_expr PARAMS ((int, tree, tree, 
302                                                   tree, tree));
303 static tree build_outer_method_access_method PARAMS ((tree));
304 static tree build_new_access_id PARAMS ((void));
305 static tree build_outer_field_access_method PARAMS ((tree, tree, tree,
306                                                     tree, tree));
307
308 static int outer_field_access_p PARAMS ((tree, tree));
309 static int outer_field_expanded_access_p PARAMS ((tree, tree *, 
310                                                  tree *, tree *));
311 static tree outer_field_access_fix PARAMS ((tree, tree, tree));
312 static tree build_incomplete_class_ref PARAMS ((int, tree));
313 static tree patch_incomplete_class_ref PARAMS ((tree));
314 static tree create_anonymous_class PARAMS ((int, tree));
315 static void patch_anonymous_class PARAMS ((tree, tree, tree));
316 static void add_inner_class_fields PARAMS ((tree, tree));
317
318 static tree build_dot_class_method PARAMS ((tree));
319 static tree build_dot_class_method_invocation PARAMS ((tree));
320 static void create_new_parser_context PARAMS ((int));
321
322 /* Number of error found so far. */
323 int java_error_count; 
324 /* Number of warning found so far. */
325 int java_warning_count;
326 /* Tell when not to fold, when doing xrefs */
327 int do_not_fold;
328 /* Cyclic inheritance report, as it can be set by layout_class */
329 char *cyclic_inheritance_report;
330
331 /* Tell when we're within an instance initializer */
332 static int in_instance_initializer;
333
334 /* The current parser context */
335 struct parser_ctxt *ctxp;
336
337 /* List of things that were analyzed for which code will be generated */
338 static struct parser_ctxt *ctxp_for_generation = NULL;
339
340 /* binop_lookup maps token to tree_code. It is used where binary
341    operations are involved and required by the parser. RDIV_EXPR
342    covers both integral/floating point division. The code is changed
343    once the type of both operator is worked out.  */
344
345 static enum tree_code binop_lookup[19] = 
346   { 
347     PLUS_EXPR, MINUS_EXPR, MULT_EXPR, RDIV_EXPR, TRUNC_MOD_EXPR,
348     LSHIFT_EXPR, RSHIFT_EXPR, URSHIFT_EXPR, 
349     BIT_AND_EXPR, BIT_XOR_EXPR, BIT_IOR_EXPR,
350     TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR,
351     EQ_EXPR, NE_EXPR, GT_EXPR, GE_EXPR, LT_EXPR, LE_EXPR,
352    };
353 #define BINOP_LOOKUP(VALUE)                                             \
354   binop_lookup [((VALUE) - PLUS_TK)%                                    \
355                 (sizeof (binop_lookup) / sizeof (binop_lookup[0]))]
356
357 /* This is the end index for binary operators that can also be used
358    in compound assignements. */
359 #define BINOP_COMPOUND_CANDIDATES 11
360
361 /* Fake WFL used to report error message. It is initialized once if
362    needed and reused with it's location information is overriden.  */
363 tree wfl_operator = NULL_TREE;
364
365 /* The "$L" identifier we use to create labels.  */
366 static tree label_id = NULL_TREE;
367
368 /* The "StringBuffer" identifier used for the String `+' operator. */
369 static tree wfl_string_buffer = NULL_TREE; 
370
371 /* The "append" identifier used for String `+' operator.  */
372 static tree wfl_append = NULL_TREE;
373
374 /* The "toString" identifier used for String `+' operator. */
375 static tree wfl_to_string = NULL_TREE;
376
377 /* The "java.lang" import qualified name.  */
378 static tree java_lang_id = NULL_TREE;
379
380 /* The generated `inst$' identifier used for generated enclosing
381    instance/field access functions.  */
382 static tree inst_id = NULL_TREE;
383
384 /* The "java.lang.Cloneable" qualified name.  */
385 static tree java_lang_cloneable = NULL_TREE;
386
387 /* Context and flag for static blocks */
388 static tree current_static_block = NULL_TREE;
389
390 /* The generated `write_parm_value$' identifier.  */
391 static tree wpv_id;
392
393 /* The list of all packages we've seen so far */
394 static tree package_list = NULL_TREE;
395  
396 /* Check modifiers. If one doesn't fit, retrieve it in its declaration
397    line and point it out.  */
398 /* Should point out the one that don't fit. ASCII/unicode, going
399    backward. FIXME */
400
401 #define check_modifiers(__message, __value, __mask) do {        \
402   if ((__value) & ~(__mask))                                    \
403     {                                                           \
404       int i, remainder = (__value) & ~(__mask);                 \
405       for (i = 0; i <= 10; i++)                                 \
406         if ((1 << i) & remainder)                               \
407           parse_error_context (ctxp->modifier_ctx [i], (__message), \
408                                java_accstring_lookup (1 << i)); \
409     }                                                           \
410 } while (0)
411
412 %}
413
414 %union {
415   tree node;
416   int sub_token;
417   struct {
418     int token;
419     int location;
420   } operator;
421   int value;
422 }
423
424 %{
425 #include "lex.c"
426 %}
427
428 %pure_parser
429
430 /* Things defined here have to match the order of what's in the
431    binop_lookup table.  */
432
433 %token   PLUS_TK         MINUS_TK        MULT_TK         DIV_TK    REM_TK
434 %token   LS_TK           SRS_TK          ZRS_TK
435 %token   AND_TK          XOR_TK          OR_TK
436 %token   BOOL_AND_TK BOOL_OR_TK 
437 %token   EQ_TK NEQ_TK GT_TK GTE_TK LT_TK LTE_TK
438
439 /* This maps to the same binop_lookup entry than the token above */
440
441 %token   PLUS_ASSIGN_TK  MINUS_ASSIGN_TK MULT_ASSIGN_TK DIV_ASSIGN_TK
442 %token   REM_ASSIGN_TK   
443 %token   LS_ASSIGN_TK    SRS_ASSIGN_TK   ZRS_ASSIGN_TK
444 %token   AND_ASSIGN_TK   XOR_ASSIGN_TK   OR_ASSIGN_TK
445
446
447 /* Modifier TOKEN have to be kept in this order. Don't scramble it */
448
449 %token   PUBLIC_TK       PRIVATE_TK         PROTECTED_TK
450 %token   STATIC_TK       FINAL_TK           SYNCHRONIZED_TK
451 %token   VOLATILE_TK     TRANSIENT_TK       NATIVE_TK
452 %token   PAD_TK          ABSTRACT_TK        MODIFIER_TK
453
454 /* Keep those two in order, too */
455 %token   DECR_TK INCR_TK
456
457 /* From now one, things can be in any order */
458
459 %token   DEFAULT_TK      IF_TK              THROW_TK
460 %token   BOOLEAN_TK      DO_TK              IMPLEMENTS_TK
461 %token   THROWS_TK       BREAK_TK           IMPORT_TK       
462 %token   ELSE_TK         INSTANCEOF_TK      RETURN_TK
463 %token   VOID_TK         CATCH_TK           INTERFACE_TK
464 %token   CASE_TK         EXTENDS_TK         FINALLY_TK
465 %token   SUPER_TK        WHILE_TK           CLASS_TK
466 %token   SWITCH_TK       CONST_TK           TRY_TK
467 %token   FOR_TK          NEW_TK             CONTINUE_TK
468 %token   GOTO_TK         PACKAGE_TK         THIS_TK
469
470 %token   BYTE_TK         SHORT_TK           INT_TK            LONG_TK
471 %token   CHAR_TK         INTEGRAL_TK
472
473 %token   FLOAT_TK        DOUBLE_TK          FP_TK
474
475 %token   ID_TK
476
477 %token   REL_QM_TK         REL_CL_TK NOT_TK  NEG_TK
478
479 %token   ASSIGN_ANY_TK   ASSIGN_TK
480 %token   OP_TK  CP_TK  OCB_TK  CCB_TK  OSB_TK  CSB_TK  SC_TK  C_TK DOT_TK
481
482 %token   STRING_LIT_TK   CHAR_LIT_TK        INT_LIT_TK        FP_LIT_TK
483 %token   TRUE_TK         FALSE_TK           BOOL_LIT_TK       NULL_TK
484
485 %type    <value>        modifiers MODIFIER_TK final synchronized
486
487 %type    <node>         super ID_TK identifier
488 %type    <node>         name simple_name qualified_name
489 %type    <node>         type_declaration compilation_unit
490                         field_declaration method_declaration extends_interfaces
491                         interfaces interface_type_list
492                         class_member_declaration
493                         import_declarations package_declaration 
494                         type_declarations interface_body
495                         interface_member_declaration constant_declaration
496                         interface_member_declarations interface_type
497                         abstract_method_declaration interface_type_list
498 %type    <node>         class_body_declaration class_member_declaration
499                         static_initializer constructor_declaration block
500 %type    <node>         class_body_declarations constructor_header
501 %type    <node>         class_or_interface_type class_type class_type_list
502                         constructor_declarator explicit_constructor_invocation
503 %type    <node>         dim_expr dim_exprs this_or_super throws
504
505 %type    <node>         variable_declarator_id variable_declarator
506                         variable_declarators variable_initializer
507                         variable_initializers constructor_body
508                         array_initializer
509
510 %type    <node>         class_body block_end constructor_block_end
511 %type    <node>         statement statement_without_trailing_substatement
512                         labeled_statement if_then_statement label_decl
513                         if_then_else_statement while_statement for_statement
514                         statement_nsi labeled_statement_nsi do_statement
515                         if_then_else_statement_nsi while_statement_nsi
516                         for_statement_nsi statement_expression_list for_init
517                         for_update statement_expression expression_statement
518                         primary_no_new_array expression primary
519                         array_creation_expression array_type
520                         class_instance_creation_expression field_access
521                         method_invocation array_access something_dot_new
522                         argument_list postfix_expression while_expression 
523                         post_increment_expression post_decrement_expression
524                         unary_expression_not_plus_minus unary_expression
525                         pre_increment_expression pre_decrement_expression
526                         unary_expression_not_plus_minus cast_expression
527                         multiplicative_expression additive_expression
528                         shift_expression relational_expression 
529                         equality_expression and_expression 
530                         exclusive_or_expression inclusive_or_expression
531                         conditional_and_expression conditional_or_expression
532                         conditional_expression assignment_expression
533                         left_hand_side assignment for_header for_begin
534                         constant_expression do_statement_begin empty_statement
535                         switch_statement synchronized_statement throw_statement
536                         try_statement switch_expression switch_block
537                         catches catch_clause catch_clause_parameter finally
538                         anonymous_class_creation
539 %type    <node>         return_statement break_statement continue_statement
540
541 %type    <operator>     ASSIGN_TK      MULT_ASSIGN_TK  DIV_ASSIGN_TK  
542 %type    <operator>     REM_ASSIGN_TK  PLUS_ASSIGN_TK  MINUS_ASSIGN_TK
543 %type    <operator>     LS_ASSIGN_TK   SRS_ASSIGN_TK   ZRS_ASSIGN_TK
544 %type    <operator>     AND_ASSIGN_TK  XOR_ASSIGN_TK   OR_ASSIGN_TK
545 %type    <operator>     ASSIGN_ANY_TK  assignment_operator
546 %token   <operator>     EQ_TK GTE_TK ZRS_TK SRS_TK GT_TK LTE_TK LS_TK 
547 %token   <operator>     BOOL_AND_TK AND_TK BOOL_OR_TK OR_TK INCR_TK PLUS_TK
548 %token   <operator>     DECR_TK MINUS_TK MULT_TK DIV_TK XOR_TK REM_TK NEQ_TK
549 %token   <operator>     NEG_TK REL_QM_TK REL_CL_TK NOT_TK LT_TK OCB_TK CCB_TK
550 %token   <operator>     OP_TK OSB_TK DOT_TK THROW_TK INSTANCEOF_TK
551 %type    <operator>     THIS_TK SUPER_TK RETURN_TK BREAK_TK CONTINUE_TK 
552 %type    <operator>     CASE_TK DEFAULT_TK TRY_TK CATCH_TK SYNCHRONIZED_TK
553 %type    <operator>     NEW_TK
554
555 %type    <node>         method_body 
556         
557 %type    <node>         literal INT_LIT_TK FP_LIT_TK BOOL_LIT_TK CHAR_LIT_TK
558                         STRING_LIT_TK NULL_TK VOID_TK
559
560 %type    <node>         IF_TK WHILE_TK FOR_TK
561
562 %type    <node>         formal_parameter_list formal_parameter
563                         method_declarator method_header
564
565 %type    <node>         primitive_type reference_type type 
566                         BOOLEAN_TK INTEGRAL_TK FP_TK
567
568 /* Added or modified JDK 1.1 rule types  */
569 %type    <node>         type_literals array_type_literal
570
571 %%
572 /* 19.2 Production from 2.3: The Syntactic Grammar  */
573 goal:
574         compilation_unit
575                 {}
576 ;
577
578 /* 19.3 Productions from 3: Lexical structure  */
579 literal:
580         INT_LIT_TK
581 |       FP_LIT_TK
582 |       BOOL_LIT_TK
583 |       CHAR_LIT_TK
584 |       STRING_LIT_TK
585 |       NULL_TK
586 ;
587
588 /* 19.4 Productions from 4: Types, Values and Variables  */
589 type:
590         primitive_type
591 |       reference_type
592 ;
593
594 primitive_type:
595         INTEGRAL_TK
596 |       FP_TK
597 |       BOOLEAN_TK
598 ;
599
600 reference_type:
601         class_or_interface_type
602 |       array_type
603 ;
604
605 class_or_interface_type:
606         name
607 ;
608
609 class_type:
610         class_or_interface_type /* Default rule */
611 ;
612
613 interface_type:
614          class_or_interface_type
615 ;
616
617 array_type:
618         primitive_type OSB_TK CSB_TK
619                 { 
620                   $$ = build_java_array_type ($1, -1);
621                   CLASS_LOADED_P ($$) = 1;
622                 }
623 |       name OSB_TK CSB_TK
624                 { $$ = build_unresolved_array_type ($1); }
625 |       array_type OSB_TK CSB_TK
626                 { $$ = build_unresolved_array_type ($1); }
627 |       primitive_type OSB_TK error
628                 {RULE ("']' expected"); RECOVER;}
629 |       array_type OSB_TK error
630                 {RULE ("']' expected"); RECOVER;}
631 ;
632
633 /* 19.5 Productions from 6: Names  */
634 name:
635         simple_name             /* Default rule */
636 |       qualified_name          /* Default rule */
637 ;
638
639 simple_name:
640         identifier              /* Default rule */
641 ;
642
643 qualified_name:
644         name DOT_TK identifier
645                 { $$ = make_qualified_name ($1, $3, $2.location); }
646 ;
647
648 identifier:
649         ID_TK
650 ;
651
652 /* 19.6: Production from 7: Packages  */
653 compilation_unit:
654                 {$$ = NULL;}
655 |       package_declaration
656 |       import_declarations
657 |       type_declarations
658 |       package_declaration import_declarations
659 |       package_declaration type_declarations
660 |       import_declarations type_declarations
661 |       package_declaration import_declarations type_declarations
662 ;
663
664 import_declarations:
665         import_declaration
666                 {
667                   $$ = NULL;
668                 }
669 |       import_declarations import_declaration
670                 {
671                   $$ = NULL;
672                 }
673 ;
674
675 type_declarations:
676         type_declaration
677 |       type_declarations type_declaration
678 ;
679
680 package_declaration:
681         PACKAGE_TK name SC_TK
682                 { 
683                   ctxp->package = EXPR_WFL_NODE ($2);
684                   package_list = tree_cons (ctxp->package, NULL, package_list);
685                 }
686 |       PACKAGE_TK error
687                 {yyerror ("Missing name"); RECOVER;}
688 |       PACKAGE_TK name error
689                 {yyerror ("';' expected"); RECOVER;}
690 ;
691
692 import_declaration:
693         single_type_import_declaration
694 |       type_import_on_demand_declaration
695 ;
696
697 single_type_import_declaration:
698         IMPORT_TK name SC_TK
699                 {
700                   tree name = EXPR_WFL_NODE ($2), node, last_name;
701                   int   i = IDENTIFIER_LENGTH (name)-1;
702                   const char *last = &IDENTIFIER_POINTER (name)[i];
703                   while (last != IDENTIFIER_POINTER (name))
704                     {
705                       if (last [0] == '.')
706                         break;
707                       last--;
708                     }
709                   last_name = get_identifier (++last);
710                   if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (last_name))
711                     {
712                       tree err = find_name_in_single_imports (last_name);
713                       if (err && err != name)
714                         parse_error_context
715                           ($2, "Ambiguous class: `%s' and `%s'",
716                            IDENTIFIER_POINTER (name), 
717                            IDENTIFIER_POINTER (err));
718                       else
719                         REGISTER_IMPORT ($2, last_name)
720                     }
721                   else
722                     REGISTER_IMPORT ($2, last_name);
723                 }
724 |       IMPORT_TK error
725                 {yyerror ("Missing name"); RECOVER;}
726 |       IMPORT_TK name error
727                 {yyerror ("';' expected"); RECOVER;}
728 ;
729
730 type_import_on_demand_declaration:
731         IMPORT_TK name DOT_TK MULT_TK SC_TK
732                 {
733                   tree name = EXPR_WFL_NODE ($2);
734                   /* Don't import java.lang.* twice. */
735                   if (name != java_lang_id)
736                     {
737                       tree node = build_tree_list ($2, NULL_TREE);
738                       read_import_dir ($2);
739                       TREE_CHAIN (node) = ctxp->import_demand_list;
740                       ctxp->import_demand_list = node;
741                     }
742                 }
743 |       IMPORT_TK name DOT_TK error
744                 {yyerror ("'*' expected"); RECOVER;}
745 |       IMPORT_TK name DOT_TK MULT_TK error
746                 {yyerror ("';' expected"); RECOVER;}
747 ;
748
749 type_declaration:
750         class_declaration
751                 { end_class_declaration (0); }
752 |       interface_declaration
753                 { end_class_declaration (0); }
754 |       SC_TK
755                 { $$ = NULL; }
756 |       error
757                 {
758                   YYERROR_NOW;
759                   yyerror ("Class or interface declaration expected");
760                 }
761 ;
762
763 /* 19.7 Shortened from the original:
764    modifiers: modifier | modifiers modifier
765    modifier: any of public...  */
766 modifiers:
767         MODIFIER_TK
768                 {
769                   $$ = (1 << $1);
770                 }
771 |       modifiers MODIFIER_TK
772                 {
773                   int acc = (1 << $2);
774                   if ($$ & acc)
775                     parse_error_context 
776                       (ctxp->modifier_ctx [$2], "Modifier `%s' declared twice",
777                        java_accstring_lookup (acc));
778                   else
779                     {
780                       $$ |= acc;
781                     }
782                 }
783 ;
784
785 /* 19.8.1 Production from $8.1: Class Declaration */
786 class_declaration:
787         modifiers CLASS_TK identifier super interfaces
788                 { create_class ($1, $3, $4, $5); }
789         class_body
790 |       CLASS_TK identifier super interfaces 
791                 { create_class (0, $2, $3, $4); }
792         class_body
793 |       modifiers CLASS_TK error
794                 {yyerror ("Missing class name"); RECOVER;}
795 |       CLASS_TK error
796                 {yyerror ("Missing class name"); RECOVER;}
797 |       CLASS_TK identifier error
798                 {
799                   if (!ctxp->class_err) yyerror ("'{' expected"); 
800                   DRECOVER(class1);
801                 }
802 |       modifiers CLASS_TK identifier error
803                 {if (!ctxp->class_err) yyerror ("'{' expected"); RECOVER;}
804 ;
805
806 super:
807                 { $$ = NULL; }
808 |       EXTENDS_TK class_type
809                 { $$ = $2; }
810 |       EXTENDS_TK class_type error
811                 {yyerror ("'{' expected"); ctxp->class_err=1;}
812 |       EXTENDS_TK error
813                 {yyerror ("Missing super class name"); ctxp->class_err=1;}
814 ;
815
816 interfaces:
817                 { $$ = NULL_TREE; }
818 |       IMPLEMENTS_TK interface_type_list
819                 { $$ = $2; }
820 |       IMPLEMENTS_TK error
821                 {
822                   ctxp->class_err=1;
823                   yyerror ("Missing interface name"); 
824                 }
825 ;
826
827 interface_type_list:
828         interface_type
829                 { 
830                   ctxp->interface_number = 1;
831                   $$ = build_tree_list ($1, NULL_TREE);
832                 }
833 |       interface_type_list C_TK interface_type
834                 { 
835                   ctxp->interface_number++;
836                   $$ = chainon ($1, build_tree_list ($3, NULL_TREE));
837                 }
838 |       interface_type_list C_TK error
839                 {yyerror ("Missing interface name"); RECOVER;}
840 ;
841
842 class_body:
843         OCB_TK CCB_TK
844                 { 
845                   /* Store the location of the `}' when doing xrefs */
846                   if (flag_emit_xref)
847                     DECL_END_SOURCE_LINE (GET_CPC ()) = 
848                       EXPR_WFL_ADD_COL ($2.location, 1);
849                   $$ = GET_CPC ();
850                 }
851 |       OCB_TK class_body_declarations CCB_TK
852                 { 
853                   /* Store the location of the `}' when doing xrefs */
854                   if (flag_emit_xref)
855                     DECL_END_SOURCE_LINE (GET_CPC ()) = 
856                       EXPR_WFL_ADD_COL ($3.location, 1);
857                   $$ = GET_CPC ();
858                 }
859 ;
860
861 class_body_declarations:
862         class_body_declaration
863 |       class_body_declarations class_body_declaration
864 ;
865
866 class_body_declaration:
867         class_member_declaration
868 |       static_initializer
869 |       constructor_declaration
870 |       block                   /* Added, JDK1.1, instance initializer */
871                 {
872                   TREE_CHAIN ($1) = CPC_INSTANCE_INITIALIZER_STMT (ctxp);
873                   SET_CPC_INSTANCE_INITIALIZER_STMT (ctxp, $1);
874                 }
875 ;
876
877 class_member_declaration:
878         field_declaration
879 |       field_declaration SC_TK
880                 { $$ = $1; }
881 |       method_declaration
882 |       class_declaration       /* Added, JDK1.1 inner classes */
883                 { end_class_declaration (1); }
884 |       interface_declaration   /* Added, JDK1.1 inner interfaces */
885                 { end_class_declaration (1); }
886 ;
887
888 /* 19.8.2 Productions from 8.3: Field Declarations  */
889 field_declaration:
890         type variable_declarators SC_TK
891                 { register_fields (0, $1, $2); }
892 |       modifiers type variable_declarators SC_TK
893                 {
894                   check_modifiers 
895                     ("Illegal modifier `%s' for field declaration",
896                      $1, FIELD_MODIFIERS);
897                   check_modifiers_consistency ($1);
898                   register_fields ($1, $2, $3);
899                 }
900 ;
901
902 variable_declarators:
903         /* Should we use build_decl_list () instead ? FIXME */
904         variable_declarator     /* Default rule */
905 |       variable_declarators C_TK variable_declarator
906                 { $$ = chainon ($1, $3); }
907 |       variable_declarators C_TK error
908                 {yyerror ("Missing term"); RECOVER;}
909 ;
910
911 variable_declarator:
912         variable_declarator_id
913                 { $$ = build_tree_list ($1, NULL_TREE); }
914 |       variable_declarator_id ASSIGN_TK variable_initializer
915                 { 
916                   if (java_error_count)
917                     $3 = NULL_TREE;
918                   $$ = build_tree_list 
919                     ($1, build_assignment ($2.token, $2.location, $1, $3));
920                 }
921 |       variable_declarator_id ASSIGN_TK error
922                 {
923                   yyerror ("Missing variable initializer");
924                   $$ = build_tree_list ($1, NULL_TREE);
925                   RECOVER;
926                 }
927 |       variable_declarator_id ASSIGN_TK variable_initializer error
928                 {
929                   yyerror ("';' expected");
930                   $$ = build_tree_list ($1, NULL_TREE);
931                   RECOVER;
932                 }
933 ;
934
935 variable_declarator_id:
936         identifier
937 |       variable_declarator_id OSB_TK CSB_TK
938                 { $$ = build_unresolved_array_type ($1); }
939 |       identifier error
940                 {yyerror ("Invalid declaration"); DRECOVER(vdi);}
941 |       variable_declarator_id OSB_TK error
942                 {yyerror ("']' expected"); DRECOVER(vdi);}
943 |       variable_declarator_id CSB_TK error
944                 {yyerror ("Unbalanced ']'"); DRECOVER(vdi);}
945 ;
946
947 variable_initializer:
948         expression
949 |       array_initializer
950 ;
951
952 /* 19.8.3 Productions from 8.4: Method Declarations  */
953 method_declaration:
954         method_header 
955                 {
956                   current_function_decl = $1;
957                   if (current_function_decl
958                       && TREE_CODE (current_function_decl) == FUNCTION_DECL)
959                     source_start_java_method (current_function_decl);
960                   else
961                     current_function_decl = NULL_TREE;
962                 }
963         method_body
964                 { finish_method_declaration ($3); }
965 |       method_header error
966                 {YYNOT_TWICE yyerror ("'{' expected"); RECOVER;}
967 ;
968
969 method_header:  
970         type method_declarator throws
971                 { $$ = method_header (0, $1, $2, $3); }
972 |       VOID_TK method_declarator throws
973                 { $$ = method_header (0, void_type_node, $2, $3); }
974 |       modifiers type method_declarator throws
975                 { $$ = method_header ($1, $2, $3, $4); }
976 |       modifiers VOID_TK method_declarator throws
977                 { $$ = method_header ($1, void_type_node, $3, $4); }
978 |       type error
979                 {
980                   yyerror ("Invalid method declaration, method name required");
981                   RECOVER;
982                 }
983 |       modifiers type error
984                 {RECOVER;}
985 |       VOID_TK error
986                 {yyerror ("Identifier expected"); RECOVER;}
987 |       modifiers VOID_TK error
988                 {yyerror ("Identifier expected"); RECOVER;}
989 |       modifiers error
990                 {
991                   yyerror ("Invalid method declaration, return type required");
992                   RECOVER;
993                 }
994 ;
995
996 method_declarator:
997         identifier OP_TK CP_TK
998                 { 
999                   ctxp->formal_parameter_number = 0;
1000                   $$ = method_declarator ($1, NULL_TREE);
1001                 }
1002 |       identifier OP_TK formal_parameter_list CP_TK
1003                 { $$ = method_declarator ($1, $3); }
1004 |       method_declarator OSB_TK CSB_TK
1005                 {
1006                   EXPR_WFL_LINECOL (wfl_operator) = $2.location;
1007                   TREE_PURPOSE ($1) = 
1008                     build_unresolved_array_type (TREE_PURPOSE ($1));
1009                   parse_warning_context 
1010                     (wfl_operator, 
1011                      "Discouraged form of returned type specification");
1012                 }
1013 |       identifier OP_TK error
1014                 {yyerror ("')' expected"); DRECOVER(method_declarator);}
1015 |       method_declarator OSB_TK error
1016                 {yyerror ("']' expected"); RECOVER;}
1017 ;
1018
1019 formal_parameter_list:
1020         formal_parameter
1021                 {
1022                   ctxp->formal_parameter_number = 1;
1023                 }
1024 |       formal_parameter_list C_TK formal_parameter
1025                 {
1026                   ctxp->formal_parameter_number += 1;
1027                   $$ = chainon ($1, $3);
1028                 }
1029 |       formal_parameter_list C_TK error
1030                 { yyerror ("Missing formal parameter term"); RECOVER; }
1031 ;
1032
1033 formal_parameter:
1034         type variable_declarator_id
1035                 {
1036                   $$ = build_tree_list ($2, $1);
1037                 }
1038 |       final type variable_declarator_id /* Added, JDK1.1 final parms */
1039                 { 
1040                   $$ = build_tree_list ($3, $2);
1041                   ARG_FINAL_P ($$) = 1;
1042                 }
1043 |       type error
1044                 {
1045                   yyerror ("Missing identifier"); RECOVER;
1046                   $$ = NULL_TREE;
1047                 }
1048 |       final type error
1049                 {
1050                   yyerror ("Missing identifier"); RECOVER;
1051                   $$ = NULL_TREE;
1052                 }
1053 ;
1054
1055 final:
1056         modifiers
1057                 {
1058                   check_modifiers ("Illegal modifier `%s'. Only `final' was expected here",
1059                                    $1, ACC_FINAL);
1060                   if ($1 != ACC_FINAL)
1061                     MODIFIER_WFL (FINAL_TK) = build_wfl_node (NULL_TREE);
1062                 }
1063 ;
1064
1065 throws:
1066                 { $$ = NULL_TREE; }
1067 |       THROWS_TK class_type_list
1068                 { $$ = $2; }
1069 |       THROWS_TK error
1070                 {yyerror ("Missing class type term"); RECOVER;}
1071 ;
1072
1073 class_type_list:
1074         class_type
1075                 { $$ = build_tree_list ($1, $1); }
1076 |       class_type_list C_TK class_type
1077                 { $$ = tree_cons ($3, $3, $1); }
1078 |       class_type_list C_TK error
1079                 {yyerror ("Missing class type term"); RECOVER;}
1080 ;
1081
1082 method_body:
1083         block
1084 |       block SC_TK
1085 |       SC_TK
1086                 { $$ = NULL_TREE; } /* Probably not the right thing to do. */
1087 ;
1088
1089 /* 19.8.4 Productions from 8.5: Static Initializers  */
1090 static_initializer:
1091         static block
1092                 {
1093                   TREE_CHAIN ($2) = CPC_STATIC_INITIALIZER_STMT (ctxp);
1094                   SET_CPC_STATIC_INITIALIZER_STMT (ctxp, $2);
1095                 }
1096 |       static block SC_TK      /* Shouldn't be here. FIXME */
1097                 {
1098                   TREE_CHAIN ($2) = CPC_STATIC_INITIALIZER_STMT (ctxp);
1099                   SET_CPC_STATIC_INITIALIZER_STMT (ctxp, $2);
1100                 }
1101 ;
1102
1103 static:                         /* Test lval.sub_token here */
1104         modifiers
1105                 {
1106                   check_modifiers ("Illegal modifier `%s' for static initializer", $1, ACC_STATIC);
1107                   /* Can't have a static initializer in an innerclass */
1108                   if ($1 | ACC_STATIC &&
1109                       GET_CPC_LIST () && !TOPLEVEL_CLASS_DECL_P (GET_CPC ()))
1110                     parse_error_context 
1111                       (MODIFIER_WFL (STATIC_TK),
1112                        "Can't define static initializer in class `%s'. Static initializer can only be defined in top-level classes",
1113                        IDENTIFIER_POINTER (DECL_NAME (GET_CPC ())));
1114                   SOURCE_FRONTEND_DEBUG (("Modifiers: %d", $1));
1115                 }
1116 ;
1117
1118 /* 19.8.5 Productions from 8.6: Constructor Declarations  */
1119 constructor_declaration:
1120         constructor_header
1121                 {
1122                   current_function_decl = $1;
1123                   source_start_java_method (current_function_decl);
1124                 }
1125         constructor_body
1126                 { finish_method_declaration ($3); }
1127 ;
1128
1129 constructor_header:
1130         constructor_declarator throws
1131                 { $$ = method_header (0, NULL_TREE, $1, $2); }
1132 |       modifiers constructor_declarator throws
1133                 { $$ = method_header ($1, NULL_TREE, $2, $3); }
1134 ;
1135
1136 constructor_declarator:
1137         simple_name OP_TK CP_TK
1138                 { 
1139                   ctxp->formal_parameter_number = 0;  
1140                   $$ = method_declarator ($1, NULL_TREE);
1141                 }
1142 |       simple_name OP_TK formal_parameter_list CP_TK
1143                 { $$ = method_declarator ($1, $3); }
1144 ;
1145
1146 constructor_body:
1147         /* Unlike regular method, we always need a complete (empty)
1148            body so we can safely perform all the required code
1149            addition (super invocation and field initialization) */
1150         block_begin constructor_block_end
1151                 { 
1152                   BLOCK_EXPR_BODY ($2) = empty_stmt_node;
1153                   $$ = $2;
1154                 }
1155 |       block_begin explicit_constructor_invocation constructor_block_end
1156                 { $$ = $3; }
1157 |       block_begin block_statements constructor_block_end
1158                 { $$ = $3; }
1159 |       block_begin explicit_constructor_invocation block_statements constructor_block_end
1160                 { $$ = $4; }
1161 ;
1162
1163 constructor_block_end:
1164         block_end
1165 |       block_end SC_TK
1166
1167 /* Error recovery for that rule moved down expression_statement: rule.  */
1168 explicit_constructor_invocation:
1169         this_or_super OP_TK CP_TK SC_TK
1170                 { 
1171                   $$ = build_method_invocation ($1, NULL_TREE); 
1172                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $$);
1173                   $$ = java_method_add_stmt (current_function_decl, $$);
1174                 }
1175 |       this_or_super OP_TK argument_list CP_TK SC_TK
1176                 { 
1177                   $$ = build_method_invocation ($1, $3); 
1178                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $$);
1179                   $$ = java_method_add_stmt (current_function_decl, $$);
1180                 }
1181         /* Added, JDK1.1 inner classes. Modified because the rule
1182            'primary' couldn't work.  */
1183 |       name DOT_TK SUPER_TK OP_TK argument_list CP_TK SC_TK
1184                 {$$ = parse_jdk1_1_error ("explicit constructor invocation"); }
1185 |       name DOT_TK SUPER_TK OP_TK CP_TK SC_TK
1186                 {$$ = parse_jdk1_1_error ("explicit constructor invocation"); }
1187 ;
1188
1189 this_or_super:                  /* Added, simplifies error diagnostics */
1190         THIS_TK
1191                 {
1192                   tree wfl = build_wfl_node (this_identifier_node);
1193                   EXPR_WFL_LINECOL (wfl) = $1.location;
1194                   $$ = wfl;
1195                 }
1196 |       SUPER_TK
1197                 {
1198                   tree wfl = build_wfl_node (super_identifier_node);
1199                   EXPR_WFL_LINECOL (wfl) = $1.location;
1200                   $$ = wfl;
1201                 }
1202 ;
1203
1204 /* 19.9 Productions from 9: Interfaces  */
1205 /* 19.9.1 Productions from 9.1: Interfaces Declarations  */
1206 interface_declaration:
1207         INTERFACE_TK identifier
1208                 { create_interface (0, $2, NULL_TREE); }
1209         interface_body
1210 |       modifiers INTERFACE_TK identifier
1211                 { create_interface ($1, $3, NULL_TREE); }
1212         interface_body
1213 |       INTERFACE_TK identifier extends_interfaces
1214                 { create_interface (0, $2, $3); }
1215         interface_body
1216 |       modifiers INTERFACE_TK identifier extends_interfaces
1217                 { create_interface ($1, $3, $4); }
1218         interface_body
1219 |       INTERFACE_TK identifier error
1220                 {yyerror ("'{' expected"); RECOVER;}
1221 |       modifiers INTERFACE_TK identifier error
1222                 {yyerror ("'{' expected"); RECOVER;}
1223 ;
1224
1225 extends_interfaces:
1226         EXTENDS_TK interface_type
1227                 { 
1228                   ctxp->interface_number = 1;
1229                   $$ = build_tree_list ($2, NULL_TREE);
1230                 }
1231 |       extends_interfaces C_TK interface_type
1232                 { 
1233                   ctxp->interface_number++;
1234                   $$ = chainon ($1, build_tree_list ($3, NULL_TREE));
1235                 }
1236 |       EXTENDS_TK error
1237                 {yyerror ("Invalid interface type"); RECOVER;}
1238 |       extends_interfaces C_TK error
1239                 {yyerror ("Missing term"); RECOVER;}
1240 ;
1241
1242 interface_body:
1243         OCB_TK CCB_TK
1244                 { $$ = NULL_TREE; }
1245 |       OCB_TK interface_member_declarations CCB_TK
1246                 { $$ = NULL_TREE; }
1247 ;
1248
1249 interface_member_declarations:
1250         interface_member_declaration
1251 |       interface_member_declarations interface_member_declaration
1252 ;
1253
1254 interface_member_declaration:
1255         constant_declaration
1256 |       abstract_method_declaration
1257 |       class_declaration       /* Added, JDK1.1 inner classes */
1258                 { end_class_declaration (1); }
1259 |       interface_declaration   /* Added, JDK1.1 inner interfaces */
1260                 { end_class_declaration (1); }
1261 ;
1262
1263 constant_declaration:
1264         field_declaration
1265 ;
1266
1267 abstract_method_declaration:
1268         method_header SC_TK
1269                 { 
1270                   check_abstract_method_header ($1);
1271                   current_function_decl = NULL_TREE; /* FIXME ? */
1272                 }
1273 |       method_header error
1274                 {yyerror ("';' expected"); RECOVER;}
1275 ;
1276
1277 /* 19.10 Productions from 10: Arrays  */
1278 array_initializer:
1279         OCB_TK CCB_TK
1280                 { $$ = build_new_array_init ($1.location, NULL_TREE); }
1281 |       OCB_TK variable_initializers CCB_TK
1282                 { $$ = build_new_array_init ($1.location, $2); }
1283 |       OCB_TK variable_initializers C_TK CCB_TK
1284                 { $$ = build_new_array_init ($1.location, $2); }
1285 ;
1286
1287 variable_initializers:
1288         variable_initializer
1289                 { 
1290                   $$ = tree_cons (maybe_build_array_element_wfl ($1), 
1291                                   $1, NULL_TREE);
1292                 }
1293 |       variable_initializers C_TK variable_initializer
1294                 {
1295                   $$ = tree_cons (maybe_build_array_element_wfl ($3), $3, $1);
1296                 }
1297 |       variable_initializers C_TK error
1298                 {yyerror ("Missing term"); RECOVER;}
1299 ;
1300
1301 /* 19.11 Production from 14: Blocks and Statements  */
1302 block:
1303         OCB_TK CCB_TK
1304                 { 
1305                   /* Store the location of the `}' when doing xrefs */
1306                   if (current_function_decl && flag_emit_xref)
1307                     DECL_END_SOURCE_LINE (current_function_decl) = 
1308                       EXPR_WFL_ADD_COL ($2.location, 1);
1309                   $$ = empty_stmt_node; 
1310                 }
1311 |       block_begin block_statements block_end
1312                 { $$ = $3; }
1313 ;
1314
1315 block_begin:
1316         OCB_TK
1317                 { enter_block (); }
1318 ;
1319
1320 block_end:
1321         CCB_TK
1322                 { 
1323                   maybe_absorb_scoping_blocks ();
1324                   /* Store the location of the `}' when doing xrefs */
1325                   if (current_function_decl && flag_emit_xref)
1326                     DECL_END_SOURCE_LINE (current_function_decl) = 
1327                       EXPR_WFL_ADD_COL ($1.location, 1);                  
1328                   $$ = exit_block ();
1329                 }
1330 ;
1331
1332 block_statements:
1333         block_statement
1334 |       block_statements block_statement
1335 ;
1336
1337 block_statement:
1338         local_variable_declaration_statement
1339 |       statement
1340                 { java_method_add_stmt (current_function_decl, $1); }
1341 |       class_declaration       /* Added, JDK1.1 local classes */
1342                 { 
1343                   LOCAL_CLASS_P (TREE_TYPE (GET_CPC ())) = 1;
1344                   end_class_declaration (1);
1345                 }
1346 ;
1347
1348 local_variable_declaration_statement:
1349         local_variable_declaration SC_TK /* Can't catch missing ';' here */
1350 ;
1351
1352 local_variable_declaration:
1353         type variable_declarators
1354                 { declare_local_variables (0, $1, $2); }
1355 |       final type variable_declarators /* Added, JDK1.1 final locals */
1356                 { declare_local_variables ($1, $2, $3); }
1357 ;
1358
1359 statement:
1360         statement_without_trailing_substatement
1361 |       labeled_statement
1362 |       if_then_statement
1363 |       if_then_else_statement
1364 |       while_statement
1365 |       for_statement
1366                 { $$ = exit_block (); }
1367 ;
1368
1369 statement_nsi:
1370         statement_without_trailing_substatement
1371 |       labeled_statement_nsi
1372 |       if_then_else_statement_nsi
1373 |       while_statement_nsi
1374 |       for_statement_nsi
1375                 { $$ = exit_block (); }
1376 ;
1377
1378 statement_without_trailing_substatement:
1379         block
1380 |       empty_statement
1381 |       expression_statement
1382 |       switch_statement
1383 |       do_statement
1384 |       break_statement
1385 |       continue_statement
1386 |       return_statement
1387 |       synchronized_statement
1388 |       throw_statement
1389 |       try_statement
1390 ;
1391
1392 empty_statement:
1393         SC_TK
1394                 { $$ = empty_stmt_node; }
1395 ;
1396
1397 label_decl:
1398         identifier REL_CL_TK
1399                 {
1400                   $$ = build_labeled_block (EXPR_WFL_LINECOL ($1), 
1401                                             EXPR_WFL_NODE ($1));
1402                   pushlevel (2);
1403                   push_labeled_block ($$);
1404                   PUSH_LABELED_BLOCK ($$);
1405                 }
1406 ;
1407
1408 labeled_statement:
1409         label_decl statement
1410                 { $$ = finish_labeled_statement ($1, $2); }
1411 |       identifier error
1412                 {yyerror ("':' expected"); RECOVER;}
1413 ;
1414
1415 labeled_statement_nsi:
1416         label_decl statement_nsi
1417                 { $$ = finish_labeled_statement ($1, $2); }
1418 ;
1419
1420 /* We concentrate here a bunch of error handling rules that we couldn't write
1421    earlier, because expression_statement catches a missing ';'.  */
1422 expression_statement:
1423         statement_expression SC_TK
1424                 {
1425                   /* We have a statement. Generate a WFL around it so
1426                      we can debug it */
1427                   $$ = build_expr_wfl ($1, input_filename, lineno, 0);
1428                   /* We know we have a statement, so set the debug
1429                      info to be eventually generate here. */
1430                   $$ = JAVA_MAYBE_GENERATE_DEBUG_INFO ($$);
1431                 }
1432 |       error SC_TK 
1433                 {
1434                   if (ctxp->prevent_ese != lineno)
1435                     yyerror ("Invalid expression statement");
1436                   DRECOVER (expr_stmt);
1437                 }
1438 |       error OCB_TK
1439                 {
1440                   if (ctxp->prevent_ese != lineno)
1441                     yyerror ("Invalid expression statement");
1442                   DRECOVER (expr_stmt);
1443                 }
1444 |       error CCB_TK
1445                 {
1446                   if (ctxp->prevent_ese != lineno)
1447                     yyerror ("Invalid expression statement");
1448                   DRECOVER (expr_stmt);
1449                 }
1450 |       this_or_super OP_TK error
1451                 {yyerror ("')' expected"); RECOVER;}
1452 |       this_or_super OP_TK CP_TK error
1453                 {
1454                   parse_ctor_invocation_error ();
1455                   RECOVER;
1456                 }
1457 |       this_or_super OP_TK argument_list error
1458                 {yyerror ("')' expected"); RECOVER;}
1459 |       this_or_super OP_TK argument_list CP_TK error
1460                 {
1461                   parse_ctor_invocation_error ();
1462                   RECOVER;
1463                 }
1464 |       name DOT_TK SUPER_TK error
1465                 {yyerror ("'(' expected"); RECOVER;}
1466 |       name DOT_TK SUPER_TK OP_TK error
1467                 {yyerror ("')' expected"); RECOVER;}
1468 |       name DOT_TK SUPER_TK OP_TK argument_list error
1469                 {yyerror ("')' expected"); RECOVER;}
1470 |       name DOT_TK SUPER_TK OP_TK argument_list CP_TK error
1471                 {yyerror ("';' expected"); RECOVER;}
1472 |       name DOT_TK SUPER_TK OP_TK CP_TK error
1473                 {yyerror ("';' expected"); RECOVER;}
1474 ;
1475
1476 statement_expression: 
1477         assignment
1478 |       pre_increment_expression
1479 |       pre_decrement_expression
1480 |       post_increment_expression
1481 |       post_decrement_expression
1482 |       method_invocation
1483 |       class_instance_creation_expression
1484 ;
1485
1486 if_then_statement:
1487         IF_TK OP_TK expression CP_TK statement
1488                 { 
1489                   $$ = build_if_else_statement ($2.location, $3, 
1490                                                 $5, NULL_TREE);
1491                 }
1492 |       IF_TK error
1493                 {yyerror ("'(' expected"); RECOVER;}
1494 |       IF_TK OP_TK error
1495                 {yyerror ("Missing term"); RECOVER;}
1496 |       IF_TK OP_TK expression error
1497                 {yyerror ("')' expected"); RECOVER;}
1498 ;
1499
1500 if_then_else_statement:
1501         IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement
1502                 { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
1503 ;
1504
1505 if_then_else_statement_nsi:
1506         IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement_nsi
1507                 { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
1508 ;
1509
1510 switch_statement:
1511         switch_expression
1512                 {
1513                   enter_block ();
1514                 }
1515         switch_block
1516                 { 
1517                   /* Make into "proper list" of COMPOUND_EXPRs.
1518                      I.e. make the last statment also have its own
1519                      COMPOUND_EXPR. */
1520                   maybe_absorb_scoping_blocks ();
1521                   TREE_OPERAND ($1, 1) = exit_block ();
1522                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $1);
1523                 }
1524 ;
1525
1526 switch_expression:
1527         SWITCH_TK OP_TK expression CP_TK
1528                 { 
1529                   $$ = build (SWITCH_EXPR, NULL_TREE, $3, NULL_TREE);
1530                   EXPR_WFL_LINECOL ($$) = $2.location;
1531                 }
1532 |       SWITCH_TK error
1533                 {yyerror ("'(' expected"); RECOVER;}
1534 |       SWITCH_TK OP_TK error
1535                 {yyerror ("Missing term or ')'"); DRECOVER(switch_statement);}
1536 |       SWITCH_TK OP_TK expression CP_TK error
1537                 {yyerror ("'{' expected"); RECOVER;}
1538 ;
1539
1540 /* Default assignment is there to avoid type node on switch_block
1541    node. */
1542
1543 switch_block:
1544         OCB_TK CCB_TK
1545                 { $$ = NULL_TREE; }
1546 |       OCB_TK switch_labels CCB_TK
1547                 { $$ = NULL_TREE; }
1548 |       OCB_TK switch_block_statement_groups CCB_TK
1549                 { $$ = NULL_TREE; }
1550 |       OCB_TK switch_block_statement_groups switch_labels CCB_TK
1551                 { $$ = NULL_TREE; }
1552 ;
1553
1554 switch_block_statement_groups: 
1555         switch_block_statement_group
1556 |       switch_block_statement_groups switch_block_statement_group
1557 ;
1558
1559 switch_block_statement_group:
1560         switch_labels block_statements
1561 ;
1562
1563 switch_labels:
1564         switch_label
1565 |       switch_labels switch_label
1566 ;
1567
1568 switch_label:
1569         CASE_TK constant_expression REL_CL_TK
1570                 { 
1571                   tree lab = build1 (CASE_EXPR, NULL_TREE, $2);
1572                   EXPR_WFL_LINECOL (lab) = $1.location;
1573                   java_method_add_stmt (current_function_decl, lab);
1574                 }
1575 |       DEFAULT_TK REL_CL_TK
1576                 { 
1577                   tree lab = build1 (DEFAULT_EXPR, NULL_TREE, NULL_TREE);
1578                   EXPR_WFL_LINECOL (lab) = $1.location;
1579                   java_method_add_stmt (current_function_decl, lab);
1580                 }
1581 |       CASE_TK error
1582                 {yyerror ("Missing or invalid constant expression"); RECOVER;}
1583 |       CASE_TK constant_expression error
1584                 {yyerror ("':' expected"); RECOVER;}
1585 |       DEFAULT_TK error
1586                 {yyerror ("':' expected"); RECOVER;}
1587 ;
1588
1589 while_expression:
1590         WHILE_TK OP_TK expression CP_TK
1591                 { 
1592                   tree body = build_loop_body ($2.location, $3, 0);
1593                   $$ = build_new_loop (body);
1594                 }
1595 ;
1596
1597 while_statement:
1598         while_expression statement
1599                 { $$ = finish_loop_body (0, NULL_TREE, $2, 0); }
1600 |       WHILE_TK error
1601                 {YYERROR_NOW; yyerror ("'(' expected"); RECOVER;}
1602 |       WHILE_TK OP_TK error
1603                 {yyerror ("Missing term and ')' expected"); RECOVER;}
1604 |       WHILE_TK OP_TK expression error
1605                 {yyerror ("')' expected"); RECOVER;}
1606 ;
1607
1608 while_statement_nsi:
1609         while_expression statement_nsi
1610                 { $$ = finish_loop_body (0, NULL_TREE, $2, 0); }
1611 ;
1612
1613 do_statement_begin:
1614         DO_TK
1615                 { 
1616                   tree body = build_loop_body (0, NULL_TREE, 1);
1617                   $$ = build_new_loop (body);
1618                 }
1619         /* Need error handing here. FIXME */
1620 ;
1621
1622 do_statement: 
1623         do_statement_begin statement WHILE_TK OP_TK expression CP_TK SC_TK
1624                 { $$ = finish_loop_body ($4.location, $5, $2, 1); }
1625 ;
1626
1627 for_statement:
1628         for_begin SC_TK expression SC_TK for_update CP_TK statement
1629                 { $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7); }
1630 |       for_begin SC_TK SC_TK for_update CP_TK statement
1631                 { 
1632                   $$ = finish_for_loop (0, NULL_TREE, $4, $6);
1633                   /* We have not condition, so we get rid of the EXIT_EXPR */
1634                   LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) = 
1635                     empty_stmt_node;
1636                 }
1637 |       for_begin SC_TK error
1638                 {yyerror ("Invalid control expression"); RECOVER;}
1639 |       for_begin SC_TK expression SC_TK error
1640                 {yyerror ("Invalid update expression"); RECOVER;}
1641 |       for_begin SC_TK SC_TK error
1642                 {yyerror ("Invalid update expression"); RECOVER;}
1643 ;
1644
1645 for_statement_nsi:
1646         for_begin SC_TK expression SC_TK for_update CP_TK statement_nsi
1647                 { $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7);}
1648 |       for_begin SC_TK SC_TK for_update CP_TK statement_nsi
1649                 { 
1650                   $$ = finish_for_loop (0, NULL_TREE, $4, $6);
1651                   /* We have not condition, so we get rid of the EXIT_EXPR */
1652                   LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) = 
1653                     empty_stmt_node;
1654                 }
1655 ;
1656
1657 for_header:
1658         FOR_TK OP_TK
1659                 { 
1660                   /* This scope defined for local variable that may be
1661                      defined within the scope of the for loop */
1662                   enter_block (); 
1663                 }
1664 |       FOR_TK error
1665                 {yyerror ("'(' expected"); DRECOVER(for_1);}
1666 |       FOR_TK OP_TK error
1667                 {yyerror ("Invalid init statement"); RECOVER;}
1668 ;
1669
1670 for_begin:
1671         for_header for_init
1672                 { 
1673                   /* We now declare the loop body. The loop is
1674                      declared as a for loop. */
1675                   tree body = build_loop_body (0, NULL_TREE, 0);
1676                   $$ =  build_new_loop (body);
1677                   FOR_LOOP_P ($$) = 1;
1678                   /* The loop is added to the current block the for
1679                      statement is defined within */
1680                   java_method_add_stmt (current_function_decl, $$);
1681                 }
1682 ;
1683 for_init:                       /* Can be empty */
1684                 { $$ = empty_stmt_node; }
1685 |       statement_expression_list
1686                 { 
1687                   /* Init statement recorded within the previously
1688                      defined block scope */
1689                   $$ = java_method_add_stmt (current_function_decl, $1);
1690                 }
1691 |       local_variable_declaration
1692                 { 
1693                   /* Local variable are recorded within the previously
1694                      defined block scope */
1695                   $$ = NULL_TREE;
1696                 }
1697 |       statement_expression_list error
1698                 {yyerror ("';' expected"); DRECOVER(for_init_1);}
1699 ;
1700
1701 for_update:                     /* Can be empty */
1702                 {$$ = empty_stmt_node;}
1703 |       statement_expression_list
1704                 { $$ = build_debugable_stmt (BUILD_LOCATION (), $1); }
1705 ;
1706
1707 statement_expression_list:
1708         statement_expression
1709                 { $$ = add_stmt_to_compound (NULL_TREE, NULL_TREE, $1); }
1710 |       statement_expression_list C_TK statement_expression
1711                 { $$ = add_stmt_to_compound ($1, NULL_TREE, $3); }
1712 |       statement_expression_list C_TK error
1713                 {yyerror ("Missing term"); RECOVER;}
1714 ;
1715
1716 break_statement:
1717         BREAK_TK SC_TK
1718                 { $$ = build_bc_statement ($1.location, 1, NULL_TREE); }
1719 |       BREAK_TK identifier SC_TK
1720                 { $$ = build_bc_statement ($1.location, 1, $2); }
1721 |       BREAK_TK error
1722                 {yyerror ("Missing term"); RECOVER;}
1723 |       BREAK_TK identifier error
1724                 {yyerror ("';' expected"); RECOVER;}
1725 ;
1726
1727 continue_statement:
1728         CONTINUE_TK SC_TK
1729                 { $$ = build_bc_statement ($1.location, 0, NULL_TREE); }
1730 |       CONTINUE_TK identifier SC_TK
1731                 { $$ = build_bc_statement ($1.location, 0, $2); }
1732 |       CONTINUE_TK error
1733                 {yyerror ("Missing term"); RECOVER;}
1734 |       CONTINUE_TK identifier error
1735                 {yyerror ("';' expected"); RECOVER;}
1736 ;
1737
1738 return_statement:
1739         RETURN_TK SC_TK
1740                 { $$ = build_return ($1.location, NULL_TREE); }
1741 |       RETURN_TK expression SC_TK
1742                 { $$ = build_return ($1.location, $2); }
1743 |       RETURN_TK error
1744                 {yyerror ("Missing term"); RECOVER;}
1745 |       RETURN_TK expression error
1746                 {yyerror ("';' expected"); RECOVER;}
1747 ;
1748
1749 throw_statement:
1750         THROW_TK expression SC_TK
1751                 { 
1752                   $$ = build1 (THROW_EXPR, NULL_TREE, $2);
1753                   EXPR_WFL_LINECOL ($$) = $1.location;
1754                 }
1755 |       THROW_TK error
1756                 {yyerror ("Missing term"); RECOVER;}
1757 |       THROW_TK expression error
1758                 {yyerror ("';' expected"); RECOVER;}
1759 ;
1760
1761 synchronized_statement:
1762         synchronized OP_TK expression CP_TK block
1763                 { 
1764                   $$ = build (SYNCHRONIZED_EXPR, NULL_TREE, $3, $5);
1765                   EXPR_WFL_LINECOL ($$) = 
1766                     EXPR_WFL_LINECOL (MODIFIER_WFL (SYNCHRONIZED_TK));
1767                 }
1768 |       synchronized OP_TK expression CP_TK error
1769                 {yyerror ("'{' expected"); RECOVER;}
1770 |       synchronized error
1771                 {yyerror ("'(' expected"); RECOVER;}
1772 |       synchronized OP_TK error CP_TK
1773                 {yyerror ("Missing term"); RECOVER;}
1774 |       synchronized OP_TK error
1775                 {yyerror ("Missing term"); RECOVER;}
1776 ;
1777
1778 synchronized:
1779         modifiers
1780                 {
1781                   check_modifiers (
1782              "Illegal modifier `%s'. Only `synchronized' was expected here",
1783                                    $1, ACC_SYNCHRONIZED);
1784                   if ($1 != ACC_SYNCHRONIZED)
1785                     MODIFIER_WFL (SYNCHRONIZED_TK) = 
1786                       build_wfl_node (NULL_TREE);
1787                 }
1788 ;
1789
1790 try_statement:
1791         TRY_TK block catches
1792                 { $$ = build_try_statement ($1.location, $2, $3); }
1793 |       TRY_TK block finally
1794                 { $$ = build_try_finally_statement ($1.location, $2, $3); }
1795 |       TRY_TK block catches finally
1796                 { $$ = build_try_finally_statement 
1797                     ($1.location, build_try_statement ($1.location,
1798                                                        $2, $3), $4);
1799                 }
1800 |       TRY_TK error
1801                 {yyerror ("'{' expected"); DRECOVER (try_statement);}
1802 ;
1803
1804 catches:
1805         catch_clause
1806 |       catches catch_clause
1807                 { 
1808                   TREE_CHAIN ($2) = $1;
1809                   $$ = $2;
1810                 }
1811 ;
1812
1813 catch_clause:
1814         catch_clause_parameter block
1815                 { 
1816                   java_method_add_stmt (current_function_decl, $2);
1817                   exit_block ();
1818                   $$ = $1;
1819                 }
1820
1821 catch_clause_parameter:
1822         CATCH_TK OP_TK formal_parameter CP_TK
1823                 { 
1824                   /* We add a block to define a scope for
1825                      formal_parameter (CCBP). The formal parameter is
1826                      declared initialized by the appropriate function
1827                      call */
1828                   tree ccpb = enter_block ();
1829                   tree init = build_assignment (ASSIGN_TK, $2.location, 
1830                                                 TREE_PURPOSE ($3), 
1831                                                 soft_exceptioninfo_call_node);
1832                   declare_local_variables (0, TREE_VALUE ($3),
1833                                            build_tree_list (TREE_PURPOSE ($3),
1834                                                             init));
1835                   $$ = build1 (CATCH_EXPR, NULL_TREE, ccpb);
1836                   EXPR_WFL_LINECOL ($$) = $1.location;
1837                 }
1838 |       CATCH_TK error
1839                 {yyerror ("'(' expected"); RECOVER; $$ = NULL_TREE;}
1840 |       CATCH_TK OP_TK error 
1841                 {
1842                   yyerror ("Missing term or ')' expected"); 
1843                   RECOVER; $$ = NULL_TREE;
1844                 }
1845 |       CATCH_TK OP_TK error CP_TK /* That's for () */
1846                 {yyerror ("Missing term"); RECOVER; $$ = NULL_TREE;}
1847 ;
1848
1849 finally:
1850         FINALLY_TK block
1851                 { $$ = $2; }
1852 |       FINALLY_TK error
1853                 {yyerror ("'{' expected"); RECOVER; }
1854 ;
1855
1856 /* 19.12 Production from 15: Expressions  */
1857 primary:
1858         primary_no_new_array
1859 |       array_creation_expression
1860 ;
1861
1862 primary_no_new_array:
1863         literal
1864 |       THIS_TK
1865                 { $$ = build_this ($1.location); }
1866 |       OP_TK expression CP_TK
1867                 {$$ = $2;}
1868 |       class_instance_creation_expression
1869 |       field_access
1870 |       method_invocation
1871 |       array_access
1872 |       type_literals
1873         /* Added, JDK1.1 inner classes. Documentation is wrong
1874            refering to a 'ClassName' (class_name) rule that doesn't
1875            exist. Used name: instead.  */
1876 |       name DOT_TK THIS_TK
1877                 { 
1878                   tree wfl = build_wfl_node (this_identifier_node);
1879                   $$ = make_qualified_primary ($1, wfl, EXPR_WFL_LINECOL ($1));
1880                 }
1881 |       OP_TK expression error 
1882                 {yyerror ("')' expected"); RECOVER;}
1883 |       name DOT_TK error
1884                 {yyerror ("'class' or 'this' expected" ); RECOVER;}
1885 |       primitive_type DOT_TK error
1886                 {yyerror ("'class' expected" ); RECOVER;}
1887 |       VOID_TK DOT_TK error
1888                 {yyerror ("'class' expected" ); RECOVER;}
1889 ;
1890
1891 /* Added, JDK1.1 type literals. We can't use `type' directly, so we
1892    broke the rule down a bit. */
1893
1894 array_type_literal:
1895         primitive_type OSB_TK CSB_TK
1896                 { 
1897                   $$ = build_java_array_type ($1, -1);
1898                   CLASS_LOADED_P ($$) = 1;
1899                 }
1900 |       name OSB_TK CSB_TK
1901                 { $$ = build_unresolved_array_type ($1); }
1902 /* This triggers two reduce/reduce conflict between array_type_literal and
1903    dims. FIXME.
1904 |       array_type OSB_TK CSB_TK
1905                 { $$ = build_unresolved_array_type ($1); }
1906 */
1907 ;
1908
1909 type_literals:
1910         name DOT_TK CLASS_TK
1911                 { $$ = build_incomplete_class_ref ($2.location, $1); }
1912 |       array_type_literal DOT_TK CLASS_TK
1913                 { $$ = build_incomplete_class_ref ($2.location, $1); }
1914 |       primitive_type DOT_TK CLASS_TK
1915                 { $$ = build_class_ref ($1); }
1916 |       VOID_TK DOT_TK CLASS_TK
1917                 { $$ = build_class_ref (void_type_node); }
1918 ;
1919
1920 class_instance_creation_expression:
1921         NEW_TK class_type OP_TK argument_list CP_TK
1922                 { $$ = build_new_invocation ($2, $4); }
1923 |       NEW_TK class_type OP_TK CP_TK
1924                 { $$ = build_new_invocation ($2, NULL_TREE); }
1925 |       anonymous_class_creation
1926         /* Added, JDK1.1 inner classes, modified to use name or
1927            primary instead of primary solely which couldn't work in
1928            all situations.  */
1929 |       something_dot_new identifier OP_TK CP_TK
1930                 { 
1931                   tree ctor = build_new_invocation ($2, NULL_TREE);
1932                   $$ = make_qualified_primary ($1, ctor, 
1933                                                EXPR_WFL_LINECOL ($1));
1934                 }
1935 |       something_dot_new identifier OP_TK CP_TK class_body
1936 |       something_dot_new identifier OP_TK argument_list CP_TK
1937                 { 
1938                   tree ctor = build_new_invocation ($2, $4);
1939                   $$ = make_qualified_primary ($1, ctor, 
1940                                                EXPR_WFL_LINECOL ($1));
1941                 }
1942 |       something_dot_new identifier OP_TK argument_list CP_TK class_body
1943 |       NEW_TK error SC_TK 
1944                 {yyerror ("'(' expected"); DRECOVER(new_1);}
1945 |       NEW_TK class_type error
1946                 {yyerror ("'(' expected"); RECOVER;}
1947 |       NEW_TK class_type OP_TK error
1948                 {yyerror ("')' or term expected"); RECOVER;}
1949 |       NEW_TK class_type OP_TK argument_list error
1950                 {yyerror ("')' expected"); RECOVER;}
1951 |       something_dot_new error
1952                 {YYERROR_NOW; yyerror ("Identifier expected"); RECOVER;}
1953 |       something_dot_new identifier error
1954                 {yyerror ("'(' expected"); RECOVER;}
1955 ;
1956
1957 /* Created after JDK1.1 rules originally added to
1958    class_instance_creation_expression, but modified to use
1959    'class_type' instead of 'TypeName' (type_name) which is mentionned
1960    in the documentation but doesn't exist. */
1961
1962 anonymous_class_creation:
1963         NEW_TK class_type OP_TK argument_list CP_TK 
1964                 { create_anonymous_class ($1.location, $2); }
1965         class_body
1966                 { 
1967                   tree id = build_wfl_node (DECL_NAME (GET_CPC ()));
1968                   EXPR_WFL_LINECOL (id) = EXPR_WFL_LINECOL ($2);
1969
1970                   end_class_declaration (1);
1971
1972                   /* Now we can craft the new expression */
1973                   $$ = build_new_invocation (id, $4);
1974
1975                   /* Note that we can't possibly be here if
1976                      `class_type' is an interface (in which case the
1977                      anonymous class extends Object and implements
1978                      `class_type', hence its constructor can't have
1979                      arguments.) */
1980
1981                   /* Otherwise, the innerclass must feature a
1982                      constructor matching `argument_list'. Anonymous
1983                      classes are a bit special: it's impossible to
1984                      define constructor for them, hence constructors
1985                      must be generated following the hints provided by
1986                      the `new' expression. Whether a super constructor
1987                      of that nature exists or not is to be verified
1988                      later on in verify_constructor_super. 
1989
1990                      It's during the expansion of a `new' statement
1991                      refering to an anonymous class that a ctor will
1992                      be generated for the anonymous class, with the
1993                      right arguments. */
1994
1995                 }
1996 |       NEW_TK class_type OP_TK CP_TK 
1997                 { create_anonymous_class ($1.location, $2); }
1998         class_body         
1999                 { 
2000                   tree id = build_wfl_node (DECL_NAME (GET_CPC ()));
2001                   EXPR_WFL_LINECOL (id) = EXPR_WFL_LINECOL ($2);
2002
2003                   end_class_declaration (1);
2004
2005                   /* Now we can craft the new expression. The
2006                      statement doesn't need to be remember so that a
2007                      constructor can be generated, since its signature
2008                      is already known. */
2009                   $$ = build_new_invocation (id, NULL_TREE);
2010                 }
2011 ;
2012
2013 something_dot_new:              /* Added, not part of the specs. */
2014         name DOT_TK NEW_TK
2015                 { $$ = $1; }
2016 |       primary DOT_TK NEW_TK
2017                 { $$ = $1; }
2018 ;
2019
2020 argument_list:
2021         expression
2022                 { 
2023                   $$ = tree_cons (NULL_TREE, $1, NULL_TREE);
2024                   ctxp->formal_parameter_number = 1; 
2025                 }
2026 |       argument_list C_TK expression
2027                 {
2028                   ctxp->formal_parameter_number += 1;
2029                   $$ = tree_cons (NULL_TREE, $3, $1);
2030                 }
2031 |       argument_list C_TK error
2032                 {yyerror ("Missing term"); RECOVER;}
2033 ;
2034
2035 array_creation_expression:
2036         NEW_TK primitive_type dim_exprs
2037                 { $$ = build_newarray_node ($2, $3, 0); }
2038 |       NEW_TK class_or_interface_type dim_exprs
2039                 { $$ = build_newarray_node ($2, $3, 0); }
2040 |       NEW_TK primitive_type dim_exprs dims
2041                 { $$ = build_newarray_node ($2, $3, CURRENT_OSB (ctxp));}
2042 |       NEW_TK class_or_interface_type dim_exprs dims
2043                 { $$ = build_newarray_node ($2, $3, CURRENT_OSB (ctxp));}
2044         /* Added, JDK1.1 anonymous array. Initial documentation rule
2045            modified */
2046 |       NEW_TK class_or_interface_type dims array_initializer
2047                 {
2048                   char *sig;
2049                   while (CURRENT_OSB (ctxp)--)
2050                     obstack_1grow (&temporary_obstack, '[');
2051                   sig = obstack_finish (&temporary_obstack);
2052                   $$ = build (NEW_ANONYMOUS_ARRAY_EXPR, NULL_TREE,
2053                               $2, get_identifier (sig), $4);
2054                 }
2055 |       NEW_TK primitive_type dims array_initializer
2056                 { 
2057                   tree type = $2;
2058                   while (CURRENT_OSB (ctxp)--)
2059                     type = build_java_array_type (type, -1);
2060                   $$ = build (NEW_ANONYMOUS_ARRAY_EXPR, NULL_TREE, 
2061                               build_pointer_type (type), NULL_TREE, $4);
2062                 }
2063 |       NEW_TK error CSB_TK
2064                 {yyerror ("'[' expected"); DRECOVER ("]");}
2065 |       NEW_TK error OSB_TK
2066                 {yyerror ("']' expected"); RECOVER;}
2067 ;
2068
2069 dim_exprs:
2070         dim_expr
2071                 { $$ = build_tree_list (NULL_TREE, $1); }
2072 |       dim_exprs dim_expr
2073                 { $$ = tree_cons (NULL_TREE, $2, $$); }
2074 ;
2075
2076 dim_expr:
2077         OSB_TK expression CSB_TK
2078                 { 
2079                   EXPR_WFL_LINECOL ($2) = $1.location;
2080                   $$ = $2;
2081                 }
2082 |       OSB_TK expression error
2083                 {yyerror ("']' expected"); RECOVER;}
2084 |       OSB_TK error
2085                 {
2086                   yyerror ("Missing term");
2087                   yyerror ("']' expected");
2088                   RECOVER;
2089                 }
2090 ;
2091
2092 dims:                           
2093         OSB_TK CSB_TK
2094                 { 
2095                   int allocate = 0;
2096                   /* If not initialized, allocate memory for the osb
2097                      numbers stack */
2098                   if (!ctxp->osb_limit)
2099                     {
2100                       allocate = ctxp->osb_limit = 32;
2101                       ctxp->osb_depth = -1;
2102                     }
2103                   /* If capacity overflown, reallocate a bigger chunk */
2104                   else if (ctxp->osb_depth+1 == ctxp->osb_limit)
2105                     allocate = ctxp->osb_limit << 1;
2106                   
2107                   if (allocate)
2108                     {
2109                       allocate *= sizeof (int);
2110                       if (ctxp->osb_number)
2111                         ctxp->osb_number = (int *)xrealloc (ctxp->osb_number,
2112                                                             allocate);
2113                       else
2114                         ctxp->osb_number = (int *)xmalloc (allocate);
2115                     }
2116                   ctxp->osb_depth++;
2117                   CURRENT_OSB (ctxp) = 1;
2118                 }
2119 |       dims OSB_TK CSB_TK
2120                 { CURRENT_OSB (ctxp)++; }
2121 |       dims OSB_TK error
2122                 { yyerror ("']' expected"); RECOVER;}
2123 ;
2124
2125 field_access:
2126         primary DOT_TK identifier
2127                 { $$ = make_qualified_primary ($1, $3, $2.location); }
2128                 /*  FIXME - REWRITE TO: 
2129                 { $$ = build_binop (COMPONENT_REF, $2.location, $1, $3); } */
2130 |       SUPER_TK DOT_TK identifier
2131                 {
2132                   tree super_wfl = 
2133                     build_wfl_node (super_identifier_node);
2134                   EXPR_WFL_LINECOL (super_wfl) = $1.location;
2135                   $$ = make_qualified_name (super_wfl, $3, $2.location);
2136                 }
2137 |       SUPER_TK error
2138                 {yyerror ("Field expected"); DRECOVER (super_field_acces);}
2139 ;
2140
2141 method_invocation:
2142         name OP_TK CP_TK
2143                 { $$ = build_method_invocation ($1, NULL_TREE); }
2144 |       name OP_TK argument_list CP_TK
2145                 { $$ = build_method_invocation ($1, $3); }
2146 |       primary DOT_TK identifier OP_TK CP_TK
2147                 { 
2148                   if (TREE_CODE ($1) == THIS_EXPR)
2149                     $$ = build_this_super_qualified_invocation 
2150                       (1, $3, NULL_TREE, 0, $2.location);
2151                   else
2152                     {
2153                       tree invok = build_method_invocation ($3, NULL_TREE);
2154                       $$ = make_qualified_primary ($1, invok, $2.location);
2155                     }
2156                 }
2157 |       primary DOT_TK identifier OP_TK argument_list CP_TK
2158                 { 
2159                   if (TREE_CODE ($1) == THIS_EXPR)
2160                     $$ = build_this_super_qualified_invocation 
2161                       (1, $3, $5, 0, $2.location);
2162                   else
2163                     {
2164                       tree invok = build_method_invocation ($3, $5);
2165                       $$ = make_qualified_primary ($1, invok, $2.location);
2166                     }
2167                 }
2168 |       SUPER_TK DOT_TK identifier OP_TK CP_TK
2169                 { 
2170                   $$ = build_this_super_qualified_invocation 
2171                     (0, $3, NULL_TREE, $1.location, $2.location);
2172                 }
2173 |       SUPER_TK DOT_TK identifier OP_TK argument_list CP_TK
2174                 {
2175                   $$ = build_this_super_qualified_invocation 
2176                     (0, $3, $5, $1.location, $2.location);
2177                 }
2178         /* Screws up thing. I let it here until I'm convinced it can
2179            be removed. FIXME
2180 |       primary DOT_TK error
2181                 {yyerror ("'(' expected"); DRECOVER(bad);} */
2182 |       SUPER_TK DOT_TK error CP_TK
2183                 { yyerror ("'(' expected"); DRECOVER (method_invocation); }
2184 |       SUPER_TK DOT_TK error DOT_TK
2185                 { yyerror ("'(' expected"); DRECOVER (method_invocation); }
2186 ;
2187
2188 array_access:
2189         name OSB_TK expression CSB_TK
2190                 { $$ = build_array_ref ($2.location, $1, $3); }
2191 |       primary_no_new_array OSB_TK expression CSB_TK
2192                 { $$ = build_array_ref ($2.location, $1, $3); }
2193 |       name OSB_TK error
2194                 {
2195                   yyerror ("Missing term and ']' expected");
2196                   DRECOVER(array_access);
2197                 }
2198 |       name OSB_TK expression error
2199                 {
2200                   yyerror ("']' expected");
2201                   DRECOVER(array_access);
2202                 }
2203 |       primary_no_new_array OSB_TK error
2204                 {
2205                   yyerror ("Missing term and ']' expected");
2206                   DRECOVER(array_access);
2207                 }
2208 |       primary_no_new_array OSB_TK expression error
2209                 {
2210                   yyerror ("']' expected");
2211                   DRECOVER(array_access);
2212                 }
2213 ;
2214
2215 postfix_expression:
2216         primary
2217 |       name
2218 |       post_increment_expression
2219 |       post_decrement_expression
2220 ;
2221
2222 post_increment_expression:
2223         postfix_expression INCR_TK
2224                 { $$ = build_incdec ($2.token, $2.location, $1, 1); }
2225 ;
2226
2227 post_decrement_expression:
2228         postfix_expression DECR_TK
2229                 { $$ = build_incdec ($2.token, $2.location, $1, 1); }
2230 ;
2231
2232 unary_expression:
2233         pre_increment_expression
2234 |       pre_decrement_expression
2235 |       PLUS_TK unary_expression
2236                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2237 |       MINUS_TK unary_expression
2238                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2239 |       unary_expression_not_plus_minus
2240 |       PLUS_TK error
2241                 {yyerror ("Missing term"); RECOVER}
2242 |       MINUS_TK error
2243                 {yyerror ("Missing term"); RECOVER}
2244 ;
2245
2246 pre_increment_expression:
2247         INCR_TK unary_expression
2248                 {$$ = build_incdec ($1.token, $1.location, $2, 0); }
2249 |       INCR_TK error
2250                 {yyerror ("Missing term"); RECOVER}
2251 ;
2252
2253 pre_decrement_expression:
2254         DECR_TK unary_expression
2255                 {$$ = build_incdec ($1.token, $1.location, $2, 0); }
2256 |       DECR_TK error
2257                 {yyerror ("Missing term"); RECOVER}
2258 ;
2259
2260 unary_expression_not_plus_minus:
2261         postfix_expression
2262 |       NOT_TK unary_expression
2263                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2264 |       NEG_TK unary_expression
2265                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2266 |       cast_expression
2267 |       NOT_TK error
2268                 {yyerror ("Missing term"); RECOVER}
2269 |       NEG_TK error
2270                 {yyerror ("Missing term"); RECOVER}
2271 ;
2272
2273 cast_expression:                /* Error handling here is potentially weak */
2274         OP_TK primitive_type dims CP_TK unary_expression
2275                 { 
2276                   tree type = $2;
2277                   while (CURRENT_OSB (ctxp)--)
2278                     type = build_java_array_type (type, -1);
2279                   ctxp->osb_depth--;
2280                   $$ = build_cast ($1.location, type, $5); 
2281                 }
2282 |       OP_TK primitive_type CP_TK unary_expression
2283                 { $$ = build_cast ($1.location, $2, $4); }
2284 |       OP_TK expression CP_TK unary_expression_not_plus_minus
2285                 { $$ = build_cast ($1.location, $2, $4); }
2286 |       OP_TK name dims CP_TK unary_expression_not_plus_minus
2287                 { 
2288                   const char *ptr;
2289                   while (CURRENT_OSB (ctxp)--)
2290                     obstack_1grow (&temporary_obstack, '[');
2291                   ctxp->osb_depth--;
2292                   obstack_grow0 (&temporary_obstack, 
2293                                  IDENTIFIER_POINTER (EXPR_WFL_NODE ($2)),
2294                                  IDENTIFIER_LENGTH (EXPR_WFL_NODE ($2)));
2295                   ptr = obstack_finish (&temporary_obstack);
2296                   EXPR_WFL_NODE ($2) = get_identifier (ptr);
2297                   $$ = build_cast ($1.location, $2, $5);
2298                 }
2299 |       OP_TK primitive_type OSB_TK error
2300                 {yyerror ("']' expected, invalid type expression");}
2301 |       OP_TK error
2302                 {
2303                   if (ctxp->prevent_ese != lineno)
2304                     yyerror ("Invalid type expression"); RECOVER;
2305                   RECOVER;
2306                 }
2307 |       OP_TK primitive_type dims CP_TK error
2308                 {yyerror ("Missing term"); RECOVER;}
2309 |       OP_TK primitive_type CP_TK error
2310                 {yyerror ("Missing term"); RECOVER;}
2311 |       OP_TK name dims CP_TK error
2312                 {yyerror ("Missing term"); RECOVER;}
2313 ;
2314
2315 multiplicative_expression:
2316         unary_expression
2317 |       multiplicative_expression MULT_TK unary_expression
2318                 { 
2319                   $$ = build_binop (BINOP_LOOKUP ($2.token), 
2320                                     $2.location, $1, $3);
2321                 }
2322 |       multiplicative_expression DIV_TK unary_expression
2323                 {
2324                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2325                                     $1, $3); 
2326                 }
2327 |       multiplicative_expression REM_TK unary_expression
2328                 {
2329                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2330                                     $1, $3); 
2331                 }
2332 |       multiplicative_expression MULT_TK error
2333                 {yyerror ("Missing term"); RECOVER;}
2334 |       multiplicative_expression DIV_TK error
2335                 {yyerror ("Missing term"); RECOVER;}
2336 |       multiplicative_expression REM_TK error
2337                 {yyerror ("Missing term"); RECOVER;}
2338 ;
2339
2340 additive_expression:
2341         multiplicative_expression
2342 |       additive_expression PLUS_TK multiplicative_expression
2343                 {
2344                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2345                                     $1, $3); 
2346                 }
2347 |       additive_expression MINUS_TK multiplicative_expression
2348                 {
2349                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2350                                     $1, $3); 
2351                 }
2352 |       additive_expression PLUS_TK error
2353                 {yyerror ("Missing term"); RECOVER;}
2354 |       additive_expression MINUS_TK error
2355                 {yyerror ("Missing term"); RECOVER;}
2356 ;
2357
2358 shift_expression:
2359         additive_expression
2360 |       shift_expression LS_TK additive_expression
2361                 {
2362                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2363                                     $1, $3); 
2364                 }
2365 |       shift_expression SRS_TK additive_expression
2366                 {
2367                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2368                                     $1, $3); 
2369                 }
2370 |       shift_expression ZRS_TK additive_expression
2371                 {
2372                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2373                                     $1, $3); 
2374                 }
2375 |       shift_expression LS_TK error
2376                 {yyerror ("Missing term"); RECOVER;}
2377 |       shift_expression SRS_TK error
2378                 {yyerror ("Missing term"); RECOVER;}
2379 |       shift_expression ZRS_TK error
2380                 {yyerror ("Missing term"); RECOVER;}
2381 ;
2382
2383 relational_expression:
2384         shift_expression
2385 |       relational_expression LT_TK shift_expression
2386                 {
2387                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2388                                     $1, $3); 
2389                 }
2390 |       relational_expression GT_TK shift_expression
2391                 {
2392                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2393                                     $1, $3); 
2394                 }
2395 |       relational_expression LTE_TK shift_expression
2396                 {
2397                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2398                                     $1, $3); 
2399                 }
2400 |       relational_expression GTE_TK shift_expression
2401                 {
2402                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2403                                     $1, $3); 
2404                 }
2405 |       relational_expression INSTANCEOF_TK reference_type
2406                 { $$ = build_binop (INSTANCEOF_EXPR, $2.location, $1, $3); }
2407 |       relational_expression LT_TK error
2408                 {yyerror ("Missing term"); RECOVER;}
2409 |       relational_expression GT_TK error
2410                 {yyerror ("Missing term"); RECOVER;}
2411 |       relational_expression LTE_TK error
2412                 {yyerror ("Missing term"); RECOVER;}
2413 |       relational_expression GTE_TK error
2414                 {yyerror ("Missing term"); RECOVER;}
2415 |       relational_expression INSTANCEOF_TK error
2416                 {yyerror ("Invalid reference type"); RECOVER;}
2417 ;
2418
2419 equality_expression:
2420         relational_expression
2421 |       equality_expression EQ_TK relational_expression
2422                 {
2423                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2424                                     $1, $3); 
2425                 }
2426 |       equality_expression NEQ_TK relational_expression
2427                 {
2428                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2429                                     $1, $3); 
2430                 }
2431 |       equality_expression EQ_TK error
2432                 {yyerror ("Missing term"); RECOVER;}
2433 |       equality_expression NEQ_TK error
2434                 {yyerror ("Missing term"); RECOVER;}
2435 ;
2436
2437 and_expression:
2438         equality_expression
2439 |       and_expression AND_TK equality_expression
2440                 {
2441                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2442                                     $1, $3); 
2443                 }
2444 |       and_expression AND_TK error
2445                 {yyerror ("Missing term"); RECOVER;}
2446 ;
2447
2448 exclusive_or_expression:
2449         and_expression
2450 |       exclusive_or_expression XOR_TK and_expression
2451                 {
2452                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2453                                     $1, $3); 
2454                 }
2455 |       exclusive_or_expression XOR_TK error
2456                 {yyerror ("Missing term"); RECOVER;}
2457 ;
2458
2459 inclusive_or_expression:
2460         exclusive_or_expression
2461 |       inclusive_or_expression OR_TK exclusive_or_expression
2462                 {
2463                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2464                                     $1, $3); 
2465                 }
2466 |       inclusive_or_expression OR_TK error
2467                 {yyerror ("Missing term"); RECOVER;}
2468 ;
2469
2470 conditional_and_expression:
2471         inclusive_or_expression
2472 |       conditional_and_expression BOOL_AND_TK inclusive_or_expression
2473                 {
2474                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2475                                     $1, $3); 
2476                 }
2477 |       conditional_and_expression BOOL_AND_TK error
2478                 {yyerror ("Missing term"); RECOVER;}
2479 ;
2480
2481 conditional_or_expression:
2482         conditional_and_expression
2483 |       conditional_or_expression BOOL_OR_TK conditional_and_expression
2484                 {
2485                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2486                                     $1, $3); 
2487                 }
2488 |       conditional_or_expression BOOL_OR_TK error
2489                 {yyerror ("Missing term"); RECOVER;}
2490 ;
2491
2492 conditional_expression:         /* Error handling here is weak */
2493         conditional_or_expression
2494 |       conditional_or_expression REL_QM_TK expression REL_CL_TK conditional_expression
2495                 {
2496                   $$ = build (CONDITIONAL_EXPR, NULL_TREE, $1, $3, $5);
2497                   EXPR_WFL_LINECOL ($$) = $2.location;
2498                 }
2499 |       conditional_or_expression REL_QM_TK REL_CL_TK error
2500                 {
2501                   YYERROR_NOW;
2502                   yyerror ("Missing term");
2503                   DRECOVER (1);
2504                 }
2505 |       conditional_or_expression REL_QM_TK error
2506                 {yyerror ("Missing term"); DRECOVER (2);}
2507 |       conditional_or_expression REL_QM_TK expression REL_CL_TK error
2508                 {yyerror ("Missing term"); DRECOVER (3);}
2509 ;
2510
2511 assignment_expression:
2512         conditional_expression
2513 |       assignment
2514 ;
2515
2516 assignment:
2517         left_hand_side assignment_operator assignment_expression
2518                 { $$ = build_assignment ($2.token, $2.location, $1, $3); }
2519 |       left_hand_side assignment_operator error
2520                 {
2521                   if (ctxp->prevent_ese != lineno)
2522                     yyerror ("Missing term");
2523                   DRECOVER (assign);
2524                 }
2525 ;
2526
2527 left_hand_side:
2528         name
2529 |       field_access
2530 |       array_access
2531 ;
2532
2533 assignment_operator:
2534         ASSIGN_ANY_TK
2535 |       ASSIGN_TK
2536 ;
2537
2538 expression:
2539         assignment_expression
2540 ;
2541
2542 constant_expression:
2543         expression
2544 ;
2545
2546 %%
2547 \f
2548
2549 /* This section of the code deal with save/restoring parser contexts.
2550    Add mode documentation here. FIXME */
2551
2552 /* Helper function. Create a new parser context. With
2553    COPY_FROM_PREVIOUS set to a non zero value, content of the previous
2554    context is copied, otherwise, the new context is zeroed. The newly
2555    created context becomes the current one.  */
2556
2557 static void
2558 create_new_parser_context (copy_from_previous)
2559     int copy_from_previous;
2560 {
2561   struct parser_ctxt *new;
2562
2563   new =  (struct parser_ctxt *)xmalloc(sizeof (struct parser_ctxt));
2564   if (copy_from_previous)
2565     {
2566       memcpy ((PTR)new, (PTR)ctxp, sizeof (struct parser_ctxt));
2567       new->saved_data_ctx = 1;
2568     }
2569   else
2570     bzero ((PTR) new, sizeof (struct parser_ctxt));
2571       
2572   new->next = ctxp;
2573   ctxp = new;
2574 }
2575
2576 /* Create a new parser context and make it the current one. */
2577
2578 void
2579 java_push_parser_context ()
2580 {
2581   create_new_parser_context (0);
2582   if (ctxp->next)
2583     {
2584       ctxp->incomplete_class = ctxp->next->incomplete_class;
2585       ctxp->gclass_list = ctxp->next->gclass_list;
2586     }
2587 }  
2588
2589 void 
2590 java_pop_parser_context (generate)
2591      int generate;
2592 {
2593   tree current;
2594   struct parser_ctxt *toFree, *next;
2595
2596   if (!ctxp)
2597     return;
2598
2599   toFree = ctxp;
2600   next = ctxp->next;
2601   if (next)
2602     {
2603       next->incomplete_class = ctxp->incomplete_class;
2604       next->gclass_list = ctxp->gclass_list;
2605       lineno = ctxp->lineno;
2606       finput = ctxp->finput;
2607       current_class = ctxp->current_class;
2608     }
2609
2610   /* Set the single import class file flag to 0 for the current list
2611      of imported things */
2612   for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
2613     IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_PURPOSE (current)) = 0;
2614
2615   /* And restore those of the previous context */
2616   if ((ctxp = next))            /* Assignment is really meant here */
2617     for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
2618       IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_PURPOSE (current)) = 1;
2619   
2620   /* If we pushed a context to parse a class intended to be generated,
2621      we keep it so we can remember the class. What we could actually
2622      do is to just update a list of class names.  */
2623   if (generate)
2624     {
2625       toFree->next = ctxp_for_generation;
2626       ctxp_for_generation = toFree;
2627     }
2628   else
2629     free (toFree);
2630 }
2631
2632 /* Create a parser context for the use of saving some global
2633    variables.  */
2634
2635 void
2636 java_parser_context_save_global ()
2637 {
2638   if (!ctxp)
2639     {
2640       java_push_parser_context ();
2641       ctxp->saved_data_ctx = 1;
2642     }
2643
2644   /* If this context already stores data, create a new one suitable
2645      for data storage. */
2646   else if (ctxp->saved_data)
2647     create_new_parser_context (1);
2648
2649   ctxp->finput = finput;
2650   ctxp->lineno = lineno;
2651   ctxp->current_class = current_class;
2652   ctxp->filename = input_filename;
2653   ctxp->current_function_decl = current_function_decl;
2654   ctxp->saved_data = 1;
2655 }
2656
2657 /* Restore some global variables from the previous context. Make the
2658    previous context the current one.  */
2659
2660 void
2661 java_parser_context_restore_global ()
2662 {
2663   finput = ctxp->finput;
2664   lineno = ctxp->lineno;
2665   current_class = ctxp->current_class;
2666   input_filename = ctxp->filename;
2667   current_function_decl = ctxp->current_function_decl;
2668   ctxp->saved_data = 0;
2669   if (ctxp->saved_data_ctx)
2670     java_pop_parser_context (0);
2671 }
2672
2673 /* Suspend vital data for the current class/function being parsed so
2674    that an other class can be parsed. Used to let local/anonymous
2675    classes be parsed.  */
2676
2677 static void
2678 java_parser_context_suspend ()
2679 {
2680   /* This makes debugging through java_debug_context easier */
2681   static char *name = "<inner buffer context>";
2682
2683   /* Duplicate the previous context, use it to save the globals we're
2684      interested in */
2685   create_new_parser_context (1);
2686   ctxp->current_function_decl = current_function_decl;
2687   ctxp->current_class = current_class;
2688
2689   /* Then create a new context which inherits all data from the
2690      previous one. This will be the new current context  */
2691   create_new_parser_context (1);
2692
2693   /* Help debugging */
2694   ctxp->next->filename = name;
2695 }
2696
2697 /* Resume vital data for the current class/function being parsed so
2698    that an other class can be parsed. Used to let local/anonymous
2699    classes be parsed.  The trick is the data storing file position
2700    informations must be restored to their current value, so parsing
2701    can resume as if no context was ever saved. */
2702
2703 static void
2704 java_parser_context_resume ()
2705 {
2706   struct parser_ctxt *old = ctxp;             /* This one is to be discarded */
2707   struct parser_ctxt *saver = old->next;      /* This one contain saved info */
2708   struct parser_ctxt *restored = saver->next; /* This one is the old current */
2709
2710   /* We need to inherit the list of classes to complete/generate */
2711   restored->incomplete_class = old->incomplete_class;
2712   restored->gclass_list = old->gclass_list;
2713   restored->classd_list = old->classd_list;
2714   restored->class_list = old->class_list;
2715
2716   /* Restore the current class and function from the saver */
2717   current_class = saver->current_class;
2718   current_function_decl = saver->current_function_decl;
2719
2720   /* Retrive the restored context */
2721   ctxp = restored;
2722
2723   /* Re-installed the data for the parsing to carry on */
2724   bcopy (&old->marker_begining, &ctxp->marker_begining,
2725          (size_t)(&ctxp->marker_end - &ctxp->marker_begining));
2726
2727   /* Buffer context can now be discarded */
2728   free (saver);
2729   free (old);
2730 }
2731
2732 /* Add a new anchor node to which all statement(s) initializing static
2733    and non static initialized upon declaration field(s) will be
2734    linked.  */
2735
2736 static void
2737 java_parser_context_push_initialized_field ()
2738 {
2739   tree node;
2740
2741   node = build_tree_list (NULL_TREE, NULL_TREE);
2742   TREE_CHAIN (node) = CPC_STATIC_INITIALIZER_LIST (ctxp);
2743   CPC_STATIC_INITIALIZER_LIST (ctxp) = node;
2744
2745   node = build_tree_list (NULL_TREE, NULL_TREE);
2746   TREE_CHAIN (node) = CPC_INITIALIZER_LIST (ctxp);
2747   CPC_INITIALIZER_LIST (ctxp) = node;
2748
2749   node = build_tree_list (NULL_TREE, NULL_TREE);
2750   TREE_CHAIN (node) = CPC_INSTANCE_INITIALIZER_LIST (ctxp);
2751   CPC_INSTANCE_INITIALIZER_LIST (ctxp) = node;
2752 }
2753
2754 /* Pop the lists of initialized field. If this lists aren't empty,
2755    remember them so we can use it to create and populate the $finit$
2756    or <clinit> functions. */
2757
2758 static void
2759 java_parser_context_pop_initialized_field ()
2760 {
2761   tree stmts;
2762   tree class_type = TREE_TYPE (GET_CPC ());
2763
2764   if (CPC_INITIALIZER_LIST (ctxp))
2765     {
2766       stmts = CPC_INITIALIZER_STMT (ctxp);
2767       CPC_INITIALIZER_LIST (ctxp) = TREE_CHAIN (CPC_INITIALIZER_LIST (ctxp));
2768       if (stmts && !java_error_count)
2769         TYPE_FINIT_STMT_LIST (class_type) = reorder_static_initialized (stmts);
2770     }
2771
2772   if (CPC_STATIC_INITIALIZER_LIST (ctxp))
2773     {
2774       stmts = CPC_STATIC_INITIALIZER_STMT (ctxp);
2775       CPC_STATIC_INITIALIZER_LIST (ctxp) = 
2776         TREE_CHAIN (CPC_STATIC_INITIALIZER_LIST (ctxp));
2777       /* Keep initialization in order to enforce 8.5 */
2778       if (stmts && !java_error_count)
2779         TYPE_CLINIT_STMT_LIST (class_type) = nreverse (stmts);
2780     }
2781
2782   /* JDK 1.1 instance initializers */
2783   if (CPC_INSTANCE_INITIALIZER_LIST (ctxp))
2784     {
2785       stmts = CPC_INSTANCE_INITIALIZER_STMT (ctxp);
2786       CPC_INSTANCE_INITIALIZER_LIST (ctxp) = 
2787         TREE_CHAIN (CPC_INSTANCE_INITIALIZER_LIST (ctxp));
2788       if (stmts && !java_error_count)
2789         TYPE_II_STMT_LIST (class_type) = nreverse (stmts);
2790     }
2791 }
2792
2793 static tree
2794 reorder_static_initialized (list)
2795      tree list;
2796 {
2797   /* We have to keep things in order. The alias initializer have to
2798      come first, then the initialized regular field, in reverse to
2799      keep them in lexical order. */
2800   tree marker, previous = NULL_TREE;
2801   for (marker = list; marker; previous = marker, marker = TREE_CHAIN (marker))
2802     if (TREE_CODE (marker) == TREE_LIST 
2803         && !TREE_VALUE (marker) && !TREE_PURPOSE (marker))
2804       break;
2805   
2806   /* No static initialized, the list is fine as is */
2807   if (!previous)
2808     list = TREE_CHAIN (marker);
2809
2810   /* No marker? reverse the whole list */
2811   else if (!marker)
2812     list = nreverse (list);
2813
2814   /* Otherwise, reverse what's after the marker and the new reordered
2815      sublist will replace the marker. */
2816   else
2817     {
2818       TREE_CHAIN (previous) = NULL_TREE;
2819       list = nreverse (list);
2820       list = chainon (TREE_CHAIN (marker), list);
2821     }
2822   return list;
2823 }
2824
2825 /* Helper functions to dump the parser context stack.  */
2826
2827 #define TAB_CONTEXT(C) \
2828   {int i; for (i = 0; i < (C); i++) fputc (' ', stderr);}
2829
2830 static void
2831 java_debug_context_do (tab)
2832      int tab;
2833 {
2834   struct parser_ctxt *copy = ctxp;
2835   while (copy)
2836     {
2837       TAB_CONTEXT (tab);
2838       fprintf (stderr, "ctxt: 0x%0lX\n", (unsigned long)copy);
2839       TAB_CONTEXT (tab);
2840       fprintf (stderr, "filename: %s\n", copy->filename);
2841       TAB_CONTEXT (tab);
2842       fprintf (stderr, "lineno: %d\n", copy->lineno);
2843       TAB_CONTEXT (tab);
2844       fprintf (stderr, "package: %s\n",
2845                (copy->package ? 
2846                 IDENTIFIER_POINTER (copy->package) : "<none>"));
2847       TAB_CONTEXT (tab);
2848       fprintf (stderr, "context for saving: %d\n", copy->saved_data_ctx);
2849       TAB_CONTEXT (tab);
2850       fprintf (stderr, "saved data: %d\n", copy->saved_data);
2851       copy = copy->next;
2852       tab += 2;
2853     }
2854 }
2855
2856 /* Dump the stacked up parser contexts. Intended to be called from a
2857    debugger.  */
2858
2859 void
2860 java_debug_context ()
2861 {
2862   java_debug_context_do (0);
2863 }
2864
2865 \f
2866
2867 /* Flag for the error report routine to issue the error the first time
2868    it's called (overriding the default behavior which is to drop the
2869    first invocation and honor the second one, taking advantage of a
2870    richer context.  */
2871 static int force_error = 0;
2872
2873 /* Reporting an constructor invocation error.  */
2874 static void
2875 parse_ctor_invocation_error ()
2876 {
2877   if (DECL_CONSTRUCTOR_P (current_function_decl))
2878     yyerror ("Constructor invocation must be first thing in a constructor"); 
2879   else
2880     yyerror ("Only constructors can invoke constructors");
2881 }
2882
2883 /* Reporting JDK1.1 features not implemented.  */
2884
2885 static tree
2886 parse_jdk1_1_error (msg)
2887     const char *msg;
2888 {
2889   sorry (": `%s' JDK1.1(TM) feature", msg);
2890   java_error_count++;
2891   return empty_stmt_node;
2892 }
2893
2894 static int do_warning = 0;
2895
2896 void
2897 yyerror (msg)
2898      const char *msg;
2899 {
2900   static java_lc elc;
2901   static int  prev_lineno;
2902   static const char *prev_msg;
2903
2904   int save_lineno;
2905   char *remainder, *code_from_source;
2906   extern struct obstack temporary_obstack;
2907   
2908   if (!force_error && prev_lineno == lineno)
2909     return;
2910
2911   /* Save current error location but report latter, when the context is
2912      richer.  */
2913   if (ctxp->java_error_flag == 0)
2914     {
2915       ctxp->java_error_flag = 1;
2916       elc = ctxp->elc;
2917       /* Do something to use the previous line if we're reaching the
2918          end of the file... */
2919 #ifdef VERBOSE_SKELETON
2920       printf ("* Error detected (%s)\n", (msg ? msg : "(null)"));
2921 #endif
2922       return;
2923     }
2924
2925   /* Ignore duplicate message on the same line. BTW, this is dubious. FIXME */
2926   if (!force_error && msg == prev_msg && prev_lineno == elc.line)
2927     return;
2928
2929   ctxp->java_error_flag = 0;
2930   if (do_warning)
2931     java_warning_count++;
2932   else
2933     java_error_count++;
2934   
2935   if (elc.col == 0 && msg && msg[1] == ';')
2936     {
2937       elc.col  = ctxp->p_line->char_col-1;
2938       elc.line = ctxp->p_line->lineno;
2939     }
2940
2941   save_lineno = lineno;
2942   prev_lineno = lineno = elc.line;
2943   prev_msg = msg;
2944
2945   code_from_source = java_get_line_col (ctxp->filename, elc.line, elc.col);
2946   obstack_grow0 (&temporary_obstack, 
2947                  code_from_source, strlen (code_from_source));
2948   remainder = obstack_finish (&temporary_obstack);
2949   if (do_warning)
2950     warning ("%s.\n%s", msg, remainder);
2951   else
2952     error ("%s.\n%s", msg, remainder);
2953
2954   /* This allow us to cheaply avoid an extra 'Invalid expression
2955      statement' error report when errors have been already reported on
2956      the same line. This occurs when we report an error but don't have
2957      a synchronization point other than ';', which
2958      expression_statement is the only one to take care of.  */
2959   ctxp->prevent_ese = lineno = save_lineno;
2960 }
2961
2962 static void
2963 issue_warning_error_from_context (cl, msg, ap)
2964      tree cl;
2965      const char *msg;
2966      va_list ap;
2967 {
2968   char *saved, *saved_input_filename;
2969   char buffer [4096];
2970   vsprintf (buffer, msg, ap);
2971   force_error = 1;
2972
2973   ctxp->elc.line = EXPR_WFL_LINENO (cl);
2974   ctxp->elc.col  = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 : 
2975                     (EXPR_WFL_COLNO (cl) == 0xffe ? -2 : EXPR_WFL_COLNO (cl)));
2976
2977   /* We have a CL, that's a good reason for using it if it contains data */
2978   saved = ctxp->filename;
2979   if (TREE_CODE (cl) == EXPR_WITH_FILE_LOCATION && EXPR_WFL_FILENAME_NODE (cl))
2980     ctxp->filename = EXPR_WFL_FILENAME (cl);
2981   saved_input_filename = input_filename;
2982   input_filename = ctxp->filename;
2983   java_error (NULL);
2984   java_error (buffer);
2985   ctxp->filename = saved;
2986   input_filename = saved_input_filename;
2987   force_error = 0;
2988 }
2989
2990 /* Issue an error message at a current source line CL */
2991
2992 void
2993 parse_error_context VPARAMS ((tree cl, const char *msg, ...))
2994 {
2995 #ifndef ANSI_PROTOTYPES
2996   tree cl;
2997   const char *msg;
2998 #endif
2999   va_list ap;
3000
3001   VA_START (ap, msg);
3002 #ifndef ANSI_PROTOTYPES
3003   cl = va_arg (ap, tree);
3004   msg = va_arg (ap, const char *);
3005 #endif
3006   issue_warning_error_from_context (cl, msg, ap);
3007   va_end (ap);
3008 }
3009
3010 /* Issue a warning at a current source line CL */
3011
3012 static void
3013 parse_warning_context VPARAMS ((tree cl, const char *msg, ...))
3014 {
3015 #ifndef ANSI_PROTOTYPES
3016   tree cl;
3017   const char *msg;
3018 #endif
3019   va_list ap;
3020
3021   VA_START (ap, msg);
3022 #ifndef ANSI_PROTOTYPES
3023   cl = va_arg (ap, tree);
3024   msg = va_arg (ap, const char *);
3025 #endif
3026
3027   force_error = do_warning = 1;
3028   issue_warning_error_from_context (cl, msg, ap);
3029   do_warning = force_error = 0;
3030   va_end (ap);
3031 }
3032
3033 static tree
3034 find_expr_with_wfl (node)
3035      tree node;
3036 {
3037   while (node)
3038     {
3039       char code;
3040       tree to_return;
3041
3042       switch (TREE_CODE (node))
3043         {
3044         case BLOCK:
3045           node = BLOCK_EXPR_BODY (node);
3046           continue;
3047
3048         case COMPOUND_EXPR:
3049           to_return = find_expr_with_wfl (TREE_OPERAND (node, 0));
3050           if (to_return)
3051             return to_return;
3052           node = TREE_OPERAND (node, 1);
3053           continue;
3054
3055         case LOOP_EXPR:
3056           node = TREE_OPERAND (node, 0);
3057           continue;
3058           
3059         case LABELED_BLOCK_EXPR:
3060           node = TREE_OPERAND (node, 1);
3061           continue;
3062
3063         default:
3064           code = TREE_CODE_CLASS (TREE_CODE (node));
3065           if (((code == '1') || (code == '2') || (code == 'e'))
3066               && EXPR_WFL_LINECOL (node))
3067             return node;
3068           return NULL_TREE;
3069         }
3070     }
3071   return NULL_TREE;
3072 }
3073
3074 /* Issue a missing return statement error. Uses METHOD to figure the
3075    last line of the method the error occurs in.  */
3076
3077 static void
3078 missing_return_error (method)
3079      tree method;
3080 {
3081   EXPR_WFL_SET_LINECOL (wfl_operator, DECL_SOURCE_LINE_LAST (method), -2);
3082   parse_error_context (wfl_operator, "Missing return statement");
3083 }
3084
3085 /* Issue an unreachable statement error. From NODE, find the next
3086    statement to report appropriately.  */
3087 static void
3088 unreachable_stmt_error (node)
3089      tree node;
3090 {
3091   /* Browse node to find the next expression node that has a WFL. Use
3092      the location to report the error */
3093   if (TREE_CODE (node) == COMPOUND_EXPR)
3094     node = find_expr_with_wfl (TREE_OPERAND (node, 1));
3095   else
3096     node = find_expr_with_wfl (node);
3097
3098   if (node)
3099     {
3100       EXPR_WFL_SET_LINECOL (wfl_operator, EXPR_WFL_LINENO (node), -2);
3101       parse_error_context (wfl_operator, "Unreachable statement");
3102     }
3103   else
3104     fatal ("Can't get valid statement - unreachable_stmt_error");
3105 }
3106
3107 int
3108 java_report_errors ()
3109 {
3110   if (java_error_count)
3111     fprintf (stderr, "%d error%s", 
3112              java_error_count, (java_error_count == 1 ? "" : "s"));
3113   if (java_warning_count)
3114     fprintf (stderr, "%s%d warning%s", (java_error_count ? ", " : ""),
3115              java_warning_count, (java_warning_count == 1 ? "" : "s"));
3116   if (java_error_count || java_warning_count)
3117     putc ('\n', stderr);
3118   return java_error_count;
3119 }
3120
3121 static char *
3122 java_accstring_lookup (flags)
3123      int flags;
3124 {
3125   static char buffer [80];
3126 #define COPY_RETURN(S) {strcpy (buffer, S); return buffer;}
3127
3128   /* Access modifier looked-up first for easier report on forbidden
3129      access. */
3130   if (flags & ACC_PUBLIC) COPY_RETURN ("public");
3131   if (flags & ACC_PRIVATE) COPY_RETURN ("private");
3132   if (flags & ACC_PROTECTED) COPY_RETURN ("protected");
3133   if (flags & ACC_STATIC) COPY_RETURN ("static");
3134   if (flags & ACC_FINAL) COPY_RETURN ("final");
3135   if (flags & ACC_SYNCHRONIZED) COPY_RETURN ("synchronized");
3136   if (flags & ACC_VOLATILE) COPY_RETURN ("volatile");
3137   if (flags & ACC_TRANSIENT) COPY_RETURN ("transient");
3138   if (flags & ACC_NATIVE) COPY_RETURN ("native");
3139   if (flags & ACC_INTERFACE) COPY_RETURN ("interface");
3140   if (flags & ACC_ABSTRACT) COPY_RETURN ("abstract");
3141
3142   buffer [0] = '\0';
3143   return buffer;
3144 #undef COPY_RETURN
3145 }
3146
3147 /* Issuing error messages upon redefinition of classes, interfaces or
3148    variables. */
3149
3150 static void
3151 classitf_redefinition_error (context, id, decl, cl)
3152      const char *context;
3153      tree id, decl, cl;
3154 {
3155   parse_error_context (cl, "%s `%s' already defined in %s:%d", 
3156                        context, IDENTIFIER_POINTER (id), 
3157                        DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
3158   /* Here we should point out where its redefined. It's a unicode. FIXME */
3159 }
3160
3161 static void
3162 variable_redefinition_error (context, name, type, line)
3163      tree context, name, type;
3164      int line;
3165 {
3166   const char *type_name;
3167
3168   /* Figure a proper name for type. We might haven't resolved it */
3169   if (TREE_CODE (type) == POINTER_TYPE && !TREE_TYPE (type))
3170     type_name = IDENTIFIER_POINTER (TYPE_NAME (type));
3171   else
3172     type_name = lang_printable_name (type, 0);
3173
3174   parse_error_context (context,
3175                        "Variable `%s' is already defined in this method and was declared `%s %s' at line %d", 
3176                        IDENTIFIER_POINTER (name),
3177                        type_name, IDENTIFIER_POINTER (name), line);
3178 }
3179
3180 static tree
3181 build_array_from_name (type, type_wfl, name, ret_name)
3182      tree type, type_wfl, name, *ret_name;
3183 {
3184   int more_dims = 0;
3185   const char *string;
3186
3187   /* Eventually get more dims */
3188   string = IDENTIFIER_POINTER (name);
3189   while (string [more_dims] == '[')
3190     more_dims++;
3191   
3192   /* If we have, then craft a new type for this variable */
3193   if (more_dims)
3194     {
3195       name = get_identifier (&string [more_dims]);
3196
3197       /* If we have a pointer, use its type */
3198       if (TREE_CODE (type) == POINTER_TYPE)
3199         type = TREE_TYPE (type);
3200
3201       /* Building the first dimension of a primitive type uses this
3202          function */
3203       if (JPRIMITIVE_TYPE_P (type))
3204         {
3205           type = build_java_array_type (type, -1);
3206           CLASS_LOADED_P (type) = 1;
3207           more_dims--;
3208         }
3209       /* Otherwise, if we have a WFL for this type, use it (the type
3210          is already an array on an unresolved type, and we just keep
3211          on adding dimensions) */
3212       else if (type_wfl)
3213         type = type_wfl;
3214
3215       /* Add all the dimensions */
3216       while (more_dims--)
3217         type = build_unresolved_array_type (type);
3218
3219       /* The type may have been incomplete in the first place */
3220       if (type_wfl)
3221         type = obtain_incomplete_type (type);
3222     }
3223
3224   if (ret_name)
3225     *ret_name = name;
3226   return type;
3227 }
3228
3229 /* Build something that the type identifier resolver will identify as
3230    being an array to an unresolved type. TYPE_WFL is a WFL on a
3231    identifier. */
3232
3233 static tree
3234 build_unresolved_array_type (type_or_wfl)
3235      tree type_or_wfl;
3236 {
3237   const char *ptr;
3238
3239   /* TYPE_OR_WFL might be an array on a resolved type. In this case,
3240      just create a array type */
3241   if (TREE_CODE (type_or_wfl) == RECORD_TYPE)
3242     {
3243       tree type = build_java_array_type (type_or_wfl, -1);
3244       CLASS_LOADED_P (type) = CLASS_LOADED_P (type_or_wfl);
3245       return type;
3246     }
3247
3248   obstack_1grow (&temporary_obstack, '[');
3249   obstack_grow0 (&temporary_obstack,
3250                  IDENTIFIER_POINTER (EXPR_WFL_NODE (type_or_wfl)),
3251                  IDENTIFIER_LENGTH (EXPR_WFL_NODE (type_or_wfl)));
3252   ptr = obstack_finish (&temporary_obstack);
3253   return build_expr_wfl (get_identifier (ptr),
3254                          EXPR_WFL_FILENAME (type_or_wfl),
3255                          EXPR_WFL_LINENO (type_or_wfl),
3256                          EXPR_WFL_COLNO (type_or_wfl));
3257 }
3258
3259 static void
3260 parser_add_interface (class_decl, interface_decl, wfl)
3261      tree class_decl, interface_decl, wfl;
3262 {
3263   if (maybe_add_interface (TREE_TYPE (class_decl), TREE_TYPE (interface_decl)))
3264     parse_error_context (wfl, "Interface `%s' repeated",
3265                          IDENTIFIER_POINTER (DECL_NAME (interface_decl)));
3266 }
3267
3268 /* Bulk of common class/interface checks. Return 1 if an error was
3269    encountered. TAG is 0 for a class, 1 for an interface.  */
3270
3271 static int
3272 check_class_interface_creation (is_interface, flags, raw_name, qualified_name, decl, cl)
3273      int is_interface, flags;
3274      tree raw_name, qualified_name, decl, cl;
3275 {
3276   tree node;
3277   int sca = 0;                  /* Static class allowed */
3278   int icaf = 0;                 /* Inner class allowed flags */
3279   int uaaf = CLASS_MODIFIERS;   /* Usually allowed access flags */
3280
3281   if (!quiet_flag)
3282     fprintf (stderr, " %s%s %s", 
3283              (CPC_INNER_P () ? "inner" : ""),
3284              (is_interface ? "interface" : "class"), 
3285              IDENTIFIER_POINTER (qualified_name));
3286
3287   /* Scope of an interface/class type name:
3288        - Can't be imported by a single type import
3289        - Can't already exists in the package */
3290   if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (raw_name)
3291       && (node = find_name_in_single_imports (raw_name)))
3292     {
3293       parse_error_context 
3294         (cl, "%s name `%s' clashes with imported type `%s'",
3295          (is_interface ? "Interface" : "Class"),
3296          IDENTIFIER_POINTER (raw_name), IDENTIFIER_POINTER (node));
3297       return 1;
3298     }
3299   if (decl && CLASS_COMPLETE_P (decl))
3300     {
3301       classitf_redefinition_error ((is_interface ? "Interface" : "Class"), 
3302                                    qualified_name, decl, cl);
3303       return 1;
3304     }
3305
3306   if (check_inner_class_redefinition (raw_name, cl))
3307     return 1;
3308
3309   /* If public, file name should match class/interface name, except
3310      when dealing with an inner class */
3311   if (!CPC_INNER_P () && (flags & ACC_PUBLIC ))
3312     {
3313       const char *f;
3314
3315       /* Contains OS dependent assumption on path separator. FIXME */
3316       for (f = &input_filename [strlen (input_filename)]; 
3317            f != input_filename && f[0] != '/' && f[0] != DIR_SEPARATOR;
3318            f--)
3319         ;
3320       if (f[0] == '/' || f[0] == DIR_SEPARATOR)
3321         f++;
3322       if (strncmp (IDENTIFIER_POINTER (raw_name), 
3323                    f , IDENTIFIER_LENGTH (raw_name)) ||
3324           f [IDENTIFIER_LENGTH (raw_name)] != '.')
3325         parse_error_context
3326           (cl, "Public %s `%s' must be defined in a file called `%s.java'", 
3327                              (is_interface ? "interface" : "class"),
3328                              IDENTIFIER_POINTER (qualified_name),
3329                              IDENTIFIER_POINTER (raw_name));
3330     }
3331
3332   /* Static classes can be declared only in top level classes. Note:
3333      once static, a inner class is a top level class. */
3334   if (flags & ACC_STATIC)
3335     {
3336       /* Catch the specific error of declaring an class inner class
3337          with no toplevel enclosing class. Prevent check_modifiers from
3338          complaining a second time */
3339       if (CPC_INNER_P () && !TOPLEVEL_CLASS_DECL_P (GET_CPC()))
3340         {
3341           parse_error_context (cl, "Inner class `%s' can't be static. Static classes can only occur in interfaces and top-level classes", 
3342                                IDENTIFIER_POINTER (qualified_name));
3343           sca = ACC_STATIC;
3344         }
3345       /* Else, in the context of a top-level class declaration, let
3346          `check_modifiers' do its job, otherwise, give it a go */
3347       else
3348         sca = (GET_CPC_LIST () ? ACC_STATIC : 0);
3349     }
3350
3351   /* Inner classes can be declared private or protected
3352      within their enclosing classes. */
3353   if (CPC_INNER_P ())
3354     {
3355       /* A class which is local to a block can't be public, private,
3356          protected or static. But it is created final, so allow this
3357          one. */
3358       if (current_function_decl)
3359         icaf = sca = uaaf = ACC_FINAL;
3360       else
3361         {
3362           check_modifiers_consistency (flags);
3363           icaf = ACC_PRIVATE|ACC_PROTECTED;
3364         }
3365     }
3366
3367   if (is_interface) 
3368     {
3369       if (CPC_INNER_P ())
3370         uaaf = INTERFACE_INNER_MODIFIERS;
3371       else
3372         uaaf = INTERFACE_MODIFIERS;
3373       
3374       check_modifiers ("Illegal modifier `%s' for interface declaration", 
3375                        flags, uaaf);
3376     }
3377   else
3378     check_modifiers ((current_function_decl ?
3379                       "Illegal modifier `%s' for local class declaration" :
3380                       "Illegal modifier `%s' for class declaration"),
3381                      flags, uaaf|sca|icaf);
3382   return 0;
3383 }
3384
3385 static void
3386 make_nested_class_name (cpc_list)
3387      tree cpc_list;
3388 {
3389   tree name;
3390
3391   if (!cpc_list)
3392     return;
3393   else
3394     make_nested_class_name (TREE_CHAIN (cpc_list));
3395
3396   /* Pick the qualified name when dealing with the first upmost
3397      enclosing class */
3398   name = (TREE_CHAIN (cpc_list) ? 
3399           TREE_PURPOSE (cpc_list) : DECL_NAME (TREE_VALUE (cpc_list)));
3400   obstack_grow (&temporary_obstack,
3401                 IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name));
3402   /* Why is NO_DOLLAR_IN_LABEL defined? */
3403 #if 0
3404 #ifdef NO_DOLLAR_IN_LABEL
3405   fatal ("make_nested_class_name: Can't use '$' as a separator "
3406          "for inner classes");
3407 #endif
3408 #endif
3409   obstack_1grow (&temporary_obstack, '$');
3410 }
3411
3412 /* Can't redefine a class already defined in an earlier scope. */
3413
3414 static int
3415 check_inner_class_redefinition (raw_name, cl)
3416      tree raw_name, cl;
3417 {
3418   tree scope_list;
3419
3420   for (scope_list = GET_CPC_LIST (); scope_list; 
3421        scope_list = GET_NEXT_ENCLOSING_CPC (scope_list))
3422     if (raw_name == GET_CPC_UN_NODE (scope_list))
3423       {
3424         parse_error_context 
3425           (cl, "The class name `%s' is already defined in this scope. An inner class may not have the same simple name as any of its enclosing classes",
3426            IDENTIFIER_POINTER (raw_name));
3427         return 1;
3428       }
3429   return 0;
3430 }
3431
3432 static tree
3433 find_as_inner_class (enclosing, name, cl)
3434      tree enclosing, name, cl;
3435 {
3436   tree qual, to_return;
3437   if (!enclosing)
3438     return NULL_TREE;
3439
3440   name = TYPE_NAME (name);
3441
3442   /* First search: within the scope of `enclosing', search for name */
3443   if (QUALIFIED_P (name) && cl && EXPR_WFL_NODE (cl) == name)
3444     qual = EXPR_WFL_QUALIFICATION (cl);
3445   else if (cl)
3446     qual = build_tree_list (cl, NULL_TREE);
3447   else
3448     qual = build_tree_list (build_expr_wfl (name, NULL, 0, 0), NULL_TREE);
3449   
3450   if ((to_return = find_as_inner_class_do (qual, enclosing)))
3451     return to_return;
3452
3453   /* We're dealing with a qualified name. Try to resolve thing until
3454      we get something that is an enclosing class. */
3455   if (QUALIFIED_P (name) && cl && EXPR_WFL_NODE (cl) == name)
3456     {
3457       tree acc = NULL_TREE, decl = NULL_TREE, ptr;
3458
3459       for(qual = EXPR_WFL_QUALIFICATION (cl); qual && !decl; 
3460           qual = TREE_CHAIN (qual))
3461         {
3462           acc = merge_qualified_name (acc, 
3463                                       EXPR_WFL_NODE (TREE_PURPOSE (qual)));
3464           BUILD_PTR_FROM_NAME (ptr, acc);
3465           decl = do_resolve_class (NULL_TREE, ptr, NULL_TREE, cl);
3466         }
3467
3468       /* A NULL qual and a decl means that the search ended
3469          successfully?!? We have to do something then. FIXME */
3470       
3471       if (decl)
3472         enclosing = decl;
3473       else
3474         qual = EXPR_WFL_QUALIFICATION (cl);
3475     }
3476   /* Otherwise, create a qual for the other part of the resolution. */
3477   else
3478     qual = build_tree_list (build_expr_wfl (name, NULL, 0, 0), NULL_TREE);
3479
3480   return find_as_inner_class_do (qual, enclosing);
3481 }
3482
3483 /* We go inside the list of sub classes and try to find a way
3484    through. */
3485
3486 static tree
3487 find_as_inner_class_do (qual, enclosing)
3488      tree qual, enclosing;
3489 {
3490   if (!qual)
3491     return NULL_TREE;
3492
3493   for (; qual && enclosing; qual = TREE_CHAIN (qual))
3494     {
3495       tree name_to_match = EXPR_WFL_NODE (TREE_PURPOSE (qual));
3496       tree next_enclosing = NULL_TREE;
3497       tree inner_list;
3498
3499       for (inner_list = DECL_INNER_CLASS_LIST (enclosing);
3500            inner_list; inner_list = TREE_CHAIN (inner_list))
3501         {
3502           if (TREE_VALUE (inner_list) == name_to_match)
3503             {
3504               next_enclosing = TREE_PURPOSE (inner_list);
3505               break;
3506             }
3507         }
3508       enclosing = next_enclosing;
3509     }
3510
3511   return (!qual && enclosing ? enclosing : NULL_TREE);
3512 }
3513
3514 /* Reach all inner classes and tie their unqualified name to a
3515    DECL. */
3516
3517 static void
3518 set_nested_class_simple_name_value (outer, set)
3519      tree outer;
3520      int set;
3521 {
3522   tree l;
3523
3524   for (l = DECL_INNER_CLASS_LIST (outer); l; l = TREE_CHAIN (l))
3525     IDENTIFIER_GLOBAL_VALUE (TREE_VALUE (l)) = (set ? 
3526                                                 TREE_PURPOSE (l) : NULL_TREE);
3527 }
3528
3529 static void
3530 link_nested_class_to_enclosing ()
3531 {
3532   if (GET_ENCLOSING_CPC ())
3533     {
3534       tree enclosing = GET_ENCLOSING_CPC_CONTEXT ();
3535       DECL_INNER_CLASS_LIST (enclosing) = 
3536         tree_cons (GET_CPC (), GET_CPC_UN (),
3537                    DECL_INNER_CLASS_LIST (enclosing));
3538       enclosing = enclosing;
3539     }
3540 }
3541
3542 static tree
3543 maybe_make_nested_class_name (name)
3544      tree name;
3545 {
3546   tree id = NULL_TREE;
3547
3548   if (CPC_INNER_P ())
3549     {
3550       make_nested_class_name (GET_CPC_LIST ());
3551       obstack_grow0 (&temporary_obstack,
3552                      IDENTIFIER_POINTER (name), 
3553                      IDENTIFIER_LENGTH (name));
3554       id = get_identifier (obstack_finish (&temporary_obstack));
3555       if (ctxp->package)
3556         QUALIFIED_P (id) = 1;
3557     }
3558   return id;
3559 }
3560
3561 /* If DECL is NULL, create and push a new DECL, record the current
3562    line CL and do other maintenance things.  */
3563
3564 static tree
3565 maybe_create_class_interface_decl (decl, raw_name, qualified_name, cl)
3566      tree decl, raw_name, qualified_name, cl;
3567 {
3568   if (!decl)
3569     decl = push_class (make_class (), qualified_name);
3570
3571   /* Take care of the file and line business */
3572   DECL_SOURCE_FILE (decl) = EXPR_WFL_FILENAME (cl);
3573   /* If we're emiting xrefs, store the line/col number information */
3574   if (flag_emit_xref)
3575     DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (cl);
3576   else
3577     DECL_SOURCE_LINE (decl) = EXPR_WFL_LINENO (cl);
3578   CLASS_FROM_SOURCE_P (TREE_TYPE (decl)) = 1;
3579   CLASS_FROM_CURRENTLY_COMPILED_SOURCE_P (TREE_TYPE (decl)) =
3580     IS_A_COMMAND_LINE_FILENAME_P (EXPR_WFL_FILENAME_NODE (cl));
3581
3582   PUSH_CPC (decl, raw_name);
3583   DECL_CONTEXT (decl) = GET_ENCLOSING_CPC_CONTEXT ();
3584
3585   /* Link the declaration to the already seen ones */
3586   TREE_CHAIN (decl) = ctxp->class_list;
3587   ctxp->class_list = decl;
3588
3589   /* Create a new nodes in the global lists */
3590   ctxp->gclass_list = tree_cons (NULL_TREE, decl, ctxp->gclass_list);
3591   all_class_list = tree_cons (NULL_TREE, decl, all_class_list);
3592
3593   /* Install a new dependency list element */
3594   create_jdep_list (ctxp);
3595
3596   SOURCE_FRONTEND_DEBUG (("Defining class/interface %s", 
3597                           IDENTIFIER_POINTER (qualified_name)));
3598   return decl;
3599 }
3600
3601 static void
3602 add_superinterfaces (decl, interface_list)
3603      tree decl, interface_list;
3604 {
3605   tree node;
3606   /* Superinterface(s): if present and defined, parser_check_super_interface ()
3607      takes care of ensuring that:
3608        - This is an accessible interface type,
3609        - Circularity detection.
3610    parser_add_interface is then called. If present but not defined,
3611    the check operation is delayed until the super interface gets
3612    defined.  */
3613   for (node = interface_list; node; node = TREE_CHAIN (node))
3614     {
3615       tree current = TREE_PURPOSE (node);
3616       tree idecl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (current));
3617       if (idecl && CLASS_LOADED_P (TREE_TYPE (idecl)))
3618         {
3619           if (!parser_check_super_interface (idecl, decl, current))
3620             parser_add_interface (decl, idecl, current);
3621         }
3622       else
3623         register_incomplete_type (JDEP_INTERFACE,
3624                                   current, decl, NULL_TREE);
3625     }
3626 }
3627
3628 /* Create an interface in pass1 and return its decl. Return the
3629    interface's decl in pass 2.  */
3630
3631 static tree
3632 create_interface (flags, id, super)
3633      int flags;
3634      tree id, super;
3635 {
3636   tree raw_name = EXPR_WFL_NODE (id);
3637   tree q_name = parser_qualified_classname (flags & ACC_STATIC, raw_name);
3638   tree decl = IDENTIFIER_CLASS_VALUE (q_name);
3639
3640   EXPR_WFL_NODE (id) = q_name;  /* Keep source location, even if refined. */
3641
3642   /* Basic checks: scope, redefinition, modifiers */ 
3643   if (check_class_interface_creation (1, flags, raw_name, q_name, decl, id))
3644     {
3645       PUSH_ERROR ();
3646       return NULL_TREE;
3647     }
3648
3649   /* Suspend the current parsing context if we're parsing an inner
3650      interface */
3651   if (CPC_INNER_P ())
3652     java_parser_context_suspend ();
3653
3654   /* Push a new context for (static) initialized upon declaration fields */
3655   java_parser_context_push_initialized_field ();
3656
3657   /* Interface modifiers check
3658        - public/abstract allowed (already done at that point)
3659        - abstract is obsolete (comes first, it's a warning, or should be)
3660        - Can't use twice the same (checked in the modifier rule) */
3661   if ((flags & ACC_ABSTRACT) && flag_redundant)
3662     parse_warning_context 
3663       (MODIFIER_WFL (ABSTRACT_TK),
3664        "Redundant use of `abstract' modifier. Interface `%s' is implicitely abstract", IDENTIFIER_POINTER (raw_name));
3665
3666   /* Create a new decl if DECL is NULL, otherwise fix it */
3667   decl = maybe_create_class_interface_decl (decl, raw_name, q_name, id);
3668
3669   /* Set super info and mark the class a complete */
3670   set_super_info (ACC_INTERFACE | flags, TREE_TYPE (decl), 
3671                   object_type_node, ctxp->interface_number);
3672   ctxp->interface_number = 0;
3673   CLASS_COMPLETE_P (decl) = 1;
3674   add_superinterfaces (decl, super);
3675
3676   return decl;
3677 }
3678
3679 /* Anonymous class counter. Will be reset to 1 every time a non
3680    anonymous class gets created. */
3681 static int anonymous_class_counter = 1;
3682
3683 /* Patch anonymous class CLASS, by either extending or implementing
3684    DEP.  */
3685
3686 static void
3687 patch_anonymous_class (type_decl, class_decl, wfl)
3688     tree type_decl, class_decl, wfl;
3689 {
3690   tree class = TREE_TYPE (class_decl);
3691   tree type =  TREE_TYPE (type_decl);
3692   tree binfo = TYPE_BINFO (class);
3693
3694   /* If it's an interface, implement it */
3695   if (CLASS_INTERFACE (type_decl))
3696     {
3697       tree s_binfo;
3698       int length;
3699
3700       if (parser_check_super_interface (type_decl, class_decl, wfl))
3701         return;
3702
3703       s_binfo = TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (class)), 0);
3704       length = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (class))+1;
3705       TYPE_BINFO_BASETYPES (class) = make_tree_vec (length);
3706       TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (class)), 0) = s_binfo;
3707       /* And add the interface */
3708       parser_add_interface (class_decl, type_decl, wfl);
3709     }
3710   /* Otherwise, it's a type we want to extend */
3711   else
3712     {
3713       if (parser_check_super (type_decl, class_decl, wfl))
3714         return;
3715       BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo), 0)) = type;
3716     }
3717 }
3718
3719 static tree
3720 create_anonymous_class (location, type_name)
3721     int location;
3722     tree type_name;
3723 {
3724   char buffer [80];
3725   tree super = NULL_TREE, itf = NULL_TREE;
3726   tree id, type_decl, class;
3727
3728   /* The unqualified name of the anonymous class. It's just a number. */
3729   sprintf (buffer, "%d", anonymous_class_counter++);
3730   id = build_wfl_node (get_identifier (buffer));
3731   EXPR_WFL_LINECOL (id) = location;
3732
3733   /* We know about the type to extend/implement. We go ahead */
3734   if ((type_decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (type_name))))
3735     {
3736       /* Create a class which either implements on extends the designated
3737          class. The class bears an innacessible name. */
3738       if (CLASS_INTERFACE (type_decl))
3739         {
3740           /* It's OK to modify it here. It's been already used and
3741              shouldn't be reused */
3742           ctxp->interface_number = 1;
3743           /* Interfaces should presented as a list of WFLs */
3744           itf = build_tree_list (type_name, NULL_TREE);
3745         }
3746       else
3747         super = type_name;
3748     }
3749
3750   class = create_class (ACC_FINAL, id, super, itf);
3751
3752   /* We didn't know anything about the stuff. We register a dependence. */
3753   if (!type_decl)
3754     register_incomplete_type (JDEP_ANONYMOUS, type_name, class, NULL_TREE);
3755
3756   ANONYMOUS_CLASS_P (TREE_TYPE (class)) = 1;
3757   return class;
3758 }
3759
3760 /* Create a class in pass1 and return its decl. Return class
3761    interface's decl in pass 2.  */
3762
3763 static tree
3764 create_class (flags, id, super, interfaces)
3765      int flags;
3766      tree id, super, interfaces;
3767 {
3768   tree raw_name = EXPR_WFL_NODE (id);
3769   tree class_id, decl;
3770   tree super_decl_type;
3771
3772   class_id = parser_qualified_classname (0, raw_name);
3773   decl = IDENTIFIER_CLASS_VALUE (class_id);
3774   EXPR_WFL_NODE (id) = class_id;
3775
3776   /* Basic check: scope, redefinition, modifiers */
3777   if (check_class_interface_creation (0, flags, raw_name, class_id, decl, id))
3778     {
3779       PUSH_ERROR ();
3780       return NULL_TREE;
3781     }
3782   
3783   /* Suspend the current parsing context if we're parsing an inner
3784      class or an anonymous class. */
3785   if (CPC_INNER_P ())
3786     java_parser_context_suspend ();
3787   /* Push a new context for (static) initialized upon declaration fields */
3788   java_parser_context_push_initialized_field ();
3789
3790   /* Class modifier check: 
3791        - Allowed modifier (already done at that point)
3792        - abstract AND final forbidden 
3793        - Public classes defined in the correct file */
3794   if ((flags & ACC_ABSTRACT) && (flags & ACC_FINAL))
3795     parse_error_context
3796       (id, "Class `%s' can't be declared both abstract and final",
3797        IDENTIFIER_POINTER (raw_name));
3798
3799   /* Create a new decl if DECL is NULL, otherwise fix it */
3800   decl = maybe_create_class_interface_decl (decl, raw_name, class_id, id);
3801
3802   /* If SUPER exists, use it, otherwise use Object */
3803   if (super)
3804     {
3805       /* Can't extend java.lang.Object */
3806       if (TREE_TYPE (IDENTIFIER_CLASS_VALUE (class_id)) == object_type_node)
3807         {
3808           parse_error_context (id, "Can't extend `java.lang.Object'");
3809           return NULL_TREE;
3810         }
3811
3812       super_decl_type = 
3813         register_incomplete_type (JDEP_SUPER, super, decl, NULL_TREE);
3814     }
3815   else if (TREE_TYPE (decl) != object_type_node)
3816     super_decl_type = object_type_node;
3817   /* We're defining java.lang.Object */
3818   else
3819     super_decl_type = NULL_TREE;
3820
3821   /* Set super info and mark the class a complete */
3822   set_super_info (flags, TREE_TYPE (decl), super_decl_type, 
3823                   ctxp->interface_number);
3824   ctxp->interface_number = 0;
3825   CLASS_COMPLETE_P (decl) = 1;
3826   add_superinterfaces (decl, interfaces);
3827
3828   /* If the class is a top level inner class, install an alias. */
3829   if (INNER_CLASS_DECL_P (decl) && CLASS_STATIC (decl))
3830     {
3831       tree alias = parser_qualified_classname (1, raw_name);
3832       IDENTIFIER_GLOBAL_VALUE (alias) = decl;
3833     }
3834
3835   /* Add the private this$<n> field, Replicate final locals still in
3836      scope as private final fields mangled like val$<local_name>.
3837      This doesn't not occur for top level (static) inner classes. */
3838   if (PURE_INNER_CLASS_DECL_P (decl))
3839     add_inner_class_fields (decl, current_function_decl);
3840
3841   /* If doing xref, store the location at which the inherited class
3842      (if any) was seen. */
3843   if (flag_emit_xref && super)
3844     DECL_INHERITED_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (super);
3845
3846   /* Eventually sets the @deprecated tag flag */
3847   CHECK_DEPRECATED (decl);
3848
3849   /* Reset the anonymous class counter when declaring non inner classes */
3850   if (!INNER_CLASS_DECL_P (decl))
3851     anonymous_class_counter = 1;
3852
3853   return decl;
3854 }
3855
3856 /* End a class declaration: register the statements used to create
3857    $finit$ and <clinit>, pop the current class and resume the prior
3858    parser context if necessary.  */
3859
3860 static void
3861 end_class_declaration (resume)
3862      int resume;
3863 {
3864   /* If an error occured, context weren't pushed and won't need to be
3865      popped by a resume. */
3866   int no_error_occured = ctxp->next && GET_CPC () != error_mark_node;
3867
3868   java_parser_context_pop_initialized_field ();
3869   POP_CPC ();
3870   if (resume && no_error_occured)
3871     java_parser_context_resume ();
3872
3873   /* 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   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 */
7301       if (METHOD_ABSTRACT (decl) || METHOD_NATIVE (decl)
7302           || DECL_CONSTRUCTOR_P (decl) || DECL_CLINIT_P (decl))
7303         continue;
7304       java_complete_expand_method (decl);
7305     }
7306
7307   /* If there is indeed a <clinit>, fully expand it now */
7308   if (clinit)
7309     {
7310       /* Prevent the use of `this' inside <clinit> */
7311       ctxp->explicit_constructor_p = 1;
7312       java_complete_expand_method (clinit);
7313       ctxp->explicit_constructor_p = 0;
7314     }
7315   
7316   /* We might have generated a class$ that we now want to expand */
7317   if (TYPE_DOT_CLASS (current_class))
7318     java_complete_expand_method (TYPE_DOT_CLASS (current_class));
7319
7320   /* Now verify constructor circularity (stop after the first one we
7321      prove wrong.) */
7322   if (!CLASS_INTERFACE (class_decl))
7323     for (decl = TYPE_METHODS (current_class); decl; decl = TREE_CHAIN (decl))
7324       if (DECL_CONSTRUCTOR_P (decl) 
7325           && verify_constructor_circularity (decl, decl))
7326         break;
7327
7328   /* Save the constant pool. We'll need to restore it later. */
7329   TYPE_CPOOL (current_class) = outgoing_cpool;
7330 }
7331
7332 /* Hold a list of catch clauses list. The first element of this list is
7333    the list of the catch clauses of the currently analysed try block. */
7334 static tree currently_caught_type_list;
7335
7336 /* Attempt to create <clinit>. Pre-expand static fields so they can be
7337    safely used in some other methods/constructors.  */
7338
7339 static tree
7340 maybe_generate_pre_expand_clinit (class_type)
7341      tree class_type;
7342 {
7343   tree current, mdecl;
7344
7345   if (!TYPE_CLINIT_STMT_LIST (class_type))
7346     return NULL_TREE;
7347
7348   /* Go through all static fields and pre expand them */
7349   for (current = TYPE_FIELDS (class_type); current; 
7350        current = TREE_CHAIN (current))
7351     if (FIELD_STATIC (current))
7352       build_field_ref (NULL_TREE, class_type, DECL_NAME (current));
7353
7354   /* Then build the <clinit> method */
7355   mdecl = create_artificial_method (class_type, ACC_STATIC, void_type_node,
7356                                     clinit_identifier_node, end_params_node);
7357   layout_class_method (class_type, CLASSTYPE_SUPER (class_type),
7358                        mdecl, NULL_TREE);
7359   start_artificial_method_body (mdecl);
7360
7361   /* We process the list of assignment we produced as the result of
7362      the declaration of initialized static field and add them as
7363      statement to the <clinit> method. */
7364   for (current = TYPE_CLINIT_STMT_LIST (class_type); current;
7365        current = TREE_CHAIN (current))
7366     {
7367       /* We build the assignment expression that will initialize the
7368          field to its value. There are strict rules on static
7369          initializers (8.5). FIXME */
7370       tree stmt = build_debugable_stmt (EXPR_WFL_LINECOL (current), current);
7371       java_method_add_stmt (mdecl, stmt);
7372     }
7373
7374   end_artificial_method_body (mdecl);
7375
7376   /* Now we want to place <clinit> as the last method for interface so
7377      that it doesn't interfere with the dispatch table based
7378      lookup. */
7379   if (CLASS_INTERFACE (TYPE_NAME (class_type))
7380       && TREE_CHAIN (TYPE_METHODS (class_type)))
7381     {
7382       tree current = 
7383         TYPE_METHODS (class_type) = TREE_CHAIN (TYPE_METHODS (class_type));
7384
7385       while (TREE_CHAIN (current))
7386         current = TREE_CHAIN (current);
7387       TREE_CHAIN (current) = mdecl;
7388       TREE_CHAIN (mdecl) = NULL_TREE;
7389     }
7390
7391   return mdecl;
7392 }
7393
7394 /* Complete and expand a method.  */
7395
7396 static void
7397 java_complete_expand_method (mdecl)
7398      tree mdecl;
7399 {
7400   current_function_decl = mdecl;
7401   /* Fix constructors before expanding them */
7402   if (DECL_CONSTRUCTOR_P (mdecl))
7403     fix_constructors (mdecl);
7404   
7405   /* Expand functions that have a body */
7406   if (DECL_FUNCTION_BODY (mdecl))
7407     {
7408       tree fbody = DECL_FUNCTION_BODY (mdecl);
7409       tree block_body = BLOCK_EXPR_BODY (fbody);
7410       tree exception_copy = NULL_TREE;
7411       expand_start_java_method (mdecl);
7412       build_result_decl (mdecl);
7413
7414       current_this 
7415         = (!METHOD_STATIC (mdecl) ? 
7416            BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl)) : NULL_TREE);
7417
7418       /* Purge the `throws' list of unchecked exceptions. If we're
7419          doing xref, save a copy of the list and re-install it
7420          later. */
7421       if (flag_emit_xref)
7422         exception_copy = copy_list (DECL_FUNCTION_THROWS (mdecl));
7423
7424       purge_unchecked_exceptions (mdecl);
7425
7426       /* Install exceptions thrown with `throws' */
7427       PUSH_EXCEPTIONS (DECL_FUNCTION_THROWS (mdecl));
7428
7429       if (block_body != NULL_TREE)
7430         {
7431           block_body = java_complete_tree (block_body);
7432
7433           if (!flag_emit_xref)
7434             check_for_initialization (block_body);
7435           ctxp->explicit_constructor_p = 0;
7436         }
7437
7438       BLOCK_EXPR_BODY (fbody) = block_body;
7439
7440       /* If we saw a return but couldn't evaluate it properly, we'll
7441          have an error_mark_node here. */
7442       if (block_body != error_mark_node
7443           && (block_body == NULL_TREE || CAN_COMPLETE_NORMALLY (block_body))
7444           && TREE_CODE (TREE_TYPE (TREE_TYPE (mdecl))) != VOID_TYPE
7445           && !flag_emit_xref)
7446         missing_return_error (current_function_decl);
7447
7448       complete_start_java_method (mdecl); 
7449
7450       /* Don't go any further if we've found error(s) during the
7451          expansion */
7452       if (!java_error_count)
7453         source_end_java_method ();
7454       else
7455         {
7456           pushdecl_force_head (DECL_ARGUMENTS (mdecl));
7457           poplevel (1, 0, 1);
7458         }
7459
7460       /* Pop the exceptions and sanity check */
7461       POP_EXCEPTIONS();
7462       if (currently_caught_type_list)
7463         fatal ("Exception list non empty - java_complete_expand_method");
7464
7465       if (flag_emit_xref)
7466         DECL_FUNCTION_THROWS (mdecl) = exception_copy;
7467     }
7468 }
7469
7470 \f
7471
7472 /* This section of the code deals with accessing enclosing context
7473    fields either directly by using the relevant access to this$<n> or
7474    by invoking an access method crafted for that purpose.  */
7475
7476 /* Build the necessary access from an inner class to an outer
7477    class. This routine could be optimized to cache previous result
7478    (decl, current_class and returned access).  When an access method
7479    needs to be generated, it always takes the form of a read. It might
7480    be later turned into a write by calling outer_field_access_fix.  */
7481
7482 static tree
7483 build_outer_field_access (id, decl)
7484      tree id, decl;
7485 {
7486   tree access = NULL_TREE;
7487   tree ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class)));
7488
7489   /* If decl's class is the direct outer class of the current_class,
7490      build the access as `this$<n>.<field>'. Not that we will break
7491      the `private' barrier if we're not emitting bytecodes. */
7492   if (ctx == DECL_CONTEXT (decl) 
7493       && (!FIELD_PRIVATE (decl) || !flag_emit_class_files ))
7494     {
7495       tree thisn = build_current_thisn (current_class);
7496       access = make_qualified_primary (build_wfl_node (thisn), 
7497                                        id, EXPR_WFL_LINECOL (id));
7498     }
7499   /* Otherwise, generate access methods to outer this and access the
7500      field (either using an access method or by direct access.) */
7501   else
7502     {
7503       int lc = EXPR_WFL_LINECOL (id);
7504
7505       /* Now we chain the required number of calls to the access$0 to
7506          get a hold to the enclosing instance we need, and the we
7507          build the field access. */
7508       access = build_access_to_thisn (ctx, DECL_CONTEXT (decl), lc);
7509
7510       /* If the field is private and we're generating bytecode, then
7511          we generate an access method */
7512       if (FIELD_PRIVATE (decl) && flag_emit_class_files )
7513         {
7514           tree name = build_outer_field_access_methods (decl);
7515           access = build_outer_field_access_expr (lc, DECL_CONTEXT (decl),
7516                                                   name, access, NULL_TREE);
7517         }
7518       /* Otherwise we use `access$(this$<j>). ... access$(this$<i>).<field>'.
7519          Once again we break the `private' access rule from a foreign
7520          class. */
7521       else
7522         access = make_qualified_primary (access, id, lc);
7523     }
7524   return resolve_expression_name (access, NULL);
7525 }
7526
7527 /* Return a non zero value if NODE describes an outer field inner
7528    access.  */
7529
7530 static int
7531 outer_field_access_p (type, decl)
7532     tree type, decl;
7533 {
7534   if (!INNER_CLASS_TYPE_P (type) 
7535       || TREE_CODE (decl) != FIELD_DECL
7536       || DECL_CONTEXT (decl) == type)
7537     return 0;
7538
7539   for (type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))); ;
7540        type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))))
7541     {
7542       if (type == DECL_CONTEXT (decl))
7543         return 1;
7544       if (!DECL_CONTEXT (TYPE_NAME (type)))
7545         break;
7546     }
7547
7548   return 0;
7549 }
7550
7551 /* Return a non zero value if NODE represents an outer field inner
7552    access that was been already expanded. As a side effect, it returns
7553    the name of the field being accessed and the argument passed to the
7554    access function, suitable for a regeneration of the access method
7555    call if necessary. */
7556
7557 static int
7558 outer_field_expanded_access_p (node, name, arg_type, arg)
7559     tree node, *name, *arg_type, *arg;
7560 {
7561   int identified = 0;
7562
7563   if (TREE_CODE (node) != CALL_EXPR)
7564     return 0;
7565
7566   /* Well, gcj generates slightly different tree nodes when compiling
7567      to native or bytecodes. It's the case for function calls. */
7568
7569   if (flag_emit_class_files 
7570       && TREE_CODE (node) == CALL_EXPR
7571       && OUTER_FIELD_ACCESS_IDENTIFIER_P (DECL_NAME (TREE_OPERAND (node, 0))))
7572     identified = 1;
7573   else if (!flag_emit_class_files)
7574     {
7575       node = TREE_OPERAND (node, 0);
7576       
7577       if (node && TREE_OPERAND (node, 0)
7578           && TREE_CODE (TREE_OPERAND (node, 0)) == ADDR_EXPR)
7579         {
7580           node = TREE_OPERAND (node, 0);
7581           if (TREE_OPERAND (node, 0)
7582               && TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL
7583               && (OUTER_FIELD_ACCESS_IDENTIFIER_P 
7584                   (DECL_NAME (TREE_OPERAND (node, 0)))))
7585             identified = 1;
7586         }
7587     }
7588
7589   if (identified && name && arg_type && arg)
7590     {
7591       tree argument = TREE_OPERAND (node, 1);
7592       *name = DECL_NAME (TREE_OPERAND (node, 0));
7593       *arg_type = TREE_TYPE (TREE_TYPE (TREE_VALUE (argument)));
7594       *arg = TREE_VALUE (argument);
7595     }
7596   return identified;
7597 }
7598
7599 /* Detect in NODE an outer field read access from an inner class and
7600    transform it into a write with RHS as an argument. This function is
7601    called from the java_complete_lhs when an assignment to a LHS can
7602    be identified. */
7603
7604 static tree
7605 outer_field_access_fix (wfl, node, rhs)
7606     tree wfl, node, rhs;
7607 {
7608   tree name, arg_type, arg;
7609   
7610   if (outer_field_expanded_access_p (node, &name, &arg_type, &arg))
7611     {
7612       /* At any rate, check whether we're trying to assign a value to
7613          a final. */
7614       tree accessed = (JDECL_P (node) ? node : 
7615                        (TREE_CODE (node) == COMPONENT_REF ? 
7616                         TREE_OPERAND (node, 1) : node));
7617       if (check_final_assignment (accessed, wfl))
7618         return error_mark_node;
7619   
7620       node = build_outer_field_access_expr (EXPR_WFL_LINECOL (wfl), 
7621                                             arg_type, name, arg, rhs);
7622       return java_complete_tree (node);
7623     }
7624   return NULL_TREE;
7625 }
7626
7627 /* Construct the expression that calls an access method:
7628      <type>.access$<n>(<arg1> [, <arg2>]); 
7629
7630    ARG2 can be NULL and will be omitted in that case. It will denote a
7631    read access.  */
7632
7633 static tree
7634 build_outer_field_access_expr (lc, type, access_method_name, arg1, arg2)
7635     int lc;
7636     tree type, access_method_name, arg1, arg2;
7637 {
7638   tree args, cn, access;
7639
7640   args = arg1 ? arg1 : 
7641     build_wfl_node (build_current_thisn (current_class));
7642   args = build_tree_list (NULL_TREE, args);
7643
7644   if (arg2)
7645     args = tree_cons (NULL_TREE, arg2, args);
7646
7647   access = build_method_invocation (build_wfl_node (access_method_name), args);
7648   cn = build_wfl_node (DECL_NAME (TYPE_NAME (type)));
7649   return make_qualified_primary (cn, access, lc);
7650 }
7651
7652 static tree
7653 build_new_access_id ()
7654 {
7655   static int access_n_counter = 1;
7656   char buffer [128];
7657
7658   sprintf (buffer, "access$%d", access_n_counter++);
7659   return get_identifier (buffer);
7660 }
7661
7662 /* Create the static access functions for the outer field DECL. We define a
7663    read:
7664      TREE_TYPE (<field>) access$<n> (DECL_CONTEXT (<field>) inst$) {
7665        return inst$.field;
7666      }
7667    and a write access:
7668      TREE_TYPE (<field>) access$<n> (DECL_CONTEXT (<field>) inst$,
7669                                      TREE_TYPE (<field>) value$) {
7670        return inst$.field = value$;
7671      }
7672    We should have a usage flags on the DECL so we can lazily turn the ones
7673    we're using for code generation. FIXME.
7674 */
7675
7676 static tree
7677 build_outer_field_access_methods (decl)
7678     tree decl;
7679 {
7680   tree id, args, stmt, mdecl;
7681   
7682   /* Check point, to be removed. FIXME */
7683   if (FIELD_INNER_ACCESS (decl) 
7684       && TREE_CODE (FIELD_INNER_ACCESS (decl)) != IDENTIFIER_NODE)
7685     abort ();
7686
7687   if (FIELD_INNER_ACCESS (decl))
7688     return FIELD_INNER_ACCESS (decl);
7689
7690   push_obstacks (&permanent_obstack, &permanent_obstack);
7691
7692   /* Create the identifier and a function named after it. */
7693   id = build_new_access_id ();
7694
7695   /* The identifier is marked as bearing the name of a generated write
7696      access function for outer field accessed from inner classes. */
7697   OUTER_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
7698
7699   /* Create the read access */
7700   args = build_tree_list (inst_id, build_pointer_type (DECL_CONTEXT (decl)));
7701   TREE_CHAIN (args) = end_params_node;
7702   stmt = make_qualified_primary (build_wfl_node (inst_id),
7703                                  build_wfl_node (DECL_NAME (decl)), 0);
7704   stmt = build_return (0, stmt);
7705   mdecl = build_outer_field_access_method (DECL_CONTEXT (decl), 
7706                                            TREE_TYPE (decl), id, args, stmt);
7707   DECL_FUNCTION_ACCESS_DECL (mdecl) = decl;
7708
7709   /* Create the write access method */
7710   args = build_tree_list (inst_id, build_pointer_type (DECL_CONTEXT (decl)));
7711   TREE_CHAIN (args) = build_tree_list (wpv_id, TREE_TYPE (decl));
7712   TREE_CHAIN (TREE_CHAIN (args)) = end_params_node;
7713   stmt = make_qualified_primary (build_wfl_node (inst_id),
7714                                  build_wfl_node (DECL_NAME (decl)), 0);
7715   stmt = build_return (0, build_assignment (ASSIGN_TK, 0, stmt,
7716                                             build_wfl_node (wpv_id)));
7717
7718   mdecl = build_outer_field_access_method (DECL_CONTEXT (decl), 
7719                                            TREE_TYPE (decl), id, args, stmt);
7720   DECL_FUNCTION_ACCESS_DECL (mdecl) = decl;
7721   pop_obstacks ();
7722
7723   /* Return the access name */
7724   return FIELD_INNER_ACCESS (decl) = id;
7725 }
7726
7727 /* Build an field access method NAME.  */
7728
7729 static tree 
7730 build_outer_field_access_method (class, type, name, args, body)
7731     tree class, type, name, args, body;
7732 {
7733   tree saved_current_function_decl, mdecl;
7734
7735   /* Create the method */
7736   mdecl = create_artificial_method (class, ACC_STATIC, type, name, args);
7737   fix_method_argument_names (args, mdecl);
7738   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
7739
7740   /* Attach the method body. */
7741   saved_current_function_decl = current_function_decl;
7742   start_artificial_method_body (mdecl);
7743   java_method_add_stmt (mdecl, body);
7744   end_artificial_method_body (mdecl);
7745   current_function_decl = saved_current_function_decl;
7746
7747   return mdecl;
7748 }
7749
7750 \f
7751 /* This section deals with building access function necessary for
7752    certain kinds of method invocation from inner classes.  */
7753
7754 static tree
7755 build_outer_method_access_method (decl)
7756     tree decl;
7757 {
7758   tree saved_current_function_decl, mdecl;
7759   tree args = NULL_TREE, call_args = NULL_TREE;
7760   tree carg, id, body, class;
7761   char buffer [80];
7762   int parm_id_count = 0;
7763
7764   /* Test this abort with an access to a private field */
7765   if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), "access$"))
7766     abort ();
7767
7768   /* Check the cache first */
7769   if (DECL_FUNCTION_INNER_ACCESS (decl))
7770     return DECL_FUNCTION_INNER_ACCESS (decl);
7771
7772   class = DECL_CONTEXT (decl);
7773
7774   /* Obtain an access identifier and mark it */
7775   id = build_new_access_id ();
7776   OUTER_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
7777
7778   push_obstacks (&permanent_obstack, &permanent_obstack);
7779
7780   carg = TYPE_ARG_TYPES (TREE_TYPE (decl));
7781   /* Create the arguments, as much as the original */
7782   for (; carg && carg != end_params_node; 
7783        carg = TREE_CHAIN (carg))
7784     {
7785       sprintf (buffer, "write_parm_value$%d", parm_id_count++);
7786       args = chainon (args, build_tree_list (get_identifier (buffer), 
7787                                              TREE_VALUE (carg)));
7788     }
7789   args = chainon (args, end_params_node);
7790
7791   /* Create the method */
7792   mdecl = create_artificial_method (class, ACC_STATIC, 
7793                                     TREE_TYPE (TREE_TYPE (decl)), id, args);
7794   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
7795   /* There is a potential bug here. We should be able to use
7796      fix_method_argument_names, but then arg names get mixed up and
7797      eventually a constructor will have its this$0 altered and the
7798      outer context won't be assignment properly. The test case is
7799      stub.java FIXME */
7800   TYPE_ARG_TYPES (TREE_TYPE (mdecl)) = args;
7801
7802   /* Attach the method body. */
7803   saved_current_function_decl = current_function_decl;
7804   start_artificial_method_body (mdecl);
7805
7806   /* The actual method invocation uses the same args. When invoking a
7807      static methods that way, we don't want to skip the first
7808      argument. */
7809   carg = args;
7810   if (!METHOD_STATIC (decl))
7811     carg = TREE_CHAIN (carg);
7812   for (; carg && carg != end_params_node; carg = TREE_CHAIN (carg))
7813     call_args = tree_cons (NULL_TREE, build_wfl_node (TREE_PURPOSE (carg)),
7814                            call_args);
7815
7816   body = build_method_invocation (build_wfl_node (DECL_NAME (decl)), 
7817                                   call_args);
7818   if (!METHOD_STATIC (decl))
7819     body = make_qualified_primary (build_wfl_node (TREE_PURPOSE (args)), 
7820                                    body, 0);
7821   if (TREE_TYPE (TREE_TYPE (decl)) != void_type_node)
7822     body = build_return (0, body);
7823   java_method_add_stmt (mdecl,body);
7824   end_artificial_method_body (mdecl);
7825   current_function_decl = saved_current_function_decl;
7826   pop_obstacks ();
7827
7828   /* Back tag the access function so it know what it accesses */
7829   DECL_FUNCTION_ACCESS_DECL (decl) = mdecl;
7830
7831   /* Tag the current method so it knows it has an access generated */
7832   return DECL_FUNCTION_INNER_ACCESS (decl) = mdecl;
7833 }
7834
7835 \f
7836 /* This section of the code deals with building expressions to access
7837    the enclosing instance of an inner class. The enclosing instance is
7838    kept in a generated field called this$<n>, with <n> being the
7839    inner class nesting level (starting from 0.)  */
7840     
7841 /* Build an access to a given this$<n>, possibly by chaining access
7842    call to others. Access methods to this$<n> are build on the fly if
7843    necessary */
7844
7845 static tree
7846 build_access_to_thisn (from, to, lc)
7847      tree from, to;
7848      int lc;
7849 {
7850   tree access = NULL_TREE;
7851
7852   while (from != to)
7853     {
7854       tree access0_wfl, cn;
7855
7856       maybe_build_thisn_access_method (from);
7857       access0_wfl = build_wfl_node (access0_identifier_node);
7858       cn = build_wfl_node (DECL_NAME (TYPE_NAME (from)));
7859       EXPR_WFL_LINECOL (access0_wfl) = lc;
7860       
7861       if (!access)
7862         {
7863           access = build_current_thisn (current_class);
7864           access = build_wfl_node (access);
7865         }
7866       access = build_tree_list (NULL_TREE, access);
7867       access = build_method_invocation (access0_wfl, access);
7868       access = make_qualified_primary (cn, access, lc);
7869       
7870       from = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (from)));
7871     }
7872   return access;
7873 }
7874
7875 /* Build an access function to the this$<n> local to TYPE. NULL_TREE
7876    is returned if nothing needs to be generated. Otherwise, the method
7877    generated, fully walked and a method decl is returned.  
7878
7879    NOTE: These generated methods should be declared in a class file
7880    attribute so that they can't be referred to directly.  */
7881
7882 static tree
7883 maybe_build_thisn_access_method (type)
7884     tree type;
7885 {
7886   tree mdecl, args, stmt, rtype;
7887   tree saved_current_function_decl;
7888
7889   /* If TYPE is a top-level class, no access method is required.
7890      If there already is such an access method, bail out. */
7891   if (CLASS_ACCESS0_GENERATED_P (type) || !INNER_CLASS_TYPE_P (type))
7892     return NULL_TREE;
7893
7894   /* We generate the method. The method looks like:
7895      static <outer_of_type> access$0 (<type> inst$) { return inst$.this$<n>; }
7896   */
7897   push_obstacks (&permanent_obstack, &permanent_obstack);
7898   args = build_tree_list (inst_id, build_pointer_type (type));
7899   TREE_CHAIN (args) = end_params_node;
7900   rtype = build_pointer_type (TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))));
7901   mdecl = create_artificial_method (type, ACC_STATIC, rtype,
7902                                     access0_identifier_node, args);
7903   fix_method_argument_names (args, mdecl);
7904   layout_class_method (type, NULL_TREE, mdecl, NULL_TREE);
7905   stmt = build_current_thisn (type);
7906   stmt = make_qualified_primary (build_wfl_node (inst_id), 
7907                                  build_wfl_node (stmt), 0);
7908   stmt = build_return (0, stmt);
7909
7910   saved_current_function_decl = current_function_decl;
7911   start_artificial_method_body (mdecl);
7912   java_method_add_stmt (mdecl, stmt);
7913   end_artificial_method_body (mdecl);
7914   current_function_decl = saved_current_function_decl;
7915   pop_obstacks ();
7916
7917   CLASS_ACCESS0_GENERATED_P (type) = 1;
7918
7919   return mdecl;
7920 }
7921
7922 /* Craft an correctly numbered `this$<n>'string. this$0 is used for
7923    the first level of innerclassing. this$1 for the next one, etc...
7924    This function can be invoked with TYPE to NULL, available and then
7925    has to count the parser context.  */
7926
7927 static tree
7928 build_current_thisn (type)
7929     tree type;
7930 {
7931   static int saved_i = -1;
7932   static tree saved_thisn = NULL_TREE;
7933
7934   tree decl;
7935   char buffer [80];
7936   int i = 0;
7937
7938   if (type)
7939     {
7940       static tree saved_type = NULL_TREE;
7941       static int saved_type_i = 0;
7942
7943       if (type == saved_type)
7944         i = saved_type_i;
7945       else
7946         {
7947           for (i = -1, decl = DECL_CONTEXT (TYPE_NAME (type)); 
7948                decl; decl = DECL_CONTEXT (decl), i++)
7949             ;
7950       
7951           saved_type = type;
7952           saved_type_i = i;
7953         }
7954     }
7955   else
7956     i = list_length (GET_CPC_LIST ())-2;
7957
7958   if (i == saved_i)
7959     return saved_thisn;
7960     
7961   sprintf (buffer, "this$%d", i);
7962   saved_i = i;
7963   saved_thisn = get_identifier (buffer);
7964   return saved_thisn;
7965 }
7966
7967 /* Return the assignement to the hidden enclosing context `this$<n>'
7968    by the second incoming parameter to the innerclass constructor. The
7969    form used is `this.this$<n> = this$<n>;'.  */
7970
7971 static tree
7972 build_thisn_assign ()
7973 {
7974   if (current_class && PURE_INNER_CLASS_TYPE_P (current_class))
7975     {
7976       tree thisn = build_current_thisn (current_class);
7977       tree lhs = make_qualified_primary (build_wfl_node (this_identifier_node),
7978                                          build_wfl_node (thisn), 0);
7979       tree rhs = build_wfl_node (thisn);
7980       EXPR_WFL_SET_LINECOL (lhs, lineno, 0);
7981       return build_assignment (ASSIGN_TK, EXPR_WFL_LINECOL (lhs), lhs, rhs);
7982     }
7983   return NULL_TREE;
7984 }
7985
7986 \f
7987 /* Building the synthetic `class$' used to implement the `.class' 1.1
7988    extension for non primitive types. This method looks like:
7989
7990     static Class class$(String type) throws NoClassDefFoundError
7991     {
7992       try {return (java.lang.Class.forName (String));}
7993       catch (ClassNotFoundException e) {
7994         throw new NoClassDefFoundError(e.getMessage());}
7995     } */
7996
7997 static tree
7998 build_dot_class_method (class)
7999      tree class;
8000 {
8001 #define BWF(S) build_wfl_node (get_identifier ((S)))
8002 #define MQN(X,Y) make_qualified_name ((X), (Y), 0)
8003   tree args, tmp, saved_current_function_decl, mdecl;
8004   tree stmt, throw_stmt, catch, catch_block, try_block;
8005   tree catch_clause_param;
8006   tree class_not_found_exception, no_class_def_found_error;
8007
8008   static tree get_message_wfl, type_parm_wfl;
8009
8010   if (!get_message_wfl)
8011     {
8012       get_message_wfl = build_wfl_node (get_identifier ("getMessage"));
8013       type_parm_wfl = build_wfl_node (get_identifier ("type$"));
8014     }
8015
8016   /* Build the arguments */
8017   args = build_tree_list (get_identifier ("type$"),
8018                           build_pointer_type (string_type_node));
8019   TREE_CHAIN (args) = end_params_node;
8020
8021   /* Build the qualified name java.lang.Class.forName */
8022   tmp = MQN (MQN (MQN (BWF ("java"), 
8023                        BWF ("lang")), BWF ("Class")), BWF ("forName"));
8024
8025   /* For things we have to catch and throw */
8026   class_not_found_exception = 
8027     lookup_class (get_identifier ("java.lang.ClassNotFoundException"));
8028   no_class_def_found_error = 
8029     lookup_class (get_identifier ("java.lang.NoClassDefFoundError"));
8030   load_class (class_not_found_exception, 1);
8031   load_class (no_class_def_found_error, 1);
8032
8033   /* Create the "class$" function */
8034   mdecl = create_artificial_method (class, ACC_STATIC, 
8035                                     build_pointer_type (class_type_node),
8036                                     get_identifier ("class$"), args);
8037   DECL_FUNCTION_THROWS (mdecl) = build_tree_list (NULL_TREE,
8038                                                   no_class_def_found_error);
8039   
8040   /* We start by building the try block. We need to build:
8041        return (java.lang.Class.forName (type)); */
8042   stmt = build_method_invocation (tmp, 
8043                                   build_tree_list (NULL_TREE, type_parm_wfl));
8044   stmt = build_return (0, stmt);
8045   /* Put it in a block. That's the try block */
8046   try_block = build_expr_block (stmt, NULL_TREE);
8047
8048   /* Now onto the catch block. We start by building the expression
8049      throwing a new exception: 
8050        throw new NoClassDefFoundError (_.getMessage); */
8051   throw_stmt = make_qualified_name (build_wfl_node (wpv_id), 
8052                                     get_message_wfl, 0);
8053   throw_stmt = build_method_invocation (throw_stmt, NULL_TREE);
8054   
8055   /* Build new NoClassDefFoundError (_.getMessage) */
8056   throw_stmt = build_new_invocation 
8057     (build_wfl_node (get_identifier ("NoClassDefFoundError")),
8058      build_tree_list (build_pointer_type (string_type_node), throw_stmt));
8059
8060   /* Build the throw, (it's too early to use BUILD_THROW) */
8061   throw_stmt = build1 (THROW_EXPR, NULL_TREE, throw_stmt);
8062
8063   /* Build the catch block to encapsulate all this. We begin by
8064      building an decl for the catch clause parameter and link it to
8065      newly created block, the catch block. */
8066   catch_clause_param = 
8067     build_decl (VAR_DECL, wpv_id, 
8068                 build_pointer_type (class_not_found_exception));
8069   catch_block = build_expr_block (NULL_TREE, catch_clause_param);
8070   
8071   /* We initialize the variable with the exception handler. */
8072   catch = build (MODIFY_EXPR, NULL_TREE, catch_clause_param,
8073                  soft_exceptioninfo_call_node);
8074   add_stmt_to_block (catch_block, NULL_TREE, catch);
8075
8076   /* We add the statement throwing the new exception */
8077   add_stmt_to_block (catch_block, NULL_TREE, throw_stmt);
8078
8079   /* Build a catch expression for all this */
8080   catch_block = build1 (CATCH_EXPR, NULL_TREE, catch_block);
8081
8082   /* Build the try/catch sequence */
8083   stmt = build_try_statement (0, try_block, catch_block);
8084
8085   fix_method_argument_names (args, mdecl);
8086   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
8087   saved_current_function_decl = current_function_decl;
8088   start_artificial_method_body (mdecl);
8089   java_method_add_stmt (mdecl, stmt);
8090   end_artificial_method_body (mdecl);
8091   current_function_decl = saved_current_function_decl;
8092   TYPE_DOT_CLASS (class) = mdecl;
8093
8094   return mdecl;
8095 }
8096
8097 static tree
8098 build_dot_class_method_invocation (name)
8099      tree name;
8100 {
8101   tree s = make_node (STRING_CST);
8102   TREE_STRING_LENGTH (s) = IDENTIFIER_LENGTH (name);
8103   TREE_STRING_POINTER (s) = obstack_alloc (expression_obstack,
8104                                            TREE_STRING_LENGTH (s)+1);
8105   strcpy (TREE_STRING_POINTER (s), IDENTIFIER_POINTER (name));
8106   return build_method_invocation (build_wfl_node (get_identifier ("class$")),
8107                                   build_tree_list (NULL_TREE, s));
8108 }
8109
8110 /* This section of the code deals with constructor.  */
8111
8112 /* Craft a body for default constructor. Patch existing constructor
8113    bodies with call to super() and field initialization statements if
8114    necessary.  */
8115
8116 static void
8117 fix_constructors (mdecl)
8118      tree mdecl;
8119 {
8120   tree body = DECL_FUNCTION_BODY (mdecl);
8121   tree thisn_assign, compound = NULL_TREE;
8122   tree class_type = DECL_CONTEXT (mdecl);
8123
8124   if (!body)
8125     {
8126       /* It is an error for the compiler to generate a default
8127          constructor if the superclass doesn't have a constructor that
8128          takes no argument, or the same args for an anonymous class */
8129       if (verify_constructor_super (mdecl))
8130         {
8131           tree sclass_decl = TYPE_NAME (CLASSTYPE_SUPER (class_type));
8132           tree save = DECL_NAME (mdecl);
8133           const char *n = IDENTIFIER_POINTER (DECL_NAME (sclass_decl));
8134           DECL_NAME (mdecl) = DECL_NAME (sclass_decl);
8135           parse_error_context
8136             (lookup_cl (TYPE_NAME (class_type)), 
8137              "No constructor matching `%s' found in class `%s'",
8138              lang_printable_name (mdecl, 0), n);
8139           DECL_NAME (mdecl) = save;
8140         }
8141       
8142       /* The constructor body must be crafted by hand. It's the
8143          constructor we defined when we realize we didn't have the
8144          CLASSNAME() constructor */
8145       start_artificial_method_body (mdecl);
8146       
8147       /* We don't generate a super constructor invocation if we're
8148          compiling java.lang.Object. build_super_invocation takes care
8149          of that. */
8150       compound = java_method_add_stmt (mdecl, build_super_invocation (mdecl));
8151
8152       /* Insert the instance initializer block right here, after the
8153          super invocation. */
8154       add_instance_initializer (mdecl);
8155
8156       /* Insert an assignment to the this$<n> hidden field, if
8157          necessary */
8158       if ((thisn_assign = build_thisn_assign ()))
8159         java_method_add_stmt (mdecl, thisn_assign);
8160
8161       end_artificial_method_body (mdecl);
8162     }
8163   /* Search for an explicit constructor invocation */
8164   else 
8165     {
8166       int found = 0;
8167       tree main_block = BLOCK_EXPR_BODY (body);
8168       
8169       while (body)
8170         switch (TREE_CODE (body))
8171           {
8172           case CALL_EXPR:
8173             found = CALL_EXPLICIT_CONSTRUCTOR_P (body);
8174             body = NULL_TREE;
8175             break;
8176           case COMPOUND_EXPR:
8177           case EXPR_WITH_FILE_LOCATION:
8178             body = TREE_OPERAND (body, 0);
8179             break;
8180           case BLOCK:
8181             body = BLOCK_EXPR_BODY (body);
8182             break;
8183           default:
8184             found = 0;
8185             body = NULL_TREE;
8186           }
8187       /* The constructor is missing an invocation of super() */
8188       if (!found)
8189         compound = add_stmt_to_compound (compound, NULL_TREE,
8190                                          build_super_invocation (mdecl));
8191       
8192       /* Insert the instance initializer block right here, after the
8193          super invocation. */
8194       add_instance_initializer (mdecl);
8195
8196       /* Generate the assignment to this$<n>, if necessary */
8197       if ((thisn_assign = build_thisn_assign ()))
8198         compound = add_stmt_to_compound (compound, NULL_TREE, thisn_assign);
8199
8200       /* Fix the constructor main block if we're adding extra stmts */
8201       if (compound)
8202         {
8203           compound = add_stmt_to_compound (compound, NULL_TREE,
8204                                            BLOCK_EXPR_BODY (main_block));
8205           BLOCK_EXPR_BODY (main_block) = compound;
8206         }
8207     }
8208 }
8209
8210 /* Browse constructors in the super class, searching for a constructor
8211    that doesn't take any argument. Return 0 if one is found, 1
8212    otherwise.  If the current class is an anonymous inner class, look
8213    for something that has the same signature. */
8214
8215 static int
8216 verify_constructor_super (mdecl)
8217      tree mdecl;
8218 {
8219   tree class = CLASSTYPE_SUPER (current_class);
8220   tree sdecl;
8221
8222   if (!class)
8223     return 0;
8224
8225   if (ANONYMOUS_CLASS_P (current_class))
8226     {
8227       tree mdecl_arg_type;
8228       SKIP_THIS_AND_ARTIFICIAL_PARMS (mdecl_arg_type, mdecl);
8229       for (sdecl = TYPE_METHODS (class); sdecl; sdecl = TREE_CHAIN (sdecl))
8230         if (DECL_CONSTRUCTOR_P (sdecl))
8231           {
8232             tree arg_type;
8233             for (arg_type = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (sdecl)));
8234                  arg_type != end_params_node && 
8235                    mdecl_arg_type != end_params_node;
8236                  arg_type = TREE_CHAIN (arg_type), 
8237                  mdecl_arg_type = TREE_CHAIN (mdecl_arg_type))
8238               if (TREE_VALUE (arg_type) != TREE_VALUE (mdecl_arg_type))
8239                 break;
8240
8241             if (arg_type == end_params_node && 
8242                 mdecl_arg_type == end_params_node)
8243               return 0;
8244           }
8245     }
8246   else
8247     {
8248       for (sdecl = TYPE_METHODS (class); sdecl; sdecl = TREE_CHAIN (sdecl))
8249         {
8250           if (DECL_CONSTRUCTOR_P (sdecl)
8251               && TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (sdecl))) 
8252                  == end_params_node)
8253             return 0;
8254         }
8255     }
8256   return 1;
8257 }
8258
8259 /* Generate code for all context remembered for code generation.  */
8260
8261 void
8262 java_expand_classes ()
8263 {
8264   int save_error_count = 0;
8265   static struct parser_ctxt *saved_ctxp = NULL;
8266
8267   java_parse_abort_on_error ();
8268   if (!(ctxp = ctxp_for_generation))
8269     return;
8270   java_layout_classes ();
8271   java_parse_abort_on_error ();
8272
8273   /* The list of packages declaration seen so far needs to be
8274      reversed, so that package declared in a file being compiled gets
8275      priority over packages declared as a side effect of parsing other
8276      files.*/
8277   package_list = nreverse (package_list);
8278
8279   saved_ctxp = ctxp_for_generation;
8280   for (; ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
8281     {
8282       ctxp = ctxp_for_generation;
8283       lang_init_source (2);            /* Error msgs have method prototypes */
8284       java_complete_expand_classes (); /* Complete and expand classes */
8285       java_parse_abort_on_error ();
8286     }
8287
8288   /* Find anonymous classes and expand their constructor, now they
8289      have been fixed. */
8290   for (ctxp_for_generation = saved_ctxp;
8291        ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
8292     {
8293       tree current;
8294       ctxp = ctxp_for_generation;
8295       for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
8296         {
8297           current_class = TREE_TYPE (current);
8298           if (ANONYMOUS_CLASS_P (current_class))
8299             {
8300               tree d;
8301               for (d = TYPE_METHODS (current_class); d; d = TREE_CHAIN (d))
8302                 {
8303                   if (DECL_CONSTRUCTOR_P (d))
8304                     {
8305                       restore_line_number_status (1);
8306                       reset_method_name (d);
8307                       java_complete_expand_method (d);
8308                       restore_line_number_status (0);
8309                       break;    /* We now there are no other ones */
8310                     }
8311                 }
8312             }
8313         }
8314     }
8315
8316   /* If we've found error at that stage, don't try to generate
8317      anything, unless we're emitting xrefs or checking the syntax only
8318      (but not using -fsyntax-only for the purpose of generating
8319      bytecode. */
8320   if (java_error_count && !flag_emit_xref 
8321       && (!flag_syntax_only && !flag_emit_class_files))
8322     return;
8323
8324   /* Now things are stable, go for generation of the class data. */
8325   for (ctxp_for_generation = saved_ctxp;
8326        ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
8327     {
8328       tree current;
8329       ctxp = ctxp_for_generation;
8330       for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
8331         {
8332           current_class = TREE_TYPE (current);
8333           outgoing_cpool = TYPE_CPOOL (current_class);
8334           if (flag_emit_class_files)
8335             write_classfile (current_class);
8336           if (flag_emit_xref)
8337             expand_xref (current_class);
8338           else if (! flag_syntax_only)
8339             finish_class ();
8340         }
8341     }
8342 }
8343
8344 /* Wrap non WFL PRIMARY around a WFL and set EXPR_WFL_QUALIFICATION to
8345    a tree list node containing RIGHT. Fore coming RIGHTs will be
8346    chained to this hook. LOCATION contains the location of the
8347    separating `.' operator.  */
8348
8349 static tree
8350 make_qualified_primary (primary, right, location)
8351      tree primary, right;
8352      int location;
8353 {
8354   tree wfl;
8355
8356   if (TREE_CODE (primary) != EXPR_WITH_FILE_LOCATION)
8357     wfl = build_wfl_wrap (primary);
8358   else
8359     {
8360       wfl = primary;
8361       /* If wfl wasn't qualified, we build a first anchor */
8362       if (!EXPR_WFL_QUALIFICATION (wfl))
8363         EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (wfl, NULL_TREE);
8364     }
8365
8366   /* And chain them */
8367   EXPR_WFL_LINECOL (right) = location;
8368   chainon (EXPR_WFL_QUALIFICATION (wfl), build_tree_list (right, NULL_TREE));
8369   PRIMARY_P (wfl) =  1;
8370   return wfl;
8371 }
8372
8373 /* Simple merge of two name separated by a `.' */
8374
8375 static tree
8376 merge_qualified_name (left, right)
8377      tree left, right;
8378 {
8379   tree node;
8380   if (!left && !right)
8381     return NULL_TREE;
8382
8383   if (!left)
8384     return right;
8385
8386   if (!right)
8387     return left;
8388
8389   obstack_grow (&temporary_obstack, IDENTIFIER_POINTER (left),
8390                 IDENTIFIER_LENGTH (left));
8391   obstack_1grow (&temporary_obstack, '.');
8392   obstack_grow0 (&temporary_obstack, IDENTIFIER_POINTER (right),
8393                  IDENTIFIER_LENGTH (right));
8394   node =  get_identifier (obstack_base (&temporary_obstack));
8395   obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
8396   QUALIFIED_P (node) = 1;
8397   return node;
8398 }
8399
8400 /* Merge the two parts of a qualified name into LEFT.  Set the
8401    location information of the resulting node to LOCATION, usually
8402    inherited from the location information of the `.' operator. */
8403
8404 static tree
8405 make_qualified_name (left, right, location)
8406      tree left, right;
8407      int location;
8408 {
8409 #ifdef USE_COMPONENT_REF
8410   tree node = build (COMPONENT_REF, NULL_TREE, left, right);
8411   EXPR_WFL_LINECOL (node) = location;
8412   return node;
8413 #else
8414   tree left_id = EXPR_WFL_NODE (left);
8415   tree right_id = EXPR_WFL_NODE (right);
8416   tree wfl, merge;
8417
8418   merge = merge_qualified_name (left_id, right_id);
8419
8420   /* Left wasn't qualified and is now qualified */
8421   if (!QUALIFIED_P (left_id))
8422     {
8423       tree wfl = build_expr_wfl (left_id, ctxp->filename, 0, 0);
8424       EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (left);
8425       EXPR_WFL_QUALIFICATION (left) = build_tree_list (wfl, NULL_TREE);
8426     }
8427   
8428   wfl = build_expr_wfl (right_id, ctxp->filename, 0, 0);
8429   EXPR_WFL_LINECOL (wfl) = location;
8430   chainon (EXPR_WFL_QUALIFICATION (left), build_tree_list (wfl, NULL_TREE));
8431
8432   EXPR_WFL_NODE (left) = merge;
8433   return left;
8434 #endif
8435 }
8436
8437 /* Extract the last identifier component of the qualified in WFL. The
8438    last identifier is removed from the linked list */
8439
8440 static tree
8441 cut_identifier_in_qualified (wfl)
8442      tree wfl;
8443 {
8444   tree q;
8445   tree previous = NULL_TREE;
8446   for (q = EXPR_WFL_QUALIFICATION (wfl); ; previous = q, q = TREE_CHAIN (q))
8447     if (!TREE_CHAIN (q))
8448       {
8449         if (!previous)
8450           fatal ("Operating on a non qualified qualified WFL - cut_identifier_in_qualified");
8451         TREE_CHAIN (previous) = NULL_TREE;
8452         return TREE_PURPOSE (q);
8453       }
8454 }
8455
8456 /* Resolve the expression name NAME. Return its decl.  */
8457
8458 static tree
8459 resolve_expression_name (id, orig)
8460      tree id;
8461      tree *orig;
8462 {
8463   tree name = EXPR_WFL_NODE (id);
8464   tree decl;
8465
8466   /* 6.5.5.1: Simple expression names */
8467   if (!PRIMARY_P (id) && !QUALIFIED_P (name))
8468     {
8469       /* 15.13.1: NAME can appear within the scope of a local variable
8470          declaration */
8471       if ((decl = IDENTIFIER_LOCAL_VALUE (name)))
8472         return decl;
8473
8474       /* 15.13.1: NAME can appear within a class declaration */
8475       else 
8476         {
8477           decl = lookup_field_wrapper (current_class, name);
8478           if (decl)
8479             {
8480               tree access = NULL_TREE;
8481               int fs = FIELD_STATIC (decl);
8482
8483               /* If we're accessing an outer scope local alias, make
8484                  sure we change the name of the field we're going to
8485                  build access to. */
8486               if (FIELD_LOCAL_ALIAS_USED (decl))
8487                 name = DECL_NAME (decl);
8488
8489               /* Instance variable (8.3.1.1) can't appear within
8490                  static method, static initializer or initializer for
8491                  a static variable. */
8492               if (!fs && METHOD_STATIC (current_function_decl))
8493                 {
8494                   static_ref_err (id, name, current_class);
8495                   return error_mark_node;
8496                 }
8497               /* Instance variables can't appear as an argument of
8498                  an explicit constructor invocation */
8499               if (!fs && ctxp->explicit_constructor_p)
8500                 {
8501                   parse_error_context
8502                     (id, "Can't reference `%s' before the superclass constructor has been called", IDENTIFIER_POINTER (name));
8503                   return error_mark_node;
8504                 }
8505
8506               /* If we're processing an inner class and we're trying
8507                  to access a field belonging to an outer class, build
8508                  the access to the field */
8509               if (!fs && outer_field_access_p (current_class, decl))
8510                 return build_outer_field_access (id, decl);
8511
8512               /* Otherwise build what it takes to access the field */
8513               access = build_field_ref ((fs ? NULL_TREE : current_this),
8514                                         DECL_CONTEXT (decl), name);
8515               if (fs && !flag_emit_class_files && !flag_emit_xref)
8516                 access = build_class_init (DECL_CONTEXT (access), access);
8517               /* We may be asked to save the real field access node */
8518               if (orig)
8519                 *orig = access;
8520               /* And we return what we got */
8521               return access;
8522             }
8523           /* Fall down to error report on undefined variable */
8524         }
8525     }
8526   /* 6.5.5.2 Qualified Expression Names */
8527   else
8528     {
8529       if (orig)
8530         *orig = NULL_TREE;
8531       qualify_ambiguous_name (id);
8532       /* 15.10.1 Field Access Using a Primary and/or Expression Name */
8533       /* 15.10.2: Accessing Superclass Members using super */
8534       return resolve_field_access (id, orig, NULL);
8535     }
8536
8537   /* We've got an error here */
8538   parse_error_context (id, "Undefined variable `%s'", 
8539                        IDENTIFIER_POINTER (name));
8540
8541   return error_mark_node;
8542 }
8543
8544 static void
8545 static_ref_err (wfl, field_id, class_type)
8546     tree wfl, field_id, class_type;
8547 {
8548   parse_error_context 
8549     (wfl, 
8550      "Can't make a static reference to nonstatic variable `%s' in class `%s'",
8551      IDENTIFIER_POINTER (field_id), 
8552      IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class_type))));
8553 }
8554
8555 /* 15.10.1 Field Acess Using a Primary and/or Expression Name.
8556    We return something suitable to generate the field access. We also
8557    return the field decl in FIELD_DECL and its type in FIELD_TYPE.  If
8558    recipient's address can be null. */
8559
8560 static tree
8561 resolve_field_access (qual_wfl, field_decl, field_type)
8562      tree qual_wfl;
8563      tree *field_decl, *field_type;
8564 {
8565   int is_static = 0;
8566   tree field_ref;
8567   tree decl, where_found, type_found;
8568
8569   if (resolve_qualified_expression_name (qual_wfl, &decl,
8570                                          &where_found, &type_found))
8571     return error_mark_node;
8572
8573   /* Resolve the LENGTH field of an array here */
8574   if (DECL_NAME (decl) == length_identifier_node && TYPE_ARRAY_P (type_found)
8575       && ! flag_emit_class_files && ! flag_emit_xref)
8576     {
8577       tree length = build_java_array_length_access (where_found);
8578       field_ref =
8579         build_java_arraynull_check (type_found, length, int_type_node);
8580     }
8581   /* We might have been trying to resolve field.method(). In which
8582      case, the resolution is over and decl is the answer */
8583   else if (JDECL_P (decl) && IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)) == decl)
8584     field_ref = decl;
8585   else if (JDECL_P (decl))
8586     {
8587       int static_final_found = 0;
8588       if (!type_found)
8589         type_found = DECL_CONTEXT (decl);
8590       is_static = JDECL_P (decl) && FIELD_STATIC (decl);
8591       if (FIELD_FINAL (decl) 
8592           && JPRIMITIVE_TYPE_P (TREE_TYPE (decl))
8593           && DECL_LANG_SPECIFIC (decl)
8594           && DECL_INITIAL (decl))
8595         {
8596           field_ref = DECL_INITIAL (decl);
8597           static_final_found = 1;
8598         }
8599       else
8600         field_ref = build_field_ref ((is_static && !flag_emit_xref? 
8601                                       NULL_TREE : where_found), 
8602                                      type_found, DECL_NAME (decl));
8603       if (field_ref == error_mark_node)
8604         return error_mark_node;
8605       if (is_static && !static_final_found 
8606           && !flag_emit_class_files && !flag_emit_xref)
8607         field_ref = build_class_init (type_found, field_ref);
8608     }
8609   else
8610     field_ref = decl;
8611
8612   if (field_decl)
8613     *field_decl = decl;
8614   if (field_type)
8615     *field_type = (QUAL_DECL_TYPE (decl) ? 
8616                    QUAL_DECL_TYPE (decl) : TREE_TYPE (decl));
8617   return field_ref;
8618 }
8619
8620 /* If NODE is an access to f static field, strip out the class
8621    initialization part and return the field decl, otherwise, return
8622    NODE. */
8623
8624 static tree
8625 strip_out_static_field_access_decl (node)
8626     tree node;
8627 {
8628   if (TREE_CODE (node) == COMPOUND_EXPR)
8629     {
8630       tree op1 = TREE_OPERAND (node, 1);
8631       if (TREE_CODE (op1) == COMPOUND_EXPR)
8632          {
8633            tree call = TREE_OPERAND (op1, 0);
8634            if (TREE_CODE (call) == CALL_EXPR
8635                && TREE_CODE (TREE_OPERAND (call, 0)) == ADDR_EXPR
8636                && TREE_OPERAND (TREE_OPERAND (call, 0), 0)
8637                == soft_initclass_node)
8638              return TREE_OPERAND (op1, 1);
8639          }
8640       else if (JDECL_P (op1))
8641         return op1;
8642     }
8643   return node;
8644 }
8645
8646 /* 6.5.5.2: Qualified Expression Names */
8647
8648 static int
8649 resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
8650      tree wfl;
8651      tree *found_decl, *type_found, *where_found;
8652 {
8653   int from_type = 0;            /* Field search initiated from a type */
8654   int from_super = 0, from_cast = 0, from_qualified_this = 0;
8655   int previous_call_static = 0;
8656   int is_static;
8657   tree decl = NULL_TREE, type = NULL_TREE, q;
8658   /* For certain for of inner class instantiation */
8659   tree saved_current, saved_this;               
8660 #define RESTORE_THIS_AND_CURRENT_CLASS                          \
8661   { current_class = saved_current; current_this = saved_this;}
8662
8663   *type_found = *where_found = NULL_TREE;
8664
8665   for (q = EXPR_WFL_QUALIFICATION (wfl); q; q = TREE_CHAIN (q))
8666     {
8667       tree qual_wfl = QUAL_WFL (q);
8668       tree ret_decl;            /* for EH checking */
8669       int location;             /* for EH checking */
8670
8671       /* 15.10.1 Field Access Using a Primary */
8672       switch (TREE_CODE (qual_wfl))
8673         {
8674         case CALL_EXPR:
8675         case NEW_CLASS_EXPR:
8676           /* If the access to the function call is a non static field,
8677              build the code to access it. */
8678           if (JDECL_P (decl) && !FIELD_STATIC (decl))
8679             {
8680               decl = maybe_access_field (decl, *where_found, 
8681                                          DECL_CONTEXT (decl));
8682               if (decl == error_mark_node)
8683                 return 1;
8684             }
8685
8686           /* And code for the function call */
8687           if (complete_function_arguments (qual_wfl))
8688             return 1;
8689
8690           /* We might have to setup a new current class and a new this
8691              for the search of an inner class, relative to the type of
8692              a expression resolved as `decl'. The current values are
8693              saved and restored shortly after */
8694           saved_current = current_class;
8695           saved_this = current_this;
8696           if (decl && TREE_CODE (qual_wfl) == NEW_CLASS_EXPR)
8697             {
8698               current_class = type;
8699               current_this = decl;
8700             }
8701
8702           if (from_super && TREE_CODE (qual_wfl) == CALL_EXPR)
8703             CALL_USING_SUPER (qual_wfl) = 1;
8704           location = (TREE_CODE (qual_wfl) == CALL_EXPR ?
8705                       EXPR_WFL_LINECOL (TREE_OPERAND (qual_wfl, 0)) : 0);
8706           *where_found = patch_method_invocation (qual_wfl, decl, type, 
8707                                                   &is_static, &ret_decl);
8708           if (*where_found == error_mark_node)
8709             {
8710               RESTORE_THIS_AND_CURRENT_CLASS;
8711               return 1;
8712             }
8713           *type_found = type = QUAL_DECL_TYPE (*where_found);
8714
8715           /* If we're creating an inner class instance, check for that
8716              an enclosing instance is in scope */
8717           if (TREE_CODE (qual_wfl) == NEW_CLASS_EXPR
8718               && INNER_ENCLOSING_SCOPE_CHECK (type))
8719             {
8720               parse_error_context 
8721                 (qual_wfl, "No enclosing instance for inner class `%s' is in scope%s",
8722                  lang_printable_name (type, 0),
8723                  (!current_this ? "" :
8724                   "; an explicit one must be provided when creating this inner class"));
8725               RESTORE_THIS_AND_CURRENT_CLASS;
8726               return 1;
8727             }
8728
8729           /* In case we had to change then to resolve a inner class
8730              instantiation using a primary qualified by a `new' */
8731           RESTORE_THIS_AND_CURRENT_CLASS;
8732
8733           /* EH check */
8734           if (location)
8735             check_thrown_exceptions (location, ret_decl);
8736
8737           /* If the previous call was static and this one is too,
8738              build a compound expression to hold the two (because in
8739              that case, previous function calls aren't transported as
8740              forcoming function's argument. */
8741           if (previous_call_static && is_static)
8742             {
8743               decl = build (COMPOUND_EXPR, type, decl, *where_found);
8744               TREE_SIDE_EFFECTS (decl) = 1;
8745             }
8746           else
8747             {
8748               previous_call_static = is_static;
8749               decl = *where_found;
8750             }
8751           from_type = 0;
8752           continue;
8753
8754         case NEW_ARRAY_EXPR:
8755         case NEW_ANONYMOUS_ARRAY_EXPR:
8756           *where_found = decl = java_complete_tree (qual_wfl);
8757           if (decl == error_mark_node)
8758             return 1;
8759           *type_found = type = QUAL_DECL_TYPE (decl);
8760           CLASS_LOADED_P (type) = 1;
8761           continue;
8762
8763         case CONVERT_EXPR:
8764           *where_found = decl = java_complete_tree (qual_wfl);
8765           if (decl == error_mark_node)
8766             return 1;
8767           *type_found = type = QUAL_DECL_TYPE (decl);
8768           from_cast = 1;
8769           continue;
8770
8771         case CONDITIONAL_EXPR:
8772         case STRING_CST:
8773         case MODIFY_EXPR:
8774           *where_found = decl = java_complete_tree (qual_wfl);
8775           if (decl == error_mark_node)
8776             return 1;
8777           *type_found = type = QUAL_DECL_TYPE (decl);
8778           continue;
8779
8780         case ARRAY_REF:
8781           /* If the access to the function call is a non static field,
8782              build the code to access it. */
8783           if (JDECL_P (decl) && !FIELD_STATIC (decl))
8784             {
8785               decl = maybe_access_field (decl, *where_found, type);
8786               if (decl == error_mark_node)
8787                 return 1;
8788             }
8789           /* And code for the array reference expression */
8790           decl = java_complete_tree (qual_wfl);
8791           if (decl == error_mark_node)
8792             return 1;
8793           type = QUAL_DECL_TYPE (decl);
8794           continue;
8795
8796         case PLUS_EXPR:
8797           if ((decl = java_complete_tree (qual_wfl)) == error_mark_node)
8798             return 1;
8799           if ((type = patch_string (decl)))
8800             decl = type;
8801           *where_found = QUAL_RESOLUTION (q) = decl;
8802           *type_found = type = TREE_TYPE (decl);
8803           break;
8804
8805         case CLASS_LITERAL:
8806           if ((decl = java_complete_tree (qual_wfl)) == error_mark_node)
8807             return 1;
8808           *where_found = QUAL_RESOLUTION (q) = decl;
8809           *type_found = type = TREE_TYPE (decl);
8810           break;
8811
8812         default:
8813           /* Fix for -Wall Just go to the next statement. Don't
8814              continue */
8815           break;
8816         }
8817
8818       /* If we fall here, we weren't processing a (static) function call. */
8819       previous_call_static = 0;
8820
8821       /* It can be the keyword THIS */
8822       if (EXPR_WFL_NODE (qual_wfl) == this_identifier_node)
8823         {
8824           if (!current_this)
8825             {
8826               parse_error_context 
8827                 (wfl, "Keyword `this' used outside allowed context");
8828               return 1;
8829             }
8830           if (ctxp->explicit_constructor_p)
8831             {
8832               parse_error_context (wfl, "Can't reference `this' before the superclass constructor has been called");
8833               return 1;
8834             }
8835           /* We have to generate code for intermediate acess */
8836           if (!from_type || TREE_TYPE (TREE_TYPE (current_this)) == type)
8837             {
8838               *where_found = decl = current_this;
8839               *type_found = type = QUAL_DECL_TYPE (decl);
8840             }
8841           /* We're trying to access the this from somewhere else... */
8842           else
8843             {
8844               *where_found = decl = build_current_thisn (type);
8845               from_qualified_this = 1;
8846             }
8847
8848           from_type = 0;
8849           continue;
8850         }
8851
8852       /* 15.10.2 Accessing Superclass Members using SUPER */
8853       if (EXPR_WFL_NODE (qual_wfl) == super_identifier_node)
8854         {
8855           tree node;
8856           /* Check on the restricted use of SUPER */
8857           if (METHOD_STATIC (current_function_decl)
8858               || current_class == object_type_node)
8859             {
8860               parse_error_context 
8861                 (wfl, "Keyword `super' used outside allowed context");
8862               return 1;
8863             }
8864           /* Otherwise, treat SUPER as (SUPER_CLASS)THIS */
8865           node = build_cast (EXPR_WFL_LINECOL (qual_wfl), 
8866                              CLASSTYPE_SUPER (current_class),
8867                              build_this (EXPR_WFL_LINECOL (qual_wfl)));
8868           *where_found = decl = java_complete_tree (node);
8869           if (decl == error_mark_node)
8870             return 1;
8871           *type_found = type = QUAL_DECL_TYPE (decl);
8872           from_super = from_type = 1;
8873           continue;
8874         }
8875
8876       /* 15.13.1: Can't search for field name in packages, so we
8877          assume a variable/class name was meant. */
8878       if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
8879         {
8880           tree name = resolve_package (wfl, &q);
8881           if (name)
8882             {
8883               tree list;
8884               *where_found = decl = resolve_no_layout (name, qual_wfl);
8885               /* We wan't to be absolutely that the class is laid
8886                  out. We're going to search something inside it. */
8887               *type_found = type = TREE_TYPE (decl);
8888               layout_class (type);
8889               from_type = 1;
8890
8891               /* Fix them all the way down, if any are left. */
8892               if (q)
8893                 {
8894                   list = TREE_CHAIN (q);
8895                   while (list)
8896                     {
8897                       RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (list)) = 1;
8898                       RESOLVE_PACKAGE_NAME_P (QUAL_WFL (list)) = 0;
8899                       list = TREE_CHAIN (list);
8900                     }
8901                 }
8902             }
8903           else
8904             {
8905               if (from_super || from_cast)
8906                 parse_error_context 
8907                   ((from_cast ? qual_wfl : wfl),
8908                    "No variable `%s' defined in class `%s'",
8909                    IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
8910                    lang_printable_name (type, 0));
8911               else
8912                 parse_error_context
8913                   (qual_wfl, "Undefined variable or class name: `%s'",
8914                    IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)));
8915               return 1;
8916             }
8917         }
8918
8919       /* We have a type name. It's been already resolved when the
8920          expression was qualified. */
8921       else if (RESOLVE_TYPE_NAME_P (qual_wfl))
8922         {
8923           if (!(decl = QUAL_RESOLUTION (q)))
8924             return 1;           /* Error reported already */
8925
8926           /* Sneak preview. If next we see a `new', we're facing a
8927              qualification with resulted in a type being selected
8928              instead of a field.  Report the error */
8929           if(TREE_CHAIN (q) 
8930              && TREE_CODE (TREE_PURPOSE (TREE_CHAIN (q))) == NEW_CLASS_EXPR)
8931             {
8932               parse_error_context (qual_wfl, "Undefined variable `%s'",
8933                                    IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
8934               return 1;
8935             }
8936
8937           if (not_accessible_p (TREE_TYPE (decl), decl, 0))
8938             {
8939               parse_error_context 
8940                 (qual_wfl, "Can't access %s field `%s.%s' from `%s'",
8941                  java_accstring_lookup (get_access_flags_from_decl (decl)),
8942                  GET_TYPE_NAME (type),
8943                  IDENTIFIER_POINTER (DECL_NAME (decl)),
8944                  IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
8945               return 1;
8946             }
8947           check_deprecation (qual_wfl, decl);
8948
8949           type = TREE_TYPE (decl);
8950           from_type = 1;
8951         }
8952       /* We resolve and expression name */
8953       else 
8954         {
8955           tree field_decl = NULL_TREE;
8956
8957           /* If there exists an early resolution, use it. That occurs
8958              only once and we know that there are more things to
8959              come. Don't do that when processing something after SUPER
8960              (we need more thing to be put in place below */
8961           if (!from_super && QUAL_RESOLUTION (q))
8962             {
8963               decl = QUAL_RESOLUTION (q);
8964               if (!type)
8965                 {
8966                   if (TREE_CODE (decl) == FIELD_DECL && !FIELD_STATIC (decl))
8967                     {
8968                       if (current_this)
8969                         *where_found = current_this;
8970                       else
8971                         {
8972                           static_ref_err (qual_wfl, DECL_NAME (decl),
8973                                           current_class);
8974                           return 1;
8975                         }
8976                     }
8977                   else
8978                     {
8979                       *where_found = TREE_TYPE (decl);
8980                       if (TREE_CODE (*where_found) == POINTER_TYPE)
8981                         *where_found = TREE_TYPE (*where_found);
8982                     }
8983                 }
8984             }
8985
8986           /* We have to search for a field, knowing the type of its
8987              container. The flag FROM_TYPE indicates that we resolved
8988              the last member of the expression as a type name, which
8989              means that for the resolution of this field, we'll look
8990              for other errors than if it was resolved as a member of
8991              an other field. */
8992           else
8993             {
8994               int is_static;
8995               tree field_decl_type; /* For layout */
8996
8997               if (!from_type && !JREFERENCE_TYPE_P (type))
8998                 {
8999                   parse_error_context 
9000                     (qual_wfl, "Attempt to reference field `%s' in `%s %s'",
9001                      IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
9002                      lang_printable_name (type, 0),
9003                      IDENTIFIER_POINTER (DECL_NAME (field_decl)));
9004                   return 1;
9005                 }
9006               
9007               field_decl = lookup_field_wrapper (type,
9008                                                  EXPR_WFL_NODE (qual_wfl));
9009               if (field_decl == NULL_TREE)
9010                 {
9011                   parse_error_context 
9012                     (qual_wfl, "No variable `%s' defined in type `%s'",
9013                      IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)), 
9014                      GET_TYPE_NAME (type));
9015                   return 1;
9016                 }
9017               if (field_decl == error_mark_node)
9018                 return 1;
9019
9020               /* Layout the type of field_decl, since we may need
9021                  it. Don't do primitive types or loaded classes. The
9022                  situation of non primitive arrays may not handled
9023                  properly here. FIXME */
9024               if (TREE_CODE (TREE_TYPE (field_decl)) == POINTER_TYPE)
9025                 field_decl_type = TREE_TYPE (TREE_TYPE (field_decl));
9026               else
9027                 field_decl_type = TREE_TYPE (field_decl);
9028               if (!JPRIMITIVE_TYPE_P (field_decl_type) 
9029                   && !CLASS_LOADED_P (field_decl_type)
9030                   && !TYPE_ARRAY_P (field_decl_type))
9031                 resolve_and_layout (field_decl_type, NULL_TREE);
9032               if (TYPE_ARRAY_P (field_decl_type))
9033                 CLASS_LOADED_P (field_decl_type) = 1;
9034               
9035               /* Check on accessibility here */
9036               if (not_accessible_p (type, field_decl, from_super))
9037                 {
9038                   parse_error_context 
9039                     (qual_wfl,
9040                      "Can't access %s field `%s.%s' from `%s'",
9041                      java_accstring_lookup 
9042                        (get_access_flags_from_decl (field_decl)),
9043                      GET_TYPE_NAME (type),
9044                      IDENTIFIER_POINTER (DECL_NAME (field_decl)),
9045                      IDENTIFIER_POINTER 
9046                        (DECL_NAME (TYPE_NAME (current_class))));
9047                   return 1;
9048                 }
9049               check_deprecation (qual_wfl, field_decl);
9050               
9051               /* There are things to check when fields are accessed
9052                  from type. There are no restrictions on a static
9053                  declaration of the field when it is accessed from an
9054                  interface */
9055               is_static = FIELD_STATIC (field_decl);
9056               if (!from_super && from_type 
9057                   && !TYPE_INTERFACE_P (type) 
9058                   && !is_static 
9059                   && (current_function_decl 
9060                       && METHOD_STATIC (current_function_decl)))
9061                 {
9062                   static_ref_err (qual_wfl, EXPR_WFL_NODE (qual_wfl), type);
9063                   return 1;
9064                 }
9065               from_cast = from_super = 0;
9066
9067               /* It's an access from a type but it isn't static, we
9068                  make it relative to `this'. */
9069               if (!is_static && from_type)
9070                 decl = current_this;
9071
9072               /* If we need to generate something to get a proper
9073                  handle on what this field is accessed from, do it
9074                  now. */
9075               if (!is_static)
9076                 {
9077                   decl = maybe_access_field (decl, *where_found, *type_found);
9078                   if (decl == error_mark_node)
9079                     return 1;
9080                 }
9081
9082               /* We want to keep the location were found it, and the type
9083                  we found. */
9084               *where_found = decl;
9085               *type_found = type;
9086
9087               /* Generate the correct expression for field access from
9088                  qualified this */
9089               if (from_qualified_this)
9090                 {
9091                   field_decl = build_outer_field_access (qual_wfl, field_decl);
9092                   from_qualified_this = 0;
9093                 }
9094
9095               /* This is the decl found and eventually the next one to
9096                  search from */
9097               decl = field_decl;
9098             }
9099           from_type = 0;
9100           type = QUAL_DECL_TYPE (decl);
9101
9102           /* Sneak preview. If decl is qualified by a `new', report
9103              the error here to be accurate on the peculiar construct */
9104           if (TREE_CHAIN (q) 
9105               && TREE_CODE (TREE_PURPOSE (TREE_CHAIN (q))) == NEW_CLASS_EXPR
9106               && !JREFERENCE_TYPE_P (type))
9107             {
9108               parse_error_context (qual_wfl, "Attempt to reference field `new' in a `%s'", 
9109                                    lang_printable_name (type, 0));
9110               return 1;
9111             }
9112         }
9113       /* `q' might have changed due to a after package resolution
9114          re-qualification */
9115       if (!q)
9116         break;
9117     }
9118   *found_decl = decl;
9119   return 0;
9120 }
9121
9122 /* 6.6 Qualified name and access control. Returns 1 if MEMBER (a decl)
9123    can't be accessed from REFERENCE (a record type). */
9124
9125 static int
9126 not_accessible_p (reference, member, from_super)
9127      tree reference, member;
9128      int from_super;
9129 {
9130   int access_flag = get_access_flags_from_decl (member);
9131
9132   /* Access always granted for members declared public */
9133   if (access_flag & ACC_PUBLIC)
9134     return 0;
9135   
9136   /* Check access on protected members */
9137   if (access_flag & ACC_PROTECTED)
9138     {
9139       /* Access granted if it occurs from within the package
9140          containing the class in which the protected member is
9141          declared */
9142       if (class_in_current_package (DECL_CONTEXT (member)))
9143         return 0;
9144
9145       /* If accessed with the form `super.member', then access is granted */
9146       if (from_super)
9147         return 0;
9148
9149       /* Otherwise, access is granted if occuring from the class where
9150          member is declared or a subclass of it */
9151       if (inherits_from_p (reference, DECL_CONTEXT (member)))
9152         return 0;
9153       return 1;
9154     }
9155
9156   /* Check access on private members. Access is granted only if it
9157      occurs from within the class in which it is declared. Exceptions
9158      are accesses from inner-classes. This section is probably not
9159      complete. FIXME */
9160   if (access_flag & ACC_PRIVATE)
9161     return (current_class == DECL_CONTEXT (member) ? 0 : 
9162             (INNER_CLASS_TYPE_P (current_class) ? 0 : 1));
9163
9164   /* Default access are permitted only when occuring within the
9165      package in which the type (REFERENCE) is declared. In other words,
9166      REFERENCE is defined in the current package */
9167   if (ctxp->package)
9168     return !class_in_current_package (reference);
9169
9170   /* Otherwise, access is granted */
9171   return 0;
9172 }
9173
9174 /* Test deprecated decl access.  */
9175 static void
9176 check_deprecation (wfl, decl)
9177      tree wfl, decl;
9178 {
9179   const char *file = DECL_SOURCE_FILE (decl);
9180   /* Complain if the field is deprecated and the file it was defined
9181      in isn't compiled at the same time the file which contains its
9182      use is */
9183   if (DECL_DEPRECATED (decl) 
9184       && !IS_A_COMMAND_LINE_FILENAME_P (get_identifier (file)))
9185     {
9186       char the [20];
9187       switch (TREE_CODE (decl))
9188         {
9189         case FUNCTION_DECL:
9190           strcpy (the, "method");
9191           break;
9192         case FIELD_DECL:
9193           strcpy (the, "field");
9194           break;
9195         case TYPE_DECL:
9196           strcpy (the, "class");
9197           break;
9198         default:
9199           fatal ("unexpected DECL code - check_deprecation");
9200         }
9201       parse_warning_context 
9202         (wfl, "The %s `%s' in class `%s' has been deprecated", 
9203          the, lang_printable_name (decl, 0),
9204          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)))));
9205     }
9206 }
9207
9208 /* Returns 1 if class was declared in the current package, 0 otherwise */
9209
9210 static int
9211 class_in_current_package (class)
9212      tree class;
9213 {
9214   static tree cache = NULL_TREE;
9215   int qualified_flag;
9216   tree left;
9217
9218   if (cache == class)
9219     return 1;
9220
9221   qualified_flag = QUALIFIED_P (DECL_NAME (TYPE_NAME (class)));
9222
9223   /* If the current package is empty and the name of CLASS is
9224      qualified, class isn't in the current package.  If there is a
9225      current package and the name of the CLASS is not qualified, class
9226      isn't in the current package */
9227   if ((!ctxp->package && qualified_flag) || (ctxp->package && !qualified_flag))
9228     return 0;
9229
9230   /* If there is not package and the name of CLASS isn't qualified,
9231      they belong to the same unnamed package */
9232   if (!ctxp->package && !qualified_flag)
9233     return 1;
9234
9235   /* Compare the left part of the name of CLASS with the package name */
9236   breakdown_qualified (&left, NULL, DECL_NAME (TYPE_NAME (class)));
9237   if (ctxp->package == left)
9238     {
9239       cache = class;
9240       return 1;
9241     }
9242   return 0;
9243 }
9244
9245 /* This function may generate code to access DECL from WHERE. This is
9246    done only if certain conditions meet.  */
9247
9248 static tree
9249 maybe_access_field (decl, where, type)
9250   tree decl, where, type;
9251 {
9252   if (TREE_CODE (decl) == FIELD_DECL && decl != current_this
9253       && !FIELD_STATIC (decl))
9254     decl = build_field_ref (where ? where : current_this, 
9255                             (type ? type : DECL_CONTEXT (decl)),
9256                             DECL_NAME (decl));
9257   return decl;
9258 }
9259
9260 /* Build a method invocation, by patching PATCH. If non NULL
9261    and according to the situation, PRIMARY and WHERE may be
9262    used. IS_STATIC is set to 1 if the invoked function is static. */
9263
9264 static tree
9265 patch_method_invocation (patch, primary, where, is_static, ret_decl)
9266      tree patch, primary, where;
9267      int *is_static;
9268      tree *ret_decl;
9269 {
9270   tree wfl = TREE_OPERAND (patch, 0);
9271   tree args = TREE_OPERAND (patch, 1);
9272   tree name = EXPR_WFL_NODE (wfl);
9273   tree list;
9274   int is_static_flag = 0;
9275   int is_super_init = 0;
9276   tree this_arg = NULL_TREE;
9277   
9278   /* Should be overriden if everything goes well. Otherwise, if
9279      something fails, it should keep this value. It stop the
9280      evaluation of a bogus assignment. See java_complete_tree,
9281      MODIFY_EXPR: for the reasons why we sometimes want to keep on
9282      evaluating an assignment */
9283   TREE_TYPE (patch) = error_mark_node;
9284
9285   /* Since lookup functions are messing with line numbers, save the
9286      context now.  */
9287   java_parser_context_save_global ();
9288
9289   /* 15.11.1: Compile-Time Step 1: Determine Class or Interface to Search */
9290
9291   /* Resolution of qualified name, excluding constructors */
9292   if (QUALIFIED_P (name) && !CALL_CONSTRUCTOR_P (patch))
9293     {
9294       tree identifier, identifier_wfl, type, resolved;
9295       /* Extract the last IDENTIFIER of the qualified
9296          expression. This is a wfl and we will use it's location
9297          data during error report. */
9298       identifier_wfl = cut_identifier_in_qualified (wfl);
9299       identifier = EXPR_WFL_NODE (identifier_wfl);
9300       
9301       /* Given the context, IDENTIFIER is syntactically qualified
9302          as a MethodName. We need to qualify what's before */
9303       qualify_ambiguous_name (wfl);
9304       resolved = resolve_field_access (wfl, NULL, NULL);
9305
9306       if (resolved == error_mark_node)
9307         PATCH_METHOD_RETURN_ERROR ();
9308
9309       type = GET_SKIP_TYPE (resolved);
9310       resolve_and_layout (type, NULL_TREE);
9311       list = lookup_method_invoke (0, identifier_wfl, type, identifier, args);
9312       args = nreverse (args);
9313
9314       /* We're resolving a call from a type */
9315       if (TREE_CODE (resolved) == TYPE_DECL)
9316         {
9317           if (CLASS_INTERFACE (resolved))
9318             {
9319               parse_error_context
9320                 (identifier_wfl,
9321                 "Can't make static reference to method `%s' in interface `%s'",
9322                  IDENTIFIER_POINTER (identifier), 
9323                  IDENTIFIER_POINTER (name));
9324               PATCH_METHOD_RETURN_ERROR ();
9325             }
9326           if (list && !METHOD_STATIC (list))
9327             {
9328               char *fct_name = xstrdup (lang_printable_name (list, 0));
9329               parse_error_context 
9330                 (identifier_wfl,
9331                  "Can't make static reference to method `%s %s' in class `%s'",
9332                  lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0), 
9333                  fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
9334               free (fct_name);
9335               PATCH_METHOD_RETURN_ERROR ();
9336             }
9337         }
9338       else
9339         this_arg = primary = resolved;
9340       
9341       /* IDENTIFIER_WFL will be used to report any problem further */
9342       wfl = identifier_wfl;
9343     }
9344   /* Resolution of simple names, names generated after a primary: or
9345      constructors */
9346   else
9347     {
9348       tree class_to_search = NULL_TREE;
9349       int lc;                   /* Looking for Constructor */
9350       
9351       /* We search constructor in their target class */
9352       if (CALL_CONSTRUCTOR_P (patch))
9353         {
9354           if (TREE_CODE (patch) == NEW_CLASS_EXPR)
9355             class_to_search = EXPR_WFL_NODE (wfl);
9356           else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) == 
9357                    this_identifier_node)
9358             class_to_search = NULL_TREE;
9359           else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) ==
9360                    super_identifier_node)
9361             {
9362               is_super_init = 1;
9363               if (CLASSTYPE_SUPER (current_class))
9364                 class_to_search = 
9365                   DECL_NAME (TYPE_NAME (CLASSTYPE_SUPER (current_class)));
9366               else
9367                 {
9368                   parse_error_context (wfl, "Can't invoke super constructor on java.lang.Object");
9369                   PATCH_METHOD_RETURN_ERROR ();
9370                 }
9371             }
9372
9373           /* Class to search is NULL if we're searching the current one */
9374           if (class_to_search)
9375             {
9376               class_to_search = resolve_and_layout (class_to_search, wfl);
9377
9378               if (!class_to_search)
9379                 {
9380                   parse_error_context 
9381                     (wfl, "Class `%s' not found in type declaration",
9382                      IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
9383                   PATCH_METHOD_RETURN_ERROR ();
9384                 }
9385               
9386               /* Can't instantiate an abstract class, but we can
9387                  invoke it's constructor. It's use within the `new'
9388                  context is denied here. */
9389               if (CLASS_ABSTRACT (class_to_search) 
9390                   && TREE_CODE (patch) == NEW_CLASS_EXPR)
9391                 {
9392                   parse_error_context 
9393                     (wfl, "Class `%s' is an abstract class. It can't be instantiated",
9394                      IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
9395                   PATCH_METHOD_RETURN_ERROR ();
9396                 }
9397
9398               class_to_search = TREE_TYPE (class_to_search);
9399             }
9400           else
9401             class_to_search = current_class;
9402           lc = 1;
9403         }
9404       /* This is a regular search in the local class, unless an
9405          alternate class is specified. */
9406       else
9407         {
9408           class_to_search = (where ? where : current_class);
9409           lc = 0;
9410         }
9411
9412       /* NAME is a simple identifier or comes from a primary. Search
9413          in the class whose declaration contain the method being
9414          invoked. */
9415       resolve_and_layout (class_to_search, NULL_TREE);
9416
9417       list = lookup_method_invoke (lc, wfl, class_to_search, name, args);
9418       /* Don't continue if no method were found, as the next statement
9419          can't be executed then. */
9420       if (!list)
9421         PATCH_METHOD_RETURN_ERROR ();
9422
9423       /* Check for static reference if non static methods */
9424       if (check_for_static_method_reference (wfl, patch, list, 
9425                                              class_to_search, primary))
9426         PATCH_METHOD_RETURN_ERROR ();
9427
9428       /* Check for inner classes creation from illegal contexts */
9429       if (lc && (INNER_CLASS_TYPE_P (class_to_search)
9430                  && !CLASS_STATIC (TYPE_NAME (class_to_search)))
9431           && INNER_ENCLOSING_SCOPE_CHECK (class_to_search))
9432         {
9433           parse_error_context 
9434             (wfl, "No enclosing instance for inner class `%s' is in scope%s",
9435              lang_printable_name (class_to_search, 0),
9436              (!current_this ? "" :
9437               "; an explicit one must be provided when creating this inner class"));
9438           PATCH_METHOD_RETURN_ERROR ();
9439         }
9440
9441       /* Non static methods are called with the current object extra
9442          argument. If patch a `new TYPE()', the argument is the value
9443          returned by the object allocator. If method is resolved as a
9444          primary, use the primary otherwise use the current THIS. */
9445       args = nreverse (args);
9446       if (TREE_CODE (patch) != NEW_CLASS_EXPR)
9447         {
9448           this_arg = primary ? primary : current_this;
9449
9450           /* If we're using an access method, things are different.
9451              There are two familly of cases:
9452
9453              1) We're not generating bytecodes:
9454
9455              - LIST is non static. It's invocation is transformed from
9456                x(a1,...,an) into this$<n>.x(a1,....an).
9457              - LIST is static. It's invocation is transformed from
9458                x(a1,...,an) into TYPE_OF(this$<n>).x(a1,....an)
9459
9460              2) We're generating bytecodes:
9461              
9462              - LIST is non static. It's invocation is transformed from
9463                x(a1,....,an) into access$<n>(this$<n>,a1,...,an).
9464              - LIST is static. It's invocation is transformed from
9465                x(a1,....,an) into TYPEOF(this$<n>).x(a1,....an).
9466
9467              Of course, this$<n> can be abitrary complex, ranging from
9468              this$0 (the immediate outer context) to 
9469              access$0(access$0(...(this$0))). 
9470              
9471              maybe_use_access_method returns a non zero value if the
9472              this_arg has to be moved into the (then generated) stub
9473              argument list. In the mean time, the selected function
9474              might have be replaced by a generated stub. */
9475           if (maybe_use_access_method (is_super_init, &list, &this_arg))
9476             args = tree_cons (NULL_TREE, this_arg, args);
9477         }
9478     }
9479
9480   /* Merge point of all resolution schemes. If we have nothing, this
9481      is an error, already signaled */
9482   if (!list) 
9483     PATCH_METHOD_RETURN_ERROR ();
9484
9485   /* Check accessibility, position the is_static flag, build and
9486      return the call */
9487   if (not_accessible_p (DECL_CONTEXT (current_function_decl), list, 0))
9488     {
9489       char *fct_name = xstrdup (lang_printable_name (list, 0));
9490       parse_error_context 
9491         (wfl, "Can't access %s method `%s %s.%s' from `%s'",
9492          java_accstring_lookup (get_access_flags_from_decl (list)),
9493          lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0), 
9494          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (list)))), 
9495          fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
9496       free (fct_name);
9497       PATCH_METHOD_RETURN_ERROR ();
9498     }
9499   check_deprecation (wfl, list);
9500
9501   /* If invoking a innerclass constructor, there are hidden parameters
9502      to pass */
9503   if (TREE_CODE (patch) == NEW_CLASS_EXPR 
9504       && PURE_INNER_CLASS_TYPE_P (DECL_CONTEXT (list)))
9505     {
9506       /* And make sure we add the accessed local variables to be saved
9507          in field aliases. */
9508       args = build_alias_initializer_parameter_list
9509         (AIPL_FUNCTION_CTOR_INVOCATION, DECL_CONTEXT (list), args, NULL);
9510
9511       /* We have to reverse things. Find out why. FIXME */
9512       if (ANONYMOUS_CLASS_P (DECL_CONTEXT (list)))
9513         args = nreverse (args);
9514       
9515       /* Secretely pass the current_this/primary as a second argument */
9516       if (primary || current_this)
9517         args = tree_cons (NULL_TREE, (primary ? primary : current_this), args);
9518       else
9519         args = tree_cons (NULL_TREE, integer_zero_node, args);
9520     }
9521
9522   is_static_flag = METHOD_STATIC (list);
9523   if (! METHOD_STATIC (list) && this_arg != NULL_TREE)
9524     args = tree_cons (NULL_TREE, this_arg, args);
9525
9526   /* In the context of an explicit constructor invocation, we can't
9527      invoke any method relying on `this'. Exceptions are: we're
9528      invoking a static function, primary exists and is not the current
9529      this, we're creating a new object. */
9530   if (ctxp->explicit_constructor_p 
9531       && !is_static_flag 
9532       && (!primary || primary == current_this)
9533       && (TREE_CODE (patch) != NEW_CLASS_EXPR))
9534     {
9535       parse_error_context (wfl, "Can't reference `this' before the superclass constructor has been called");
9536       PATCH_METHOD_RETURN_ERROR ();
9537     }
9538   java_parser_context_restore_global ();
9539   if (is_static) 
9540     *is_static = is_static_flag;
9541   /* Sometimes, we want the decl of the selected method. Such as for
9542      EH checking */
9543   if (ret_decl)
9544     *ret_decl = list;
9545   patch = patch_invoke (patch, list, args);
9546   if (is_super_init && CLASS_HAS_FINIT_P (current_class))
9547     {
9548       tree finit_parms, finit_call;
9549       
9550       /* Prepare to pass hidden parameters to $finit$, if any. */
9551       finit_parms = build_alias_initializer_parameter_list 
9552         (AIPL_FUNCTION_FINIT_INVOCATION, current_class, NULL_TREE, NULL);
9553
9554       finit_call = 
9555         build_method_invocation (build_wfl_node (finit_identifier_node),
9556                                  finit_parms);
9557
9558       /* Generate the code used to initialize fields declared with an
9559          initialization statement and build a compound statement along
9560          with the super constructor invocation. */
9561       patch = build (COMPOUND_EXPR, void_type_node, patch,
9562                      java_complete_tree (finit_call));
9563       CAN_COMPLETE_NORMALLY (patch) = 1;
9564     }
9565   return patch;
9566 }
9567
9568 /* Check that we're not trying to do a static reference to a method in
9569    non static method. Return 1 if it's the case, 0 otherwise. */
9570
9571 static int
9572 check_for_static_method_reference (wfl, node, method, where, primary)
9573      tree wfl, node, method, where, primary;
9574 {
9575   if (METHOD_STATIC (current_function_decl) 
9576       && !METHOD_STATIC (method) && !primary && !CALL_CONSTRUCTOR_P (node))
9577     {
9578       char *fct_name = xstrdup (lang_printable_name (method, 0));
9579       parse_error_context 
9580         (wfl, "Can't make static reference to method `%s %s' in class `%s'", 
9581          lang_printable_name (TREE_TYPE (TREE_TYPE (method)), 0), fct_name,
9582          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (where))));
9583       free (fct_name);
9584       return 1;
9585     }
9586   return 0;
9587 }
9588
9589 /* Fix the invocation of *MDECL if necessary in the case of a
9590    invocation from an inner class. *THIS_ARG might be modified
9591    appropriately and an alternative access to *MDECL might be
9592    returned.  */
9593
9594 static int
9595 maybe_use_access_method (is_super_init, mdecl, this_arg)
9596      int is_super_init;
9597      tree *mdecl, *this_arg;
9598 {
9599   tree ctx;
9600   tree md = *mdecl, ta = *this_arg;
9601   int to_return = 0;
9602   int non_static_context = !METHOD_STATIC (md);
9603
9604   if (is_super_init 
9605       || DECL_CONTEXT (md) == current_class
9606       || !PURE_INNER_CLASS_TYPE_P (current_class) 
9607       || DECL_FINIT_P (md))
9608     return 0;
9609   
9610   /* If we're calling a method found in an enclosing class, generate
9611      what it takes to retrieve the right this. Don't do that if we're
9612      invoking a static method. */
9613
9614   if (non_static_context)
9615     {
9616       ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class)));
9617       if (ctx == DECL_CONTEXT (md))
9618         {
9619           ta = build_current_thisn (current_class);
9620           ta = build_wfl_node (ta);
9621         }
9622       else
9623         {
9624           tree type = ctx;
9625           while (type)
9626             {
9627               maybe_build_thisn_access_method (type);
9628               if (type == DECL_CONTEXT (md))
9629                 {
9630                   ta = build_access_to_thisn (ctx, type, 0);
9631                   break;
9632                 }
9633               type = (DECL_CONTEXT (TYPE_NAME (type)) ? 
9634                       TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))) : NULL_TREE);
9635             }
9636         }
9637       ta = java_complete_tree (ta);
9638     }
9639
9640   /* We might have to use an access method to get to MD. We can
9641      break the method access rule as far as we're not generating
9642      bytecode */
9643   if (METHOD_PRIVATE (md) && flag_emit_class_files)
9644     {
9645       md = build_outer_method_access_method (md);
9646       to_return = 1;
9647     }
9648
9649   *mdecl = md;
9650   *this_arg = ta;
9651
9652   /* Returnin a non zero value indicates we were doing a non static
9653      method invokation that is now a static invocation. It will have
9654      callee displace `this' to insert it in the regular argument
9655      list. */
9656   return (non_static_context && to_return);
9657 }
9658
9659 /* Patch an invoke expression METHOD and ARGS, based on its invocation
9660    mode.  */
9661
9662 static tree
9663 patch_invoke (patch, method, args)
9664      tree patch, method, args;
9665 {
9666   tree dtable, func;
9667   tree original_call, t, ta;
9668   tree cond = NULL_TREE;
9669
9670   /* Last step for args: convert build-in types. If we're dealing with
9671      a new TYPE() type call, the first argument to the constructor
9672      isn't found in the incoming argument list, but delivered by
9673      `new' */
9674   t = TYPE_ARG_TYPES (TREE_TYPE (method));
9675   if (TREE_CODE (patch) == NEW_CLASS_EXPR)
9676     t = TREE_CHAIN (t);
9677   for (ta = args; t != end_params_node && ta; 
9678        t = TREE_CHAIN (t), ta = TREE_CHAIN (ta))
9679     if (JPRIMITIVE_TYPE_P (TREE_TYPE (TREE_VALUE (ta))) &&
9680         TREE_TYPE (TREE_VALUE (ta)) != TREE_VALUE (t))
9681       TREE_VALUE (ta) = convert (TREE_VALUE (t), TREE_VALUE (ta));
9682
9683   /* Resolve unresolved returned type isses */
9684   t = TREE_TYPE (TREE_TYPE (method));
9685   if (TREE_CODE (t) == POINTER_TYPE && !CLASS_LOADED_P (TREE_TYPE (t)))
9686     resolve_and_layout (TREE_TYPE (t), NULL);
9687
9688   if (flag_emit_class_files || flag_emit_xref)
9689     func = method;
9690   else
9691     {
9692       tree signature = build_java_signature (TREE_TYPE (method));
9693       switch (invocation_mode (method, CALL_USING_SUPER (patch)))
9694         {
9695         case INVOKE_VIRTUAL:
9696           dtable = invoke_build_dtable (0, args);
9697           func = build_invokevirtual (dtable, method);
9698           break;
9699
9700         case INVOKE_NONVIRTUAL:
9701           /* If the object for the method call is null, we throw an
9702              exception.  We don't do this if the object is the current
9703              method's `this'.  In other cases we just rely on an
9704              optimization pass to eliminate redundant checks.  */
9705           if (TREE_VALUE (args) != current_this)
9706             {
9707               /* We use a SAVE_EXPR here to make sure we only evaluate
9708                  the new `self' expression once.  */
9709               tree save_arg = save_expr (TREE_VALUE (args));
9710               TREE_VALUE (args) = save_arg;
9711               cond = build (EQ_EXPR, boolean_type_node, save_arg,
9712                             null_pointer_node);
9713             }
9714           /* Fall through.  */
9715
9716         case INVOKE_SUPER:
9717         case INVOKE_STATIC:
9718           func = build_known_method_ref (method, TREE_TYPE (method),
9719                                          DECL_CONTEXT (method),
9720                                          signature, args);
9721           break;
9722
9723         case INVOKE_INTERFACE:
9724           dtable = invoke_build_dtable (1, args);
9725           func = build_invokeinterface (dtable, method);
9726           break;
9727
9728         default:
9729           fatal ("internal error - unknown invocation_mode result");
9730         }
9731
9732       /* Ensure self_type is initialized, (invokestatic). FIXME */
9733       func = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (method)), func);
9734     }
9735
9736   TREE_TYPE (patch) = TREE_TYPE (TREE_TYPE (method));
9737   TREE_OPERAND (patch, 0) = func;
9738   TREE_OPERAND (patch, 1) = args;
9739   original_call = patch;
9740
9741   /* We're processing a `new TYPE ()' form. New is called and its
9742      returned value is the first argument to the constructor. We build
9743      a COMPOUND_EXPR and use saved expression so that the overall NEW
9744      expression value is a pointer to a newly created and initialized
9745      class. */
9746   if (TREE_CODE (original_call) == NEW_CLASS_EXPR)
9747     {
9748       tree class = DECL_CONTEXT (method);
9749       tree c1, saved_new, size, new;
9750       if (flag_emit_class_files || flag_emit_xref)
9751         {
9752           TREE_TYPE (patch) = build_pointer_type (class);
9753           return patch;
9754         }
9755       if (!TYPE_SIZE (class))
9756         safe_layout_class (class);
9757       size = size_in_bytes (class);
9758       new = build (CALL_EXPR, promote_type (class),
9759                    build_address_of (alloc_object_node),
9760                    tree_cons (NULL_TREE, build_class_ref (class),
9761                               build_tree_list (NULL_TREE, 
9762                                                size_in_bytes (class))),
9763                    NULL_TREE);
9764       saved_new = save_expr (new);
9765       c1 = build_tree_list (NULL_TREE, saved_new);
9766       TREE_CHAIN (c1) = TREE_OPERAND (original_call, 1);
9767       TREE_OPERAND (original_call, 1) = c1;
9768       TREE_SET_CODE (original_call, CALL_EXPR);
9769       patch = build (COMPOUND_EXPR, TREE_TYPE (new), patch, saved_new);
9770     }
9771
9772   /* If COND is set, then we are building a check to see if the object
9773      is NULL.  */
9774   if (cond != NULL_TREE)
9775     {
9776       /* We have to make the `then' branch a compound expression to
9777          make the types turn out right.  This seems bizarre.  */
9778       patch = build (COND_EXPR, TREE_TYPE (patch), cond,
9779                      build (COMPOUND_EXPR, TREE_TYPE (patch),
9780                             build (CALL_EXPR, void_type_node,
9781                                    build_address_of (soft_nullpointer_node),
9782                                    NULL_TREE, NULL_TREE),
9783                             (FLOAT_TYPE_P (TREE_TYPE (patch))
9784                              ? build_real (TREE_TYPE (patch), dconst0)
9785                              : build1 (CONVERT_EXPR, TREE_TYPE (patch),
9786                                        integer_zero_node))),
9787                      patch);
9788       TREE_SIDE_EFFECTS (patch) = 1;
9789     }
9790
9791   return patch;
9792 }
9793
9794 static int
9795 invocation_mode (method, super)
9796      tree method;
9797      int super;
9798 {
9799   int access = get_access_flags_from_decl (method);
9800
9801   if (super)
9802     return INVOKE_SUPER;
9803
9804   if (access & ACC_STATIC)
9805     return INVOKE_STATIC;
9806
9807   /* We have to look for a constructor before we handle nonvirtual
9808      calls; otherwise the constructor will look nonvirtual.  */
9809   if (DECL_CONSTRUCTOR_P (method))
9810     return INVOKE_STATIC;
9811
9812   if (access & ACC_FINAL || access & ACC_PRIVATE)
9813     return INVOKE_NONVIRTUAL;
9814
9815   if (CLASS_FINAL (TYPE_NAME (DECL_CONTEXT (method))))
9816     return INVOKE_NONVIRTUAL;
9817
9818   if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))))
9819     return INVOKE_INTERFACE;
9820
9821   return INVOKE_VIRTUAL;
9822 }
9823
9824 /* Retrieve a refined list of matching methods. It covers the step
9825    15.11.2 (Compile-Time Step 2) */
9826
9827 static tree
9828 lookup_method_invoke (lc, cl, class, name, arg_list)
9829      int lc;
9830      tree cl;
9831      tree class, name, arg_list;
9832 {
9833   tree atl = end_params_node;           /* Arg Type List */
9834   tree method, signature, list, node;
9835   const char *candidates;               /* Used for error report */
9836   char *dup;
9837
9838   /* Fix the arguments */
9839   for (node = arg_list; node; node = TREE_CHAIN (node))
9840     {
9841       tree current_arg = TREE_TYPE (TREE_VALUE (node));
9842       /* Non primitive type may have to be resolved */
9843       if (!JPRIMITIVE_TYPE_P (current_arg))
9844         resolve_and_layout (current_arg, NULL_TREE);
9845       /* And promoted */
9846       if (TREE_CODE (current_arg) == RECORD_TYPE)
9847         current_arg = promote_type (current_arg);
9848       atl = tree_cons (NULL_TREE, current_arg, atl);
9849     }
9850
9851   /* Presto. If we're dealing with an anonymous class and a
9852      constructor call, generate the right constructor now, since we
9853      know the arguments' types. */
9854
9855   if (lc && ANONYMOUS_CLASS_P (class))
9856     craft_constructor (TYPE_NAME (class), atl);
9857
9858   /* Find all candidates and then refine the list, searching for the
9859      most specific method. */
9860   list = find_applicable_accessible_methods_list (lc, class, name, atl);
9861   list = find_most_specific_methods_list (list);
9862   if (list && !TREE_CHAIN (list))
9863     return TREE_VALUE (list);
9864
9865   /* Issue an error. List candidates if any. Candidates are listed
9866      only if accessible (non accessible methods may end-up here for
9867      the sake of a better error report). */
9868   candidates = NULL;
9869   if (list)
9870     {
9871       tree current;
9872       obstack_grow (&temporary_obstack, ". Candidates are:\n", 18);
9873       for (current = list; current; current = TREE_CHAIN (current))
9874         {
9875           tree cm = TREE_VALUE (current);
9876           char string [4096];
9877           if (!cm || not_accessible_p (class, cm, 0))
9878             continue;
9879           sprintf 
9880             (string, "  `%s' in `%s'%s",
9881              get_printable_method_name (cm),
9882              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (cm)))),
9883              (TREE_CHAIN (current) ? "\n" : ""));
9884           obstack_grow (&temporary_obstack, string, strlen (string));
9885         }
9886       obstack_1grow (&temporary_obstack, '\0');
9887       candidates = obstack_finish (&temporary_obstack);
9888     }
9889   /* Issue the error message */
9890   method = make_node (FUNCTION_TYPE);
9891   TYPE_ARG_TYPES (method) = atl;
9892   signature = build_java_argument_signature (method);
9893   dup = xstrdup (lang_printable_name (class, 0));
9894   parse_error_context (cl, "Can't find %s `%s(%s)' in type `%s'%s",
9895                        (lc ? "constructor" : "method"),
9896                        (lc ? dup : IDENTIFIER_POINTER (name)),
9897                        IDENTIFIER_POINTER (signature), dup,
9898                        (candidates ? candidates : ""));
9899   free (dup);
9900   return NULL_TREE;
9901 }
9902
9903 /* 15.11.2.1: Find Methods that are Applicable and Accessible. LC is 1
9904    when we're looking for a constructor. */
9905
9906 static tree
9907 find_applicable_accessible_methods_list (lc, class, name, arglist)
9908      int lc;
9909      tree class, name, arglist;
9910 {
9911   static int object_done = 0;
9912   tree list = NULL_TREE, all_list = NULL_TREE;
9913
9914   if (!CLASS_LOADED_P (class) && !CLASS_FROM_SOURCE_P (class))
9915     {
9916       load_class (class, 1);
9917       safe_layout_class (class);
9918     }
9919
9920   /* Search interfaces */
9921   if (CLASS_INTERFACE (TYPE_NAME (class)))
9922     {
9923       static struct hash_table t, *searched_interfaces = NULL;
9924       static int search_not_done = 0;
9925       int i, n;
9926       tree basetype_vec = TYPE_BINFO_BASETYPES (class);
9927
9928       /* Search in the hash table, otherwise create a new one if
9929          necessary and insert the new entry. */
9930
9931       if (searched_interfaces)
9932         {
9933           if (hash_lookup (searched_interfaces, 
9934                            (const hash_table_key) class, FALSE, NULL))
9935             return NULL;
9936         }
9937       else
9938         {
9939           hash_table_init (&t, hash_newfunc, java_hash_hash_tree_node,
9940                            java_hash_compare_tree_node);
9941           searched_interfaces = &t;
9942         }
9943
9944       hash_lookup (searched_interfaces, 
9945                    (const hash_table_key) class, TRUE, NULL);
9946
9947       search_applicable_methods_list (lc, TYPE_METHODS (class), 
9948                                       name, arglist, &list, &all_list);
9949       n = TREE_VEC_LENGTH (basetype_vec);
9950       for (i = 1; i < n; i++)
9951         {
9952           tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
9953           tree rlist;
9954
9955           search_not_done++;
9956           rlist = find_applicable_accessible_methods_list (lc,  t, name, 
9957                                                            arglist);
9958           list = chainon (rlist, list);
9959           search_not_done--;
9960         }
9961
9962       /* We're done. Reset the searched interfaces list and finally search
9963          java.lang.Object */
9964       if (!search_not_done)
9965         {  
9966           if (!object_done)
9967             search_applicable_methods_list (lc, 
9968                                             TYPE_METHODS (object_type_node),
9969                                             name, arglist, &list, &all_list);
9970           hash_table_free (searched_interfaces);
9971           searched_interfaces = NULL;  
9972         }
9973     }
9974   /* Search classes */
9975   else
9976     {
9977       tree sc = class;
9978       int seen_inner_class = 0;
9979       search_applicable_methods_list (lc, TYPE_METHODS (class), 
9980                                       name, arglist, &list, &all_list);
9981
9982       /* We must search all interfaces of this class */
9983       if (!lc)
9984       {
9985         tree basetype_vec = TYPE_BINFO_BASETYPES (sc);
9986         int n = TREE_VEC_LENGTH (basetype_vec), i;
9987         object_done = 1;
9988         for (i = 1; i < n; i++)
9989           {
9990             tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
9991             tree rlist;
9992             if (t != object_type_node)
9993               rlist = find_applicable_accessible_methods_list (lc, t,
9994                                                                name, arglist);
9995             list = chainon (rlist, list);
9996           }
9997         object_done = 0;
9998       }
9999
10000       /* Search enclosing context of inner classes before looking
10001          ancestors up. */
10002       while (!lc && INNER_CLASS_TYPE_P (class))
10003         {
10004           tree rlist;
10005           seen_inner_class = 1;
10006           class = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class)));
10007           rlist = find_applicable_accessible_methods_list (lc, class, 
10008                                                            name, arglist);
10009           list = chainon (rlist, list);
10010         }
10011
10012       if (!lc && seen_inner_class 
10013           && TREE_TYPE (DECL_CONTEXT (TYPE_NAME (sc))) == CLASSTYPE_SUPER (sc))
10014         class = CLASSTYPE_SUPER (sc);
10015       else
10016         class = sc;
10017
10018       for (class = (lc ? NULL_TREE : CLASSTYPE_SUPER (class)); 
10019         class; class = CLASSTYPE_SUPER (class))
10020        search_applicable_methods_list (lc, TYPE_METHODS (class), 
10021                                        name, arglist, &list, &all_list);
10022     }
10023
10024   /* Either return the list obtained or all selected (but
10025      inaccessible) methods for better error report. */
10026   return (!list ? all_list : list);
10027 }
10028
10029 /* Effectively search for the approriate method in method */
10030
10031 static void 
10032 search_applicable_methods_list (lc, method, name, arglist, list, all_list)
10033      int lc;
10034      tree method, name, arglist;
10035      tree *list, *all_list;
10036 {
10037   for (; method; method = TREE_CHAIN (method))
10038     {
10039       /* When dealing with constructor, stop here, otherwise search
10040          other classes */
10041       if (lc && !DECL_CONSTRUCTOR_P (method))
10042         continue;
10043       else if (!lc && (DECL_CONSTRUCTOR_P (method) 
10044                        || (GET_METHOD_NAME (method) != name)))
10045         continue;
10046           
10047       if (argument_types_convertible (method, arglist))
10048         {
10049           /* Retain accessible methods only */
10050           if (!not_accessible_p (DECL_CONTEXT (current_function_decl), 
10051                                  method, 0))
10052             *list = tree_cons (NULL_TREE, method, *list);
10053           else
10054             /* Also retain all selected method here */
10055             *all_list = tree_cons (NULL_TREE, method, *list);
10056         }
10057     }
10058 }    
10059
10060 /* 15.11.2.2 Choose the Most Specific Method */
10061
10062 static tree
10063 find_most_specific_methods_list (list)
10064      tree list;
10065 {
10066   int max = 0;
10067   tree current, new_list = NULL_TREE;
10068   for (current = list; current; current = TREE_CHAIN (current))
10069     {
10070       tree method;
10071       DECL_SPECIFIC_COUNT (TREE_VALUE (current)) = 0;
10072
10073       for (method = list; method; method = TREE_CHAIN (method))
10074         {
10075           /* Don't test a method against itself */
10076           if (method == current)
10077             continue;
10078
10079           /* Compare arguments and location where method where declared */
10080           if (argument_types_convertible (TREE_VALUE (method), 
10081                                           TREE_VALUE (current))
10082               && valid_method_invocation_conversion_p 
10083                    (DECL_CONTEXT (TREE_VALUE (method)), 
10084                     DECL_CONTEXT (TREE_VALUE (current))))
10085             {
10086               int v = ++DECL_SPECIFIC_COUNT (TREE_VALUE (current));
10087               max = (v > max ? v : max);
10088             }
10089         }
10090     }
10091
10092   /* Review the list and select the maximally specific methods */
10093   for (current = list; current; current = TREE_CHAIN (current))
10094     if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
10095       new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
10096
10097   /* If we have several and they're all abstract, just pick the
10098      closest one. */
10099
10100   if (new_list && TREE_CHAIN (new_list))
10101     {
10102       tree c;
10103       for (c = new_list; c && METHOD_ABSTRACT (TREE_VALUE (c)); 
10104            c = TREE_CHAIN (c))
10105         ;
10106       if (!c)
10107         {
10108           new_list = nreverse (new_list);
10109           TREE_CHAIN (new_list) = NULL_TREE;
10110         }
10111     }
10112
10113   /* If we can't find one, lower expectations and try to gather multiple
10114      maximally specific methods */
10115   while (!new_list && max)
10116     {
10117       while (--max > 0)
10118         {
10119           if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
10120             new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
10121         }
10122     }
10123
10124   return new_list;
10125 }
10126
10127 /* Make sure that the type of each M2_OR_ARGLIST arguments can be
10128    converted by method invocation conversion (5.3) to the type of the
10129    corresponding parameter of M1. Implementation expects M2_OR_ARGLIST
10130    to change less often than M1. */
10131
10132 static int
10133 argument_types_convertible (m1, m2_or_arglist)
10134     tree m1, m2_or_arglist;
10135 {
10136   static tree m2_arg_value = NULL_TREE;
10137   static tree m2_arg_cache = NULL_TREE;
10138
10139   register tree m1_arg, m2_arg;
10140
10141   SKIP_THIS_AND_ARTIFICIAL_PARMS (m1_arg, m1)
10142
10143   if (m2_arg_value == m2_or_arglist)
10144     m2_arg = m2_arg_cache;
10145   else
10146     {
10147       /* M2_OR_ARGLIST can be a function DECL or a raw list of
10148          argument types */
10149       if (m2_or_arglist && TREE_CODE (m2_or_arglist) == FUNCTION_DECL)
10150         {
10151           m2_arg = TYPE_ARG_TYPES (TREE_TYPE (m2_or_arglist));
10152           if (!METHOD_STATIC (m2_or_arglist))
10153             m2_arg = TREE_CHAIN (m2_arg);
10154         }
10155       else
10156         m2_arg = m2_or_arglist;
10157
10158       m2_arg_value = m2_or_arglist;
10159       m2_arg_cache = m2_arg;
10160     }
10161
10162   while (m1_arg != end_params_node && m2_arg != end_params_node)
10163     {
10164       resolve_and_layout (TREE_VALUE (m1_arg), NULL_TREE);
10165       if (!valid_method_invocation_conversion_p (TREE_VALUE (m1_arg),
10166                                                  TREE_VALUE (m2_arg)))
10167         break;
10168       m1_arg = TREE_CHAIN (m1_arg);
10169       m2_arg = TREE_CHAIN (m2_arg);
10170     }
10171   return m1_arg == end_params_node && m2_arg == end_params_node;
10172 }
10173
10174 /* Qualification routines */
10175
10176 static void
10177 qualify_ambiguous_name (id)
10178      tree id;
10179 {
10180   tree qual, qual_wfl, name = NULL_TREE, decl, ptr_type = NULL_TREE,
10181     saved_current_class;
10182   int again, super_found = 0, this_found = 0, new_array_found = 0;
10183   int code;
10184
10185   /* We first qualify the first element, then derive qualification of
10186      others based on the first one. If the first element is qualified
10187      by a resolution (field or type), this resolution is stored in the
10188      QUAL_RESOLUTION of the qual element being examined. We need to
10189      save the current_class since the use of SUPER might change the
10190      its value. */
10191   saved_current_class = current_class;
10192   qual = EXPR_WFL_QUALIFICATION (id);
10193   do {
10194
10195     /* Simple qualified expression feature a qual_wfl that is a
10196        WFL. Expression derived from a primary feature more complicated
10197        things like a CALL_EXPR. Expression from primary need to be
10198        worked out to extract the part on which the qualification will
10199        take place. */
10200     qual_wfl = QUAL_WFL (qual);
10201     switch (TREE_CODE (qual_wfl))
10202       {
10203       case CALL_EXPR:
10204         qual_wfl = TREE_OPERAND (qual_wfl, 0);
10205         if (TREE_CODE (qual_wfl) != EXPR_WITH_FILE_LOCATION)
10206           {
10207             qual = EXPR_WFL_QUALIFICATION (qual_wfl);
10208             qual_wfl = QUAL_WFL (qual);
10209           }
10210         break;
10211       case NEW_ARRAY_EXPR:
10212       case NEW_ANONYMOUS_ARRAY_EXPR:
10213         qual = TREE_CHAIN (qual);
10214         again = new_array_found = 1;
10215         continue;
10216       case CONVERT_EXPR:
10217         break;
10218       case NEW_CLASS_EXPR:
10219         qual_wfl = TREE_OPERAND (qual_wfl, 0);
10220         break;
10221       case ARRAY_REF:
10222         while (TREE_CODE (qual_wfl) == ARRAY_REF)
10223           qual_wfl = TREE_OPERAND (qual_wfl, 0);
10224         break;
10225       case STRING_CST:
10226         qual = TREE_CHAIN (qual);
10227         qual_wfl = QUAL_WFL (qual);
10228         break;
10229       case CLASS_LITERAL:
10230         qual = TREE_CHAIN (qual);
10231         qual_wfl = QUAL_WFL (qual);
10232       break;
10233       default:
10234         /* Fix for -Wall. Just break doing nothing */
10235         break;
10236       }
10237
10238     ptr_type = current_class;
10239     again = 0;
10240     code = TREE_CODE (qual_wfl);
10241
10242     /* Pos evaluation: non WFL leading expression nodes */
10243     if (code == CONVERT_EXPR
10244         && TREE_CODE (TREE_TYPE (qual_wfl)) == EXPR_WITH_FILE_LOCATION)
10245       name = EXPR_WFL_NODE (TREE_TYPE (qual_wfl));
10246
10247     else if (code == INTEGER_CST)
10248       name = qual_wfl;
10249     
10250     else if ((code == ARRAY_REF || code == CALL_EXPR || code == MODIFY_EXPR) &&
10251              TREE_CODE (TREE_OPERAND (qual_wfl, 0)) == EXPR_WITH_FILE_LOCATION)
10252       name = EXPR_WFL_NODE (TREE_OPERAND (qual_wfl, 0));
10253
10254     else if (code == TREE_LIST)
10255       name = EXPR_WFL_NODE (TREE_PURPOSE (qual_wfl));
10256
10257     else if (code == STRING_CST || code == CONDITIONAL_EXPR 
10258              || code == PLUS_EXPR)
10259       {
10260         qual = TREE_CHAIN (qual);
10261         qual_wfl = QUAL_WFL (qual);
10262         again = 1;
10263       }
10264     else 
10265       {
10266         name = EXPR_WFL_NODE (qual_wfl);
10267         if (!name)
10268           {
10269             qual = EXPR_WFL_QUALIFICATION (qual_wfl);
10270             again = 1;
10271           }
10272       }
10273
10274     /* If we have a THIS (from a primary), we set the context accordingly */
10275     if (name == this_identifier_node)
10276       {
10277         qual = TREE_CHAIN (qual);
10278         qual_wfl = QUAL_WFL (qual);
10279         if (TREE_CODE (qual_wfl) == CALL_EXPR)
10280           again = 1;
10281         else
10282           name = EXPR_WFL_NODE (qual_wfl);
10283         this_found = 1;
10284       }
10285     /* If we have a SUPER, we set the context accordingly */
10286     if (name == super_identifier_node)
10287       {
10288         current_class = CLASSTYPE_SUPER (ptr_type);
10289         /* Check that there is such a thing as a super class. If not,
10290            return.  The error will be caught later on, during the
10291            resolution */
10292         if (!current_class)
10293           {
10294             current_class = saved_current_class;
10295             return;
10296           }
10297         qual = TREE_CHAIN (qual);
10298         /* Do one more interation to set things up */
10299         super_found = again = 1;
10300       }
10301   } while (again);
10302   
10303   /* If name appears within the scope of a local variable declaration
10304      or parameter declaration, then it is an expression name. We don't
10305      carry this test out if we're in the context of the use of SUPER
10306      or THIS */
10307   if (!this_found && !super_found 
10308       && TREE_CODE (name) != STRING_CST && TREE_CODE (name) != INTEGER_CST
10309       && (decl = IDENTIFIER_LOCAL_VALUE (name)))
10310     {
10311       RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
10312       QUAL_RESOLUTION (qual) = decl;
10313     }
10314
10315   /* If within the class/interface NAME was found to be used there
10316      exists a (possibly inherited) field named NAME, then this is an
10317      expression name. If we saw a NEW_ARRAY_EXPR before and want to
10318      address length, it is OK. */
10319   else if ((decl = lookup_field_wrapper (ptr_type, name))
10320            || (new_array_found && name == length_identifier_node))
10321     {
10322       RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
10323       QUAL_RESOLUTION (qual) = (new_array_found ? NULL_TREE : decl);
10324     }
10325
10326   /* We reclassify NAME as yielding to a type name resolution if:
10327      - NAME is a class/interface declared within the compilation
10328        unit containing NAME,
10329      - NAME is imported via a single-type-import declaration,
10330      - NAME is declared in an another compilation unit of the package
10331        of the compilation unit containing NAME,
10332      - NAME is declared by exactly on type-import-on-demand declaration
10333      of the compilation unit containing NAME. 
10334      - NAME is actually a STRING_CST. */
10335   else if (TREE_CODE (name) == STRING_CST || TREE_CODE (name) == INTEGER_CST
10336            || (decl = resolve_and_layout (name, NULL_TREE)))
10337     {
10338       RESOLVE_TYPE_NAME_P (qual_wfl) = 1;
10339       QUAL_RESOLUTION (qual) = decl;
10340     }
10341
10342   /* Method call, array references and cast are expression name */
10343   else if (TREE_CODE (QUAL_WFL (qual)) == CALL_EXPR
10344            || TREE_CODE (QUAL_WFL (qual)) == ARRAY_REF
10345            || TREE_CODE (QUAL_WFL (qual)) == CONVERT_EXPR)
10346     RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
10347
10348   /* Check here that NAME isn't declared by more than one
10349      type-import-on-demand declaration of the compilation unit
10350      containing NAME. FIXME */
10351
10352   /* Otherwise, NAME is reclassified as a package name */
10353   else 
10354     RESOLVE_PACKAGE_NAME_P (qual_wfl) = 1;
10355
10356   /* Propagate the qualification accross other components of the
10357      qualified name */
10358   for (qual = TREE_CHAIN (qual); qual;
10359        qual_wfl = QUAL_WFL (qual), qual = TREE_CHAIN (qual))
10360     {
10361       if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
10362         RESOLVE_PACKAGE_NAME_P (QUAL_WFL (qual)) = 1;
10363       else 
10364         RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (qual)) = 1;
10365     }
10366
10367   /* Store the global qualification for the ambiguous part of ID back
10368      into ID fields */
10369   if (RESOLVE_EXPRESSION_NAME_P (qual_wfl))
10370     RESOLVE_EXPRESSION_NAME_P (id) = 1;
10371   else if (RESOLVE_TYPE_NAME_P (qual_wfl))
10372     RESOLVE_TYPE_NAME_P (id) = 1;
10373   else if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
10374     RESOLVE_PACKAGE_NAME_P (id) = 1;
10375
10376   /* Restore the current class */
10377   current_class = saved_current_class;
10378 }
10379
10380 static int
10381 breakdown_qualified (left, right, source)
10382     tree *left, *right, source;
10383 {
10384   char *p = IDENTIFIER_POINTER (source), *base;
10385   int   l = IDENTIFIER_LENGTH (source);
10386
10387   /* Breakdown NAME into REMAINDER . IDENTIFIER */
10388   base = p;
10389   p += (l-1);
10390   while (*p != '.' && p != base)
10391     p--;
10392
10393   /* We didn't find a '.'. Return an error */
10394   if (p == base)
10395     return 1;
10396
10397   *p = '\0';
10398   if (right)
10399     *right = get_identifier (p+1);
10400   *left = get_identifier (IDENTIFIER_POINTER (source));
10401   *p = '.';
10402   
10403   return 0;
10404 }
10405
10406 /* Patch tree nodes in a function body. When a BLOCK is found, push
10407    local variable decls if present.
10408    Same as java_complete_lhs, but does resolve static finals to values. */
10409
10410 static tree
10411 java_complete_tree (node)
10412      tree node;
10413 {
10414   node = java_complete_lhs (node);
10415   if (TREE_CODE (node) == VAR_DECL && FIELD_STATIC (node)
10416       && FIELD_FINAL (node) && DECL_INITIAL (node) != NULL_TREE
10417       && !flag_emit_xref)
10418     {
10419       tree value = DECL_INITIAL (node);
10420       DECL_INITIAL (node) = NULL_TREE;
10421       push_obstacks (&permanent_obstack, &permanent_obstack);
10422       value = fold_constant_for_init (value, node);
10423       pop_obstacks ();
10424       DECL_INITIAL (node) = value;
10425       if (value != NULL_TREE)
10426         {
10427           /* fold_constant_for_init sometimes widen the original type
10428              of the constant (i.e. byte to int.) It's not desirable,
10429              especially if NODE is a function argument. */
10430           if (TREE_CODE (value) == INTEGER_CST
10431               && TREE_TYPE (node) != TREE_TYPE (value))
10432             return convert (TREE_TYPE (node), value);
10433           else
10434             return value;
10435         }
10436     }
10437   return node;
10438 }
10439
10440 static tree
10441 java_stabilize_reference (node)
10442      tree node;
10443 {
10444   if (TREE_CODE (node) == COMPOUND_EXPR)
10445     {
10446       tree op0 = TREE_OPERAND (node, 0);
10447       tree op1 = TREE_OPERAND (node, 1);
10448       TREE_OPERAND (node, 0) = save_expr (op0);
10449       TREE_OPERAND (node, 1) = java_stabilize_reference (op1);
10450       return node;
10451     }
10452   return stabilize_reference (node);
10453 }
10454
10455 /* Patch tree nodes in a function body. When a BLOCK is found, push
10456    local variable decls if present.
10457    Same as java_complete_tree, but does not resolve static finals to values. */
10458
10459 static tree
10460 java_complete_lhs (node)
10461      tree node;
10462 {
10463   tree nn, cn, wfl_op1, wfl_op2, wfl_op3;
10464   int flag;
10465
10466   /* CONVERT_EXPR always has its type set, even though it needs to be
10467      worked out. */
10468   if (TREE_TYPE (node) && TREE_CODE (node) != CONVERT_EXPR)
10469     return node;
10470
10471   /* The switch block implements cases processing container nodes
10472      first.  Contained nodes are always written back. Leaves come
10473      next and return a value. */
10474   switch (TREE_CODE (node))
10475     {
10476     case BLOCK:
10477
10478       /* 1- Block section.
10479          Set the local values on decl names so we can identify them
10480          faster when they're referenced. At that stage, identifiers
10481          are legal so we don't check for declaration errors. */
10482       for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
10483         {
10484           DECL_CONTEXT (cn) = current_function_decl;
10485           IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = cn;
10486         }
10487       if (BLOCK_EXPR_BODY (node) == NULL_TREE)
10488           CAN_COMPLETE_NORMALLY (node) = 1;
10489       else
10490         {
10491           tree stmt = BLOCK_EXPR_BODY (node);
10492           tree *ptr;
10493           int error_seen = 0;
10494           if (TREE_CODE (stmt) == COMPOUND_EXPR)
10495             {
10496               /* Re-order from (((A; B); C); ...; Z) to 
10497                  (A; (B; (C ; (...; Z)))).
10498                  This makes it easier to scan the statements left-to-right
10499                  without using recursion (which might overflow the stack
10500                  if the block has many statements. */
10501               for (;;)
10502                 {
10503                   tree left = TREE_OPERAND (stmt, 0);
10504                   if (TREE_CODE (left) != COMPOUND_EXPR)
10505                     break;
10506                   TREE_OPERAND (stmt, 0) = TREE_OPERAND (left, 1);
10507                   TREE_OPERAND (left, 1) = stmt;
10508                   stmt = left;
10509                 }
10510               BLOCK_EXPR_BODY (node) = stmt;
10511             }
10512
10513           /* Now do the actual complete, without deep recursion for
10514              long blocks. */
10515           ptr = &BLOCK_EXPR_BODY (node);
10516           while (TREE_CODE (*ptr) == COMPOUND_EXPR
10517                  && TREE_OPERAND (*ptr, 1) != empty_stmt_node)
10518             {
10519               tree cur = java_complete_tree (TREE_OPERAND (*ptr, 0));
10520               tree *next = &TREE_OPERAND (*ptr, 1);
10521               TREE_OPERAND (*ptr, 0) = cur;
10522               if (cur == empty_stmt_node)
10523                 {
10524                   /* Optimization;  makes it easier to detect empty bodies.
10525                      Most useful for <clinit> with all-constant initializer. */
10526                   *ptr = *next;
10527                   continue;
10528                 }
10529               if (TREE_CODE (cur) == ERROR_MARK)
10530                 error_seen++;
10531               else if (! CAN_COMPLETE_NORMALLY (cur))
10532                 {
10533                   wfl_op2 = *next;
10534                   for (;;)
10535                     {
10536                       if (TREE_CODE (wfl_op2) == BLOCK)
10537                         wfl_op2 = BLOCK_EXPR_BODY (wfl_op2);
10538                       else if (TREE_CODE (wfl_op2) == COMPOUND_EXPR)
10539                         wfl_op2 = TREE_OPERAND (wfl_op2, 0);
10540                       else
10541                         break;
10542                     }
10543                   if (TREE_CODE (wfl_op2) != CASE_EXPR
10544                       && TREE_CODE (wfl_op2) != DEFAULT_EXPR)
10545                     unreachable_stmt_error (*ptr);
10546                 }
10547               ptr = next;
10548             }
10549           *ptr = java_complete_tree (*ptr);
10550
10551           if (TREE_CODE (*ptr) == ERROR_MARK || error_seen > 0)
10552             return error_mark_node;
10553           CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (*ptr);
10554         }
10555       /* Turn local bindings to null */
10556       for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
10557         IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = NULL_TREE;
10558
10559       TREE_TYPE (node) = void_type_node;
10560       break;
10561
10562       /* 2- They are expressions but ultimately deal with statements */
10563
10564     case THROW_EXPR:
10565       wfl_op1 = TREE_OPERAND (node, 0);
10566       COMPLETE_CHECK_OP_0 (node);
10567       /* 14.19 A throw statement cannot complete normally. */
10568       CAN_COMPLETE_NORMALLY (node) = 0;
10569       return patch_throw_statement (node, wfl_op1);
10570
10571     case SYNCHRONIZED_EXPR:
10572       wfl_op1 = TREE_OPERAND (node, 0);
10573       return patch_synchronized_statement (node, wfl_op1);
10574
10575     case TRY_EXPR:
10576       return patch_try_statement (node);
10577
10578     case TRY_FINALLY_EXPR:
10579       COMPLETE_CHECK_OP_0 (node);
10580       COMPLETE_CHECK_OP_1 (node);
10581       CAN_COMPLETE_NORMALLY (node)
10582         = (CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0))
10583            && CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)));
10584       TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 0));
10585       return node;
10586
10587     case CLEANUP_POINT_EXPR:
10588       COMPLETE_CHECK_OP_0 (node);
10589       TREE_TYPE (node) = void_type_node;
10590       CAN_COMPLETE_NORMALLY (node) = 
10591         CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
10592       return node;
10593
10594     case WITH_CLEANUP_EXPR:
10595       COMPLETE_CHECK_OP_0 (node);
10596       COMPLETE_CHECK_OP_2 (node);
10597       CAN_COMPLETE_NORMALLY (node) = 
10598         CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
10599       TREE_TYPE (node) = void_type_node;
10600       return node;
10601
10602     case LABELED_BLOCK_EXPR:
10603       PUSH_LABELED_BLOCK (node);
10604       if (LABELED_BLOCK_BODY (node))
10605         COMPLETE_CHECK_OP_1 (node);
10606       TREE_TYPE (node) = void_type_node;
10607       POP_LABELED_BLOCK ();
10608
10609       if (LABELED_BLOCK_BODY (node) == empty_stmt_node)
10610         {
10611           LABELED_BLOCK_BODY (node) = NULL_TREE;
10612           CAN_COMPLETE_NORMALLY (node) = 1;
10613         }
10614       else if (CAN_COMPLETE_NORMALLY (LABELED_BLOCK_BODY (node)))
10615         CAN_COMPLETE_NORMALLY (node) = 1;
10616       return node;
10617
10618     case EXIT_BLOCK_EXPR:
10619       /* We don't complete operand 1, because it's the return value of
10620          the EXIT_BLOCK_EXPR which doesn't exist it Java */
10621       return patch_bc_statement (node);
10622
10623     case CASE_EXPR:
10624       cn = java_complete_tree (TREE_OPERAND (node, 0));
10625       if (cn == error_mark_node)
10626         return cn;
10627
10628       /* First, the case expression must be constant. Values of final
10629          fields are accepted. */
10630       cn = fold (cn);
10631       if ((TREE_CODE (cn) == COMPOUND_EXPR || TREE_CODE (cn) == COMPONENT_REF)
10632           && JDECL_P (TREE_OPERAND (cn, 1))
10633           && FIELD_FINAL (TREE_OPERAND (cn, 1))
10634           && DECL_INITIAL (TREE_OPERAND (cn, 1)))
10635         {
10636           push_obstacks (&permanent_obstack, &permanent_obstack);
10637           cn = fold_constant_for_init (DECL_INITIAL (TREE_OPERAND (cn, 1)),
10638                                        TREE_OPERAND (cn, 1));
10639           pop_obstacks ();
10640         }
10641
10642       if (!TREE_CONSTANT (cn) && !flag_emit_xref)
10643         {
10644           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10645           parse_error_context (node, "Constant expression required");
10646           return error_mark_node;
10647         }
10648
10649       nn = ctxp->current_loop;
10650
10651       /* It must be assignable to the type of the switch expression. */
10652       if (!try_builtin_assignconv (NULL_TREE, 
10653                                    TREE_TYPE (TREE_OPERAND (nn, 0)), cn))
10654         {
10655           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10656           parse_error_context 
10657             (wfl_operator,
10658              "Incompatible type for case. Can't convert `%s' to `int'",
10659              lang_printable_name (TREE_TYPE (cn), 0));
10660           return error_mark_node;
10661         }
10662
10663       cn = fold (convert (int_type_node, cn));
10664
10665       /* Multiple instance of a case label bearing the same
10666          value is checked during code generation. The case
10667          expression is allright so far. */
10668       TREE_OPERAND (node, 0) = cn;
10669       TREE_TYPE (node) = void_type_node;
10670       CAN_COMPLETE_NORMALLY (node) = 1;
10671       TREE_SIDE_EFFECTS (node) = 1;
10672       break;
10673
10674     case DEFAULT_EXPR:
10675       nn = ctxp->current_loop;
10676       /* Only one default label is allowed per switch statement */
10677       if (SWITCH_HAS_DEFAULT (nn))
10678         {
10679           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10680           parse_error_context (wfl_operator, 
10681                                "Duplicate case label: `default'");
10682           return error_mark_node;
10683         }
10684       else
10685         SWITCH_HAS_DEFAULT (nn) = 1;
10686       TREE_TYPE (node) = void_type_node;
10687       TREE_SIDE_EFFECTS (node) = 1;
10688       CAN_COMPLETE_NORMALLY (node) = 1;
10689       break;
10690
10691     case SWITCH_EXPR:
10692     case LOOP_EXPR:
10693       PUSH_LOOP (node);
10694       /* Check whether the loop was enclosed in a labeled
10695          statement. If not, create one, insert the loop in it and
10696          return the node */
10697       nn = patch_loop_statement (node);
10698
10699       /* Anyways, walk the body of the loop */
10700       if (TREE_CODE (node) == LOOP_EXPR)
10701         TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
10702       /* Switch statement: walk the switch expression and the cases */
10703       else
10704         node = patch_switch_statement (node);
10705
10706       if (TREE_OPERAND (node, 0) == error_mark_node)
10707         nn = error_mark_node;
10708       else
10709         {
10710           TREE_TYPE (nn) = TREE_TYPE (node) = void_type_node;
10711           /* If we returned something different, that's because we
10712              inserted a label. Pop the label too. */
10713           if (nn != node)
10714             {
10715               if (CAN_COMPLETE_NORMALLY (node))
10716                 CAN_COMPLETE_NORMALLY (nn) = 1;
10717               POP_LABELED_BLOCK ();
10718             }
10719         }
10720       POP_LOOP ();
10721       return nn;
10722
10723     case EXIT_EXPR:
10724       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
10725       return patch_exit_expr (node);
10726
10727     case COND_EXPR:
10728       /* Condition */
10729       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
10730       if (TREE_OPERAND (node, 0) == error_mark_node)
10731         return error_mark_node;
10732       /* then-else branches */
10733       TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
10734       if (TREE_OPERAND (node, 1) == error_mark_node)
10735         return error_mark_node;
10736       TREE_OPERAND (node, 2) = java_complete_tree (TREE_OPERAND (node, 2));
10737       if (TREE_OPERAND (node, 2) == error_mark_node)
10738         return error_mark_node;
10739       return patch_if_else_statement (node);
10740       break;
10741
10742     case CONDITIONAL_EXPR:
10743       /* Condition */
10744       wfl_op1 = TREE_OPERAND (node, 0);
10745       COMPLETE_CHECK_OP_0 (node);
10746       wfl_op2 = TREE_OPERAND (node, 1);
10747       COMPLETE_CHECK_OP_1 (node);
10748       wfl_op3 = TREE_OPERAND (node, 2);
10749       COMPLETE_CHECK_OP_2 (node);
10750       return patch_conditional_expr (node, wfl_op1, wfl_op2);
10751
10752       /* 3- Expression section */
10753     case COMPOUND_EXPR:
10754       wfl_op2 = TREE_OPERAND (node, 1);
10755       TREE_OPERAND (node, 0) = nn = 
10756         java_complete_tree (TREE_OPERAND (node, 0));
10757       if (wfl_op2 == empty_stmt_node)
10758         CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (nn);
10759       else
10760         {
10761           if (! CAN_COMPLETE_NORMALLY (nn) && TREE_CODE (nn) != ERROR_MARK)
10762             {
10763               /* An unreachable condition in a do-while statement
10764                  is *not* (technically) an unreachable statement. */
10765               nn = wfl_op2;
10766               if (TREE_CODE (nn) == EXPR_WITH_FILE_LOCATION)
10767                 nn = EXPR_WFL_NODE (nn);
10768               if (TREE_CODE (nn) != EXIT_EXPR)
10769                 {
10770                   SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
10771                   parse_error_context (wfl_operator, "Unreachable statement");
10772                 }
10773             }
10774           TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
10775           if (TREE_OPERAND (node, 1) == error_mark_node)
10776             return error_mark_node;
10777           CAN_COMPLETE_NORMALLY (node)
10778             = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1));
10779         }
10780       TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 1));
10781       break;
10782
10783     case RETURN_EXPR:
10784       /* CAN_COMPLETE_NORMALLY (node) = 0; */
10785       return patch_return (node);
10786
10787     case EXPR_WITH_FILE_LOCATION:
10788       if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
10789           || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
10790         {
10791           tree wfl = node;
10792           node = resolve_expression_name (node, NULL);
10793           if (node == error_mark_node)
10794             return node;
10795           /* Keep line number information somewhere were it doesn't
10796              disrupt the completion process. */
10797           if (flag_emit_xref && TREE_CODE (node) != CALL_EXPR)
10798             {
10799               EXPR_WFL_NODE (wfl) = TREE_OPERAND (node, 1);
10800               TREE_OPERAND (node, 1) = wfl;
10801             }
10802           CAN_COMPLETE_NORMALLY (node) = 1;
10803         }
10804       else
10805         {
10806           tree body;
10807           int save_lineno = lineno;
10808           lineno = EXPR_WFL_LINENO (node);
10809           body = java_complete_tree (EXPR_WFL_NODE (node));
10810           lineno = save_lineno;
10811           EXPR_WFL_NODE (node) = body;
10812           TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (body);
10813           CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (body);
10814           if (body == empty_stmt_node)
10815             {
10816               /* Optimization;  makes it easier to detect empty bodies. */
10817               return body;
10818             }
10819           if (body == error_mark_node)
10820             {
10821               /* Its important for the evaluation of assignment that
10822                  this mark on the TREE_TYPE is propagated. */
10823               TREE_TYPE (node) = error_mark_node;
10824               return error_mark_node;
10825             }
10826           else
10827             TREE_TYPE (node) = TREE_TYPE (EXPR_WFL_NODE (node));
10828           
10829         }
10830       break;
10831
10832     case NEW_ARRAY_EXPR:
10833       /* Patch all the dimensions */
10834       flag = 0;
10835       for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
10836         {
10837           int location = EXPR_WFL_LINECOL (TREE_VALUE (cn));
10838           tree dim = convert (int_type_node, 
10839                               java_complete_tree (TREE_VALUE (cn)));
10840           if (dim == error_mark_node)
10841             {
10842               flag = 1;
10843               continue;
10844             }
10845           else
10846             {
10847               TREE_VALUE (cn) = dim;
10848               /* Setup the location of the current dimension, for
10849                  later error report. */
10850               TREE_PURPOSE (cn) = 
10851                 build_expr_wfl (NULL_TREE, input_filename, 0, 0);
10852               EXPR_WFL_LINECOL (TREE_PURPOSE (cn)) = location;
10853             }
10854         }
10855       /* They complete the array creation expression, if no errors
10856          were found. */
10857       CAN_COMPLETE_NORMALLY (node) = 1;
10858       return (flag ? error_mark_node
10859               : force_evaluation_order (patch_newarray (node)));
10860
10861     case NEW_ANONYMOUS_ARRAY_EXPR:
10862       /* Create the array type if necessary. */
10863       if (ANONYMOUS_ARRAY_DIMS_SIG (node))
10864         {
10865           tree type = ANONYMOUS_ARRAY_BASE_TYPE (node);
10866           if (!(type = resolve_type_during_patch (type)))
10867             return error_mark_node;
10868           type = build_array_from_name (type, NULL_TREE,
10869                                         ANONYMOUS_ARRAY_DIMS_SIG (node), NULL);
10870           ANONYMOUS_ARRAY_BASE_TYPE (node) = build_pointer_type (type);
10871         }
10872       node = patch_new_array_init (ANONYMOUS_ARRAY_BASE_TYPE (node),
10873                                    ANONYMOUS_ARRAY_INITIALIZER (node));
10874       if (node == error_mark_node)
10875         return error_mark_node;
10876       CAN_COMPLETE_NORMALLY (node) = 1;
10877       return node;
10878
10879     case NEW_CLASS_EXPR:
10880     case CALL_EXPR:
10881       /* Complete function's argument(s) first */
10882       if (complete_function_arguments (node))
10883         return error_mark_node;
10884       else
10885         {
10886           tree decl, wfl = TREE_OPERAND (node, 0);
10887           int in_this = CALL_THIS_CONSTRUCTOR_P (node);
10888
10889           node = patch_method_invocation (node, NULL_TREE, 
10890                                           NULL_TREE, 0, &decl);
10891           if (node == error_mark_node)
10892             return error_mark_node;
10893
10894           check_thrown_exceptions (EXPR_WFL_LINECOL (node), decl);
10895           /* If we call this(...), register signature and positions */
10896           if (in_this)
10897             DECL_CONSTRUCTOR_CALLS (current_function_decl) = 
10898               tree_cons (wfl, decl, 
10899                          DECL_CONSTRUCTOR_CALLS (current_function_decl));
10900           CAN_COMPLETE_NORMALLY (node) = 1;
10901           return force_evaluation_order (node);
10902         }
10903
10904     case MODIFY_EXPR:
10905       /* Save potential wfls */
10906       wfl_op1 = TREE_OPERAND (node, 0);
10907       TREE_OPERAND (node, 0) = nn = java_complete_lhs (wfl_op1);
10908       
10909       if (MODIFY_EXPR_FROM_INITIALIZATION_P (node)
10910           && TREE_CODE (nn) == VAR_DECL && TREE_STATIC (nn)
10911           && DECL_INITIAL (nn) != NULL_TREE)
10912         {
10913           tree value;
10914           
10915           push_obstacks (&permanent_obstack, &permanent_obstack);
10916           value = fold_constant_for_init (nn, nn);
10917           pop_obstacks ();
10918
10919           if (value != NULL_TREE)
10920             {
10921               tree type = TREE_TYPE (value);
10922               if (JPRIMITIVE_TYPE_P (type) || 
10923                   (type == string_ptr_type_node && ! flag_emit_class_files))
10924                 return empty_stmt_node;
10925             }
10926           DECL_INITIAL (nn) = NULL_TREE;
10927         }
10928       wfl_op2 = TREE_OPERAND (node, 1);
10929
10930       if (TREE_OPERAND (node, 0) == error_mark_node)
10931         return error_mark_node;
10932
10933       flag = COMPOUND_ASSIGN_P (wfl_op2);
10934       if (flag)
10935         {
10936           /* This might break when accessing outer field from inner
10937              class. TESTME, FIXME */
10938           tree lvalue = java_stabilize_reference (TREE_OPERAND (node, 0)); 
10939
10940           /* Hand stablize the lhs on both places */
10941           TREE_OPERAND (node, 0) = lvalue;
10942           TREE_OPERAND (TREE_OPERAND (node, 1), 0) = 
10943             (flag_emit_class_files ? lvalue : save_expr (lvalue));
10944
10945           /* 15.25.2.a: Left hand is not an array access. FIXME */
10946           /* Now complete the RHS. We write it back later on. */
10947           nn = java_complete_tree (TREE_OPERAND (node, 1));
10948
10949           if ((cn = patch_string (nn)))
10950             nn = cn;
10951
10952           /* The last part of the rewrite for E1 op= E2 is to have 
10953              E1 = (T)(E1 op E2), with T being the type of E1. */
10954           nn = java_complete_tree (build_cast (EXPR_WFL_LINECOL (wfl_op2), 
10955                                                TREE_TYPE (lvalue), nn));
10956
10957           /* 15.25.2.b: Left hand is an array access. FIXME */
10958         }
10959
10960       /* If we're about to patch a NEW_ARRAY_INIT, we call a special
10961          function to complete this RHS. Note that a NEW_ARRAY_INIT
10962          might have been already fully expanded if created as a result
10963          of processing an anonymous array initializer. We avoid doing
10964          the operation twice by testing whether the node already bears
10965          a type. */
10966       else if (TREE_CODE (wfl_op2) == NEW_ARRAY_INIT && !TREE_TYPE (wfl_op2))
10967         nn = patch_new_array_init (TREE_TYPE (TREE_OPERAND (node, 0)),
10968                                    TREE_OPERAND (node, 1));
10969       /* Otherwise we simply complete the RHS */
10970       else
10971         nn = java_complete_tree (TREE_OPERAND (node, 1));
10972
10973       if (nn == error_mark_node)
10974         return error_mark_node;
10975
10976       /* Write back the RHS as we evaluated it. */
10977       TREE_OPERAND (node, 1) = nn;
10978
10979       /* In case we're handling = with a String as a RHS, we need to
10980          produce a String out of the RHS (it might still be a
10981          STRING_CST or a StringBuffer at this stage */
10982       if ((nn = patch_string (TREE_OPERAND (node, 1))))
10983         TREE_OPERAND (node, 1) = nn;
10984
10985       if ((nn = outer_field_access_fix (wfl_op1, TREE_OPERAND (node, 0),
10986                                         TREE_OPERAND (node, 1))))
10987         {
10988           /* We return error_mark_node if outer_field_access_fix
10989              detects we write into a final. */
10990           if (nn == error_mark_node)
10991             return error_mark_node;
10992           node = nn;
10993         }
10994       else
10995         {
10996           node = patch_assignment (node, wfl_op1, wfl_op2);
10997           /* Reorganize the tree if necessary. */
10998           if (flag && (!JREFERENCE_TYPE_P (TREE_TYPE (node)) 
10999                        || JSTRING_P (TREE_TYPE (node))))
11000             node = java_refold (node);
11001         }
11002       
11003       CAN_COMPLETE_NORMALLY (node) = 1;
11004       return node;
11005
11006     case MULT_EXPR:
11007     case PLUS_EXPR:
11008     case MINUS_EXPR:
11009     case LSHIFT_EXPR:
11010     case RSHIFT_EXPR:
11011     case URSHIFT_EXPR:
11012     case BIT_AND_EXPR:
11013     case BIT_XOR_EXPR:
11014     case BIT_IOR_EXPR:
11015     case TRUNC_MOD_EXPR:
11016     case TRUNC_DIV_EXPR:
11017     case RDIV_EXPR:
11018     case TRUTH_ANDIF_EXPR:
11019     case TRUTH_ORIF_EXPR:
11020     case EQ_EXPR: 
11021     case NE_EXPR:
11022     case GT_EXPR:
11023     case GE_EXPR:
11024     case LT_EXPR:
11025     case LE_EXPR:
11026       /* Operands 0 and 1 are WFL in certain cases only. patch_binop
11027          knows how to handle those cases. */
11028       wfl_op1 = TREE_OPERAND (node, 0);
11029       wfl_op2 = TREE_OPERAND (node, 1);
11030
11031       CAN_COMPLETE_NORMALLY (node) = 1;
11032       /* Don't complete string nodes if dealing with the PLUS operand. */
11033       if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op1))
11034         {
11035           nn = java_complete_tree (wfl_op1);
11036           if (nn == error_mark_node)
11037             return error_mark_node;
11038
11039           TREE_OPERAND (node, 0) = nn;
11040         }
11041       if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op2))
11042         {
11043           nn = java_complete_tree (wfl_op2);
11044           if (nn == error_mark_node)
11045             return error_mark_node;
11046
11047           TREE_OPERAND (node, 1) = nn;
11048         }
11049       return force_evaluation_order (patch_binop (node, wfl_op1, wfl_op2));
11050
11051     case INSTANCEOF_EXPR:
11052       wfl_op1 = TREE_OPERAND (node, 0);
11053       COMPLETE_CHECK_OP_0 (node);
11054       if (flag_emit_xref)
11055         {
11056           TREE_TYPE (node) = boolean_type_node;
11057           return node;
11058         }
11059       return patch_binop (node, wfl_op1, TREE_OPERAND (node, 1));
11060
11061     case UNARY_PLUS_EXPR:
11062     case NEGATE_EXPR:
11063     case TRUTH_NOT_EXPR:
11064     case BIT_NOT_EXPR:
11065     case PREDECREMENT_EXPR:
11066     case PREINCREMENT_EXPR:
11067     case POSTDECREMENT_EXPR:
11068     case POSTINCREMENT_EXPR:
11069     case CONVERT_EXPR:
11070       /* There are cases were wfl_op1 is a WFL. patch_unaryop knows
11071          how to handle those cases. */
11072       wfl_op1 = TREE_OPERAND (node, 0);
11073       CAN_COMPLETE_NORMALLY (node) = 1;
11074       TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
11075       if (TREE_OPERAND (node, 0) == error_mark_node)
11076         return error_mark_node;
11077       node = patch_unaryop (node, wfl_op1);
11078       CAN_COMPLETE_NORMALLY (node) = 1;
11079       break;
11080
11081     case ARRAY_REF:
11082       /* There are cases were wfl_op1 is a WFL. patch_array_ref knows
11083          how to handle those cases. */
11084       wfl_op1 = TREE_OPERAND (node, 0);
11085       TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
11086       if (TREE_OPERAND (node, 0) == error_mark_node)
11087         return error_mark_node;
11088       if (!flag_emit_class_files && !flag_emit_xref)
11089         TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
11090       /* The same applies to wfl_op2 */
11091       wfl_op2 = TREE_OPERAND (node, 1);
11092       TREE_OPERAND (node, 1) = java_complete_tree (wfl_op2);
11093       if (TREE_OPERAND (node, 1) == error_mark_node)
11094         return error_mark_node;
11095       if (!flag_emit_class_files && !flag_emit_xref)
11096         TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1));
11097       return patch_array_ref (node);
11098
11099     case RECORD_TYPE:
11100       return node;;
11101
11102     case COMPONENT_REF:
11103       /* The first step in the re-write of qualified name handling.  FIXME.
11104          So far, this is only to support PRIMTYPE.class -> PRIMCLASS.TYPE. */
11105       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
11106       if (TREE_CODE (TREE_OPERAND (node, 0)) == RECORD_TYPE)
11107         {
11108           tree name = TREE_OPERAND (node, 1);
11109           tree field = lookup_field_wrapper (TREE_OPERAND (node, 0), name);
11110           if (field == NULL_TREE)
11111             {
11112               error ("missing static field `%s'", IDENTIFIER_POINTER (name));
11113               return error_mark_node;
11114             }
11115           if (! FIELD_STATIC (field))
11116             {
11117               error ("not a static field `%s'", IDENTIFIER_POINTER (name));
11118               return error_mark_node;
11119             }
11120           return field;
11121         }
11122       else
11123         fatal ("unimplemented java_complete_tree for COMPONENT_REF");
11124       break;
11125
11126     case THIS_EXPR:
11127       /* Can't use THIS in a static environment */
11128       if (!current_this)
11129         {
11130           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11131           parse_error_context (wfl_operator,
11132                                "Keyword `this' used outside allowed context");
11133           TREE_TYPE (node) = error_mark_node;
11134           return error_mark_node;
11135         }
11136       if (ctxp->explicit_constructor_p)
11137         {
11138           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11139           parse_error_context 
11140             (wfl_operator, "Can't reference `this' or `super' before the superclass constructor has been called");
11141           TREE_TYPE (node) = error_mark_node;
11142           return error_mark_node;
11143         }
11144       return current_this;
11145       
11146     case CLASS_LITERAL:
11147       CAN_COMPLETE_NORMALLY (node) = 1;
11148       node = patch_incomplete_class_ref (node);
11149       if (node == error_mark_node)
11150         return error_mark_node;
11151       break;
11152
11153     case INSTANCE_INITIALIZERS_EXPR:
11154       in_instance_initializer++;
11155       node = java_complete_tree (TREE_OPERAND (node, 0));
11156       in_instance_initializer--;
11157       if (node != error_mark_node)
11158         TREE_TYPE (node) = void_type_node;
11159       else
11160         return error_mark_node;
11161       break;
11162
11163     default:
11164       CAN_COMPLETE_NORMALLY (node) = 1;
11165       /* Ok: may be we have a STRING_CST or a crafted `StringBuffer'
11166          and it's time to turn it into the appropriate String object */
11167       if ((nn = patch_string (node)))
11168         node = nn;
11169       else
11170         fatal ("No case for tree code `%s' - java_complete_tree\n",
11171                tree_code_name [TREE_CODE (node)]);
11172     }
11173   return node;
11174 }
11175
11176 /* Complete function call's argument. Return a non zero value is an
11177    error was found.  */
11178
11179 static int
11180 complete_function_arguments (node)
11181      tree node;
11182 {
11183   int flag = 0;
11184   tree cn;
11185
11186   ctxp->explicit_constructor_p += (CALL_EXPLICIT_CONSTRUCTOR_P (node) ? 1 : 0);
11187   for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
11188     {
11189       tree wfl = TREE_VALUE (cn), parm, temp;
11190       parm = java_complete_tree (wfl);
11191
11192       if (parm == error_mark_node)
11193         {
11194           flag = 1;
11195           continue;
11196         }
11197       /* If have a string literal that we haven't transformed yet or a
11198          crafted string buffer, as a result of use of the the String
11199          `+' operator. Build `parm.toString()' and expand it. */
11200       if ((temp = patch_string (parm)))
11201         parm = temp;
11202       /* Inline PRIMTYPE.TYPE read access */
11203       parm = maybe_build_primttype_type_ref (parm, wfl);
11204
11205       TREE_VALUE (cn) = parm;
11206     }
11207   ctxp->explicit_constructor_p -= (CALL_EXPLICIT_CONSTRUCTOR_P (node) ? 1 : 0);
11208   return flag;
11209 }
11210
11211 /* Sometimes (for loops and variable initialized during their
11212    declaration), we want to wrap a statement around a WFL and turn it
11213    debugable.  */
11214
11215 static tree
11216 build_debugable_stmt (location, stmt)
11217     int location;
11218     tree stmt;
11219 {
11220   if (TREE_CODE (stmt) != EXPR_WITH_FILE_LOCATION)
11221     {
11222       stmt = build_expr_wfl (stmt, input_filename, 0, 0);
11223       EXPR_WFL_LINECOL (stmt) = location;
11224     }
11225   JAVA_MAYBE_GENERATE_DEBUG_INFO (stmt);
11226   return stmt;
11227 }
11228
11229 static tree
11230 build_expr_block (body, decls)
11231      tree body, decls;
11232 {
11233   tree node = make_node (BLOCK);
11234   BLOCK_EXPR_DECLS (node) = decls;
11235   BLOCK_EXPR_BODY (node) = body;
11236   if (body)
11237     TREE_TYPE (node) = TREE_TYPE (body);
11238   TREE_SIDE_EFFECTS (node) = 1;
11239   return node;
11240 }
11241
11242 /* Create a new function block and link it approriately to current
11243    function block chain */
11244
11245 static tree
11246 enter_block ()
11247 {
11248   return (enter_a_block (build_expr_block (NULL_TREE, NULL_TREE)));
11249 }
11250
11251 /* Link block B supercontext to the previous block. The current
11252    function DECL is used as supercontext when enter_a_block is called
11253    for the first time for a given function. The current function body
11254    (DECL_FUNCTION_BODY) is set to be block B.  */
11255
11256 static tree
11257 enter_a_block (b)
11258      tree b;
11259 {
11260   tree fndecl = current_function_decl; 
11261
11262   if (!fndecl) {
11263     BLOCK_SUPERCONTEXT (b) = current_static_block;
11264     current_static_block = b;
11265   }
11266
11267   else if (!DECL_FUNCTION_BODY (fndecl))
11268     {
11269       BLOCK_SUPERCONTEXT (b) = fndecl;
11270       DECL_FUNCTION_BODY (fndecl) = b;
11271     }
11272   else
11273     {
11274       BLOCK_SUPERCONTEXT (b) = DECL_FUNCTION_BODY (fndecl);
11275       DECL_FUNCTION_BODY (fndecl) = b;
11276     }
11277   return b;
11278 }
11279
11280 /* Exit a block by changing the current function body
11281    (DECL_FUNCTION_BODY) to the current block super context, only if
11282    the block being exited isn't the method's top level one.  */
11283
11284 static tree
11285 exit_block ()
11286 {
11287   tree b;
11288   if (current_function_decl)
11289     {
11290       b = DECL_FUNCTION_BODY (current_function_decl);
11291       if (BLOCK_SUPERCONTEXT (b) != current_function_decl)
11292         DECL_FUNCTION_BODY (current_function_decl) = BLOCK_SUPERCONTEXT (b);
11293     }
11294   else
11295     {
11296       b = current_static_block;
11297
11298       if (BLOCK_SUPERCONTEXT (b))
11299         current_static_block = BLOCK_SUPERCONTEXT (b);
11300     }
11301   return b;
11302 }
11303
11304 /* Lookup for NAME in the nested function's blocks, all the way up to
11305    the current toplevel one. It complies with Java's local variable
11306    scoping rules.  */
11307
11308 static tree
11309 lookup_name_in_blocks (name)
11310      tree name;
11311 {
11312   tree b = GET_CURRENT_BLOCK (current_function_decl);
11313
11314   while (b != current_function_decl)
11315     {
11316       tree current;
11317
11318       /* Paranoid sanity check. To be removed */
11319       if (TREE_CODE (b) != BLOCK)
11320         fatal ("non block expr function body - lookup_name_in_blocks");
11321
11322       for (current = BLOCK_EXPR_DECLS (b); current; 
11323            current = TREE_CHAIN (current))
11324         if (DECL_NAME (current) == name)
11325           return current;
11326       b = BLOCK_SUPERCONTEXT (b);
11327     }
11328   return NULL_TREE;
11329 }
11330
11331 static void
11332 maybe_absorb_scoping_blocks ()
11333 {
11334   while (BLOCK_EXPR_ORIGIN (GET_CURRENT_BLOCK (current_function_decl)))
11335     {
11336       tree b = exit_block ();
11337       java_method_add_stmt (current_function_decl, b);
11338       SOURCE_FRONTEND_DEBUG (("Absorbing scoping block at line %d", lineno));
11339     }
11340 }
11341
11342 \f
11343 /* This section of the source is reserved to build_* functions that
11344    are building incomplete tree nodes and the patch_* functions that
11345    are completing them.  */
11346
11347 /* Wrap a non WFL node around a WFL.  */
11348 static tree
11349 build_wfl_wrap (node)
11350     tree node;
11351 {
11352   tree wfl, node_to_insert = node;
11353   
11354   /* We want to process THIS . xxx symbolicaly, to keep it consistent
11355      with the way we're processing SUPER. A THIS from a primary as a
11356      different form than a SUPER. Turn THIS into something symbolic */
11357   if (TREE_CODE (node) == THIS_EXPR)
11358     node_to_insert = wfl = build_wfl_node (this_identifier_node);
11359   else
11360     wfl = build_expr_wfl (NULL_TREE, ctxp->filename, 0, 0);
11361
11362   EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (node);
11363   EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (node_to_insert, NULL_TREE);
11364   return wfl;
11365 }
11366
11367
11368 /* Build a super() constructor invocation. Returns empty_stmt_node if
11369    we're currently dealing with the class java.lang.Object. */
11370
11371 static tree
11372 build_super_invocation (mdecl)
11373      tree mdecl;
11374 {
11375   if (DECL_CONTEXT (mdecl) == object_type_node)
11376     return empty_stmt_node;
11377   else
11378     {
11379       tree super_wfl = build_wfl_node (super_identifier_node);
11380       tree a = NULL_TREE, t;
11381       /* If we're dealing with an anonymous class, pass the arguments
11382          of the crafted constructor along. */
11383       if (ANONYMOUS_CLASS_P (DECL_CONTEXT (mdecl)))
11384         {
11385           SKIP_THIS_AND_ARTIFICIAL_PARMS (t, mdecl);
11386           for (; t != end_params_node; t = TREE_CHAIN (t))
11387             a = tree_cons (NULL_TREE, build_wfl_node (TREE_PURPOSE (t)), a);
11388         }
11389       return build_method_invocation (super_wfl, a);
11390     }
11391 }
11392
11393 /* Build a SUPER/THIS qualified method invocation.  */
11394
11395 static tree
11396 build_this_super_qualified_invocation (use_this, name, args, lloc, rloc)
11397      int use_this;
11398      tree name, args;
11399      int lloc, rloc;
11400 {
11401   tree invok;
11402   tree wfl = 
11403     build_wfl_node (use_this ? this_identifier_node : super_identifier_node);
11404   EXPR_WFL_LINECOL (wfl) = lloc;
11405   invok = build_method_invocation (name, args);
11406   return make_qualified_primary (wfl, invok, rloc);
11407 }
11408
11409 /* Build an incomplete CALL_EXPR node. */
11410
11411 static tree
11412 build_method_invocation (name, args)
11413     tree name;
11414     tree args;
11415 {
11416   tree call = build (CALL_EXPR, NULL_TREE, name, args, NULL_TREE);
11417   TREE_SIDE_EFFECTS (call) = 1;
11418   EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
11419   return call;
11420 }
11421
11422 /* Build an incomplete new xxx(...) node. */
11423
11424 static tree
11425 build_new_invocation (name, args)
11426     tree name, args;
11427 {
11428   tree call = build (NEW_CLASS_EXPR, NULL_TREE, name, args, NULL_TREE);
11429   TREE_SIDE_EFFECTS (call) = 1;
11430   EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
11431   return call;
11432 }
11433
11434 /* Build an incomplete assignment expression. */
11435
11436 static tree
11437 build_assignment (op, op_location, lhs, rhs)
11438      int op, op_location;
11439      tree lhs, rhs;
11440 {
11441   tree assignment;
11442   /* Build the corresponding binop if we deal with a Compound
11443      Assignment operator. Mark the binop sub-tree as part of a
11444      Compound Assignment expression */
11445   if (op != ASSIGN_TK)
11446     {
11447       rhs = build_binop (BINOP_LOOKUP (op), op_location, lhs, rhs);
11448       COMPOUND_ASSIGN_P (rhs) = 1;
11449     }
11450   assignment = build (MODIFY_EXPR, NULL_TREE, lhs, rhs);
11451   TREE_SIDE_EFFECTS (assignment) = 1;
11452   EXPR_WFL_LINECOL (assignment) = op_location;
11453   return assignment;
11454 }
11455
11456 /* Print an INTEGER_CST node in a static buffer, and return the buffer. */
11457
11458 char *
11459 print_int_node (node)
11460     tree node;
11461 {
11462   static char buffer [80];
11463   if (TREE_CONSTANT_OVERFLOW (node))
11464     sprintf (buffer, "<overflow>");
11465     
11466   if (TREE_INT_CST_HIGH (node) == 0)
11467     sprintf (buffer, HOST_WIDE_INT_PRINT_UNSIGNED,
11468              TREE_INT_CST_LOW (node));
11469   else if (TREE_INT_CST_HIGH (node) == -1
11470            && TREE_INT_CST_LOW (node) != 0)
11471     {
11472       buffer [0] = '-';
11473       sprintf (&buffer [1], HOST_WIDE_INT_PRINT_UNSIGNED,
11474                -TREE_INT_CST_LOW (node));
11475     }
11476   else
11477     sprintf (buffer, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
11478              TREE_INT_CST_HIGH (node), TREE_INT_CST_LOW (node));
11479
11480   return buffer;
11481 }
11482
11483 /* Return 1 if an assignment to a FINAL is attempted in a non suitable
11484    context.  */
11485
11486 static int
11487 check_final_assignment (lvalue, wfl)
11488      tree lvalue, wfl;
11489 {
11490   if (TREE_CODE (lvalue) == COMPOUND_EXPR 
11491       && JDECL_P (TREE_OPERAND (lvalue, 1)))
11492     lvalue = TREE_OPERAND (lvalue, 1);
11493
11494   /* When generating class files, references to the `length' field
11495      look a bit different.  */
11496   if ((flag_emit_class_files
11497        && TREE_CODE (lvalue) == COMPONENT_REF
11498        && TYPE_ARRAY_P (TREE_TYPE (TREE_OPERAND (lvalue, 0)))
11499        && FIELD_FINAL (TREE_OPERAND (lvalue, 1)))
11500       || (TREE_CODE (lvalue) == FIELD_DECL
11501           && FIELD_FINAL (lvalue)
11502           && !DECL_CLINIT_P (current_function_decl)
11503           && !DECL_FINIT_P (current_function_decl)))
11504     {
11505       parse_error_context 
11506         (wfl, "Can't assign a value to the final variable `%s'",
11507          IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
11508       return 1;
11509     }
11510   return 0;
11511 }
11512
11513 /* Inline references to java.lang.PRIMTYPE.TYPE when accessed in
11514    read. This is needed to avoid circularities in the implementation
11515    of these fields in libjava. */
11516
11517 static tree
11518 maybe_build_primttype_type_ref (rhs, wfl)
11519     tree rhs, wfl;
11520 {
11521   tree to_return = NULL_TREE;
11522   tree rhs_type = TREE_TYPE (rhs);
11523   if (TREE_CODE (rhs) == COMPOUND_EXPR)
11524     {
11525       tree n = TREE_OPERAND (rhs, 1);
11526       if (TREE_CODE (n) == VAR_DECL 
11527           && DECL_NAME (n) == TYPE_identifier_node
11528           && rhs_type == class_ptr_type)
11529         {
11530           const char *self_name = IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl));
11531           if (!strncmp (self_name, "java.lang.", 10))
11532             to_return = build_primtype_type_ref (self_name);
11533         }
11534     }
11535   return (to_return ? to_return : rhs );
11536 }
11537
11538 /* 15.25 Assignment operators. */
11539
11540 static tree
11541 patch_assignment (node, wfl_op1, wfl_op2)
11542      tree node;
11543      tree wfl_op1;
11544      tree wfl_op2;
11545 {
11546   tree rhs = TREE_OPERAND (node, 1);
11547   tree lvalue = TREE_OPERAND (node, 0), llvalue;
11548   tree lhs_type = NULL_TREE, rhs_type, new_rhs = NULL_TREE;
11549   int error_found = 0;
11550   int lvalue_from_array = 0;
11551
11552   /* Can't assign to a (blank) final. */
11553   if (check_final_assignment (lvalue, wfl_op1))
11554     error_found = 1;
11555
11556   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11557
11558   /* Lhs can be a named variable */
11559   if (JDECL_P (lvalue))
11560     {
11561       lhs_type = TREE_TYPE (lvalue);
11562     }
11563   /* Or Lhs can be a array acccess. Should that be lvalue ? FIXME +
11564      comment on reason why */
11565   else if (TREE_CODE (wfl_op1) == ARRAY_REF)
11566     {
11567       lhs_type = TREE_TYPE (lvalue);
11568       lvalue_from_array = 1;
11569     }
11570   /* Or a field access */
11571   else if (TREE_CODE (lvalue) == COMPONENT_REF)
11572     lhs_type = TREE_TYPE (lvalue);
11573   /* Or a function return slot */
11574   else if (TREE_CODE (lvalue) == RESULT_DECL)
11575     lhs_type = TREE_TYPE (lvalue);
11576   /* Otherwise, we might want to try to write into an optimized static
11577      final, this is an of a different nature, reported further on. */
11578   else if (TREE_CODE (wfl_op1) == EXPR_WITH_FILE_LOCATION
11579            && resolve_expression_name (wfl_op1, &llvalue))
11580     {
11581       if (!error_found && check_final_assignment (llvalue, wfl_op1))
11582         {
11583           /* What we should do instead is resetting the all the flags
11584              previously set, exchange lvalue for llvalue and continue. */
11585           error_found = 1;
11586           return error_mark_node;
11587         }
11588       else 
11589         lhs_type = TREE_TYPE (lvalue);
11590     }
11591   else 
11592     {
11593       parse_error_context (wfl_op1, "Invalid left hand side of assignment");
11594       error_found = 1;
11595     }
11596
11597   rhs_type = TREE_TYPE (rhs);
11598   /* 5.1 Try the assignment conversion for builtin type. */
11599   new_rhs = try_builtin_assignconv (wfl_op1, lhs_type, rhs);
11600
11601   /* 5.2 If it failed, try a reference conversion */
11602   if (!new_rhs && (new_rhs = try_reference_assignconv (lhs_type, rhs)))
11603     lhs_type = promote_type (rhs_type);
11604
11605   /* 15.25.2 If we have a compound assignment, convert RHS into the
11606      type of the LHS */
11607   else if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
11608     new_rhs = convert (lhs_type, rhs);
11609
11610   /* Explicit cast required. This is an error */
11611   if (!new_rhs)
11612     {
11613       char *t1 = xstrdup (lang_printable_name (TREE_TYPE (rhs), 0));
11614       char *t2 = xstrdup (lang_printable_name (lhs_type, 0));
11615       tree wfl;
11616       char operation [32];      /* Max size known */
11617
11618       /* If the assignment is part of a declaration, we use the WFL of
11619          the declared variable to point out the error and call it a
11620          declaration problem. If the assignment is a genuine =
11621          operator, we call is a operator `=' problem, otherwise we
11622          call it an assignment problem. In both of these last cases,
11623          we use the WFL of the operator to indicate the error. */
11624
11625       if (MODIFY_EXPR_FROM_INITIALIZATION_P (node))
11626         {
11627           wfl = wfl_op1;
11628           strcpy (operation, "declaration");
11629         }
11630       else
11631         {
11632           wfl = wfl_operator;
11633           if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
11634             strcpy (operation, "assignment");
11635           else if (TREE_CODE (TREE_OPERAND (node, 0)) == RESULT_DECL)
11636             strcpy (operation, "`return'");
11637           else
11638             strcpy (operation, "`='");
11639         }
11640
11641       if (!valid_cast_to_p (rhs_type, lhs_type))
11642         parse_error_context
11643           (wfl, "Incompatible type for %s. Can't convert `%s' to `%s'",
11644            operation, t1, t2);
11645       else
11646         parse_error_context (wfl, "Incompatible type for %s. Explicit cast needed to convert `%s' to `%s'",
11647                              operation, t1, t2);
11648       free (t1); free (t2);
11649       error_found = 1;
11650     }
11651
11652   /* Inline read access to java.lang.PRIMTYPE.TYPE */
11653   if (new_rhs)
11654     new_rhs = maybe_build_primttype_type_ref (new_rhs, wfl_op2);
11655
11656   if (error_found)
11657     return error_mark_node;
11658
11659   /* 10.10: Array Store Exception runtime check */
11660   if (!flag_emit_class_files
11661       && !flag_emit_xref
11662       && lvalue_from_array 
11663       && JREFERENCE_TYPE_P (TYPE_ARRAY_ELEMENT (lhs_type)))
11664     {
11665       tree check;
11666       tree base = lvalue;
11667
11668       /* We need to retrieve the right argument for _Jv_CheckArrayStore */
11669       if (TREE_CODE (lvalue) == COMPOUND_EXPR)
11670         base = TREE_OPERAND (lvalue, 0);
11671       else
11672         {
11673           if (flag_bounds_check)
11674             base = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (base, 0), 1), 0);
11675           else
11676             base = TREE_OPERAND (TREE_OPERAND (base, 0), 0);
11677         }
11678
11679       /* Build the invocation of _Jv_CheckArrayStore */
11680       new_rhs = save_expr (new_rhs);
11681       check = build (CALL_EXPR, void_type_node,
11682                      build_address_of (soft_checkarraystore_node),
11683                      tree_cons (NULL_TREE, base,
11684                                 build_tree_list (NULL_TREE, new_rhs)),
11685                      NULL_TREE);
11686       TREE_SIDE_EFFECTS (check) = 1;
11687
11688       /* We have to decide on an insertion point */
11689       if (TREE_CODE (lvalue) == COMPOUND_EXPR)
11690         {
11691           tree t;
11692           if (flag_bounds_check)
11693             {
11694               t = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (lvalue, 1), 0), 0);
11695               TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (lvalue, 1), 0), 0) =
11696                 build (COMPOUND_EXPR, void_type_node, t, check);
11697             }
11698           else
11699             TREE_OPERAND (lvalue, 1) = build (COMPOUND_EXPR, lhs_type,
11700                                               check, TREE_OPERAND (lvalue, 1));
11701         }
11702       else 
11703         {
11704           /* Make sure the bound check will happen before the store check */
11705           if (flag_bounds_check)
11706             TREE_OPERAND (TREE_OPERAND (lvalue, 0), 0) =
11707               build (COMPOUND_EXPR, void_type_node,
11708                      TREE_OPERAND (TREE_OPERAND (lvalue, 0), 0), check);
11709           else
11710             lvalue = build (COMPOUND_EXPR, lhs_type, check, lvalue);
11711         }
11712     }
11713
11714   TREE_OPERAND (node, 0) = lvalue;
11715   TREE_OPERAND (node, 1) = new_rhs;
11716   TREE_TYPE (node) = lhs_type;
11717   return node;
11718 }
11719
11720 /* Check that type SOURCE can be cast into type DEST. If the cast
11721    can't occur at all, return 0 otherwise 1. This function is used to
11722    produce accurate error messages on the reasons why an assignment
11723    failed. */
11724
11725 static tree
11726 try_reference_assignconv (lhs_type, rhs)
11727      tree lhs_type, rhs;
11728 {
11729   tree new_rhs = NULL_TREE;
11730   tree rhs_type = TREE_TYPE (rhs);
11731
11732   if (!JPRIMITIVE_TYPE_P (rhs_type) && JREFERENCE_TYPE_P (lhs_type))
11733     {
11734       /* `null' may be assigned to any reference type */
11735       if (rhs == null_pointer_node)
11736         new_rhs = null_pointer_node;
11737       /* Try the reference assignment conversion */
11738       else if (valid_ref_assignconv_cast_p (rhs_type, lhs_type, 0))
11739         new_rhs = rhs;
11740       /* This is a magic assignment that we process differently */
11741       else if (rhs == soft_exceptioninfo_call_node)
11742         new_rhs = rhs;
11743     }
11744   return new_rhs;
11745 }
11746
11747 /* Check that RHS can be converted into LHS_TYPE by the assignment
11748    conversion (5.2), for the cases of RHS being a builtin type. Return
11749    NULL_TREE if the conversion fails or if because RHS isn't of a
11750    builtin type. Return a converted RHS if the conversion is possible.  */
11751
11752 static tree
11753 try_builtin_assignconv (wfl_op1, lhs_type, rhs)
11754      tree wfl_op1, lhs_type, rhs;
11755 {
11756   tree new_rhs = NULL_TREE;
11757   tree rhs_type = TREE_TYPE (rhs);
11758
11759   /* Zero accepted everywhere */
11760   if (TREE_CODE (rhs) == INTEGER_CST 
11761       && TREE_INT_CST_HIGH (rhs) == 0 && TREE_INT_CST_LOW (rhs) == 0
11762       && JPRIMITIVE_TYPE_P (rhs_type))
11763     new_rhs = convert (lhs_type, rhs);
11764
11765   /* 5.1.1 Try Identity Conversion,
11766      5.1.2 Try Widening Primitive Conversion */
11767   else if (valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type))
11768     new_rhs = convert (lhs_type, rhs);
11769
11770   /* Try a narrowing primitive conversion (5.1.3): 
11771        - expression is a constant expression of type int AND
11772        - variable is byte, short or char AND
11773        - The value of the expression is representable in the type of the 
11774          variable */
11775   else if (rhs_type == int_type_node && TREE_CONSTANT (rhs)
11776            && (lhs_type == byte_type_node || lhs_type == char_type_node
11777                || lhs_type == short_type_node))
11778     {
11779       if (int_fits_type_p (rhs, lhs_type))
11780         new_rhs = convert (lhs_type, rhs);
11781       else if (wfl_op1)         /* Might be called with a NULL */
11782         parse_warning_context 
11783           (wfl_op1, "Constant expression `%s' to wide for narrowing primitive conversion to `%s'", 
11784            print_int_node (rhs), lang_printable_name (lhs_type, 0));
11785       /* Reported a warning that will turn into an error further
11786          down, so we don't return */
11787     }
11788
11789   return new_rhs;
11790 }
11791
11792 /* Return 1 if RHS_TYPE can be converted to LHS_TYPE by identity
11793    conversion (5.1.1) or widening primitve conversion (5.1.2).  Return
11794    0 is the conversion test fails.  This implements parts the method
11795    invocation convertion (5.3).  */
11796
11797 static int
11798 valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type)
11799      tree lhs_type, rhs_type;
11800 {
11801   /* 5.1.1: This is the identity conversion part. */
11802   if (lhs_type == rhs_type)
11803     return 1;
11804
11805   /* Reject non primitive types */
11806   if (!JPRIMITIVE_TYPE_P (lhs_type) || !JPRIMITIVE_TYPE_P (rhs_type))
11807     return 0;
11808
11809   /* 5.1.2: widening primitive conversion. byte, even if it's smaller
11810      than a char can't be converted into a char. Short can't too, but
11811      the < test below takes care of that */
11812   if (lhs_type == char_type_node && rhs_type == byte_type_node)
11813     return 0;
11814
11815   /* Accept all promoted type here. Note, we can't use <= in the test
11816      below, because we still need to bounce out assignments of short
11817      to char and the likes */
11818   if (lhs_type == int_type_node
11819       && (rhs_type == promoted_byte_type_node
11820           || rhs_type == promoted_short_type_node
11821           || rhs_type == promoted_char_type_node
11822           || rhs_type == promoted_boolean_type_node))
11823     return 1;
11824
11825   /* From here, an integral is widened if its precision is smaller
11826      than the precision of the LHS or if the LHS is a floating point
11827      type, or the RHS is a float and the RHS a double. */
11828   if ((JINTEGRAL_TYPE_P (rhs_type) && JINTEGRAL_TYPE_P (lhs_type) 
11829        && (TYPE_PRECISION (rhs_type) < TYPE_PRECISION (lhs_type)))
11830       || (JINTEGRAL_TYPE_P (rhs_type) && JFLOAT_TYPE_P (lhs_type))
11831       || (rhs_type == float_type_node && lhs_type == double_type_node))
11832     return 1;
11833
11834   return 0;
11835 }
11836
11837 /* Check that something of SOURCE type can be assigned or cast to
11838    something of DEST type at runtime. Return 1 if the operation is
11839    valid, 0 otherwise. If CAST is set to 1, we're treating the case
11840    were SOURCE is cast into DEST, which borrows a lot of the
11841    assignment check. */
11842
11843 static int
11844 valid_ref_assignconv_cast_p (source, dest, cast)
11845      tree source;
11846      tree dest;
11847      int cast;
11848 {
11849   /* SOURCE or DEST might be null if not from a declared entity. */
11850   if (!source || !dest)
11851     return 0;
11852   if (JNULLP_TYPE_P (source))
11853     return 1;
11854   if (TREE_CODE (source) == POINTER_TYPE)
11855     source = TREE_TYPE (source);
11856   if (TREE_CODE (dest) == POINTER_TYPE)
11857     dest = TREE_TYPE (dest);
11858   /* Case where SOURCE is a class type */
11859   if (TYPE_CLASS_P (source))
11860     {
11861       if (TYPE_CLASS_P (dest))
11862         return  (source == dest 
11863                  || inherits_from_p (source, dest)
11864                  || enclosing_context_p (dest, source /*source, dest*/)
11865                  || (cast && inherits_from_p (dest, source)));
11866       if (TYPE_INTERFACE_P (dest))
11867         {
11868           /* If doing a cast and SOURCE is final, the operation is
11869              always correct a compile time (because even if SOURCE
11870              does not implement DEST, a subclass of SOURCE might). */
11871           if (cast && !CLASS_FINAL (TYPE_NAME (source)))
11872             return 1;
11873           /* Otherwise, SOURCE must implement DEST */
11874           return interface_of_p (dest, source);
11875         }
11876       /* DEST is an array, cast permited if SOURCE is of Object type */
11877       return (cast && source == object_type_node ? 1 : 0);
11878     }
11879   if (TYPE_INTERFACE_P (source))
11880     {
11881       if (TYPE_CLASS_P (dest))
11882         {
11883           /* If not casting, DEST must be the Object type */
11884           if (!cast)
11885             return dest == object_type_node;
11886           /* We're doing a cast. The cast is always valid is class
11887              DEST is not final, otherwise, DEST must implement SOURCE */
11888           else if (!CLASS_FINAL (TYPE_NAME (dest)))
11889             return 1;
11890           else
11891             return interface_of_p (source, dest);
11892         }
11893       if (TYPE_INTERFACE_P (dest))
11894         {
11895           /* If doing a cast, then if SOURCE and DEST contain method
11896              with the same signature but different return type, then
11897              this is a (compile time) error */
11898           if (cast)
11899             {
11900               tree method_source, method_dest;
11901               tree source_type;
11902               tree source_sig;
11903               tree source_name;
11904               for (method_source = TYPE_METHODS (source); method_source; 
11905                    method_source = TREE_CHAIN (method_source))
11906                 {
11907                   source_sig = 
11908                     build_java_argument_signature (TREE_TYPE (method_source));
11909                   source_type = TREE_TYPE (TREE_TYPE (method_source));
11910                   source_name = DECL_NAME (method_source);
11911                   for (method_dest = TYPE_METHODS (dest);
11912                        method_dest; method_dest = TREE_CHAIN (method_dest))
11913                     if (source_sig == 
11914                         build_java_argument_signature (TREE_TYPE (method_dest))
11915                         && source_name == DECL_NAME (method_dest)
11916                         && source_type != TREE_TYPE (TREE_TYPE (method_dest)))
11917                       return 0;
11918                 }
11919               return 1;
11920             }
11921           else
11922             return source == dest || interface_of_p (dest, source);
11923         }
11924       else                      /* Array */
11925         return (cast ? 
11926                 (DECL_NAME (TYPE_NAME (source)) == java_lang_cloneable) : 0);
11927     }
11928   if (TYPE_ARRAY_P (source))
11929     {
11930       if (TYPE_CLASS_P (dest))
11931         return dest == object_type_node;
11932       /* Can't cast an array to an interface unless the interface is
11933          java.lang.Cloneable */
11934       if (TYPE_INTERFACE_P (dest))
11935         return (DECL_NAME (TYPE_NAME (dest)) == java_lang_cloneable ? 1 : 0);
11936       else                      /* Arrays */
11937         {
11938           tree source_element_type = TYPE_ARRAY_ELEMENT (source);
11939           tree dest_element_type = TYPE_ARRAY_ELEMENT (dest);
11940           
11941           /* In case of severe errors, they turn out null */
11942           if (!dest_element_type || !source_element_type)
11943             return 0;
11944           if (source_element_type == dest_element_type)
11945             return 1;
11946           return valid_ref_assignconv_cast_p (source_element_type,
11947                                               dest_element_type, cast);
11948         }
11949       return 0;
11950     }
11951   return 0;
11952 }
11953
11954 static int
11955 valid_cast_to_p (source, dest)
11956      tree source;
11957      tree dest;
11958 {
11959   if (TREE_CODE (source) == POINTER_TYPE)
11960     source = TREE_TYPE (source);
11961   if (TREE_CODE (dest) == POINTER_TYPE)
11962     dest = TREE_TYPE (dest);
11963
11964   if (TREE_CODE (source) == RECORD_TYPE && TREE_CODE (dest) == RECORD_TYPE)
11965     return valid_ref_assignconv_cast_p (source, dest, 1);
11966
11967   else if (JNUMERIC_TYPE_P (source) && JNUMERIC_TYPE_P (dest))
11968     return 1;
11969
11970   return 0;
11971 }
11972
11973 /* Method invocation conversion test. Return 1 if type SOURCE can be
11974    converted to type DEST through the methond invocation conversion
11975    process (5.3) */
11976
11977 static tree
11978 do_unary_numeric_promotion (arg)
11979      tree arg;
11980 {
11981   tree type = TREE_TYPE (arg);
11982   if (TREE_CODE (type) == INTEGER_TYPE ? TYPE_PRECISION (type) < 32
11983       : TREE_CODE (type) == CHAR_TYPE)
11984     arg = convert (int_type_node, arg);
11985   return arg;
11986 }
11987
11988 /* Return a non zero value if SOURCE can be converted into DEST using
11989    the method invocation conversion rule (5.3).  */
11990 static int
11991 valid_method_invocation_conversion_p (dest, source)
11992      tree dest, source;
11993 {
11994   return ((JPRIMITIVE_TYPE_P (source) && JPRIMITIVE_TYPE_P (dest)
11995            && valid_builtin_assignconv_identity_widening_p (dest, source))
11996           || ((JREFERENCE_TYPE_P (source) || JNULLP_TYPE_P (source))
11997               && (JREFERENCE_TYPE_P (dest) || JNULLP_TYPE_P (dest))
11998               && valid_ref_assignconv_cast_p (source, dest, 0)));
11999 }
12000
12001 /* Build an incomplete binop expression. */
12002
12003 static tree
12004 build_binop (op, op_location, op1, op2)
12005      enum tree_code op;
12006      int op_location;
12007      tree op1, op2;
12008 {
12009   tree binop = build (op, NULL_TREE, op1, op2);
12010   TREE_SIDE_EFFECTS (binop) = 1;
12011   /* Store the location of the operator, for better error report. The
12012      string of the operator will be rebuild based on the OP value. */
12013   EXPR_WFL_LINECOL (binop) = op_location;
12014   return binop;
12015 }
12016
12017 /* Build the string of the operator retained by NODE. If NODE is part
12018    of a compound expression, add an '=' at the end of the string. This
12019    function is called when an error needs to be reported on an
12020    operator. The string is returned as a pointer to a static character
12021    buffer. */
12022
12023 static char *
12024 operator_string (node)
12025      tree node;
12026 {
12027 #define BUILD_OPERATOR_STRING(S)                                        \
12028   {                                                                     \
12029     sprintf (buffer, "%s%s", S, (COMPOUND_ASSIGN_P (node) ? "=" : "")); \
12030     return buffer;                                                      \
12031   }
12032   
12033   static char buffer [10];
12034   switch (TREE_CODE (node))
12035     {
12036     case MULT_EXPR: BUILD_OPERATOR_STRING ("*");
12037     case RDIV_EXPR: BUILD_OPERATOR_STRING ("/");
12038     case TRUNC_MOD_EXPR: BUILD_OPERATOR_STRING ("%");
12039     case PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
12040     case MINUS_EXPR: BUILD_OPERATOR_STRING ("-");
12041     case LSHIFT_EXPR: BUILD_OPERATOR_STRING ("<<");
12042     case RSHIFT_EXPR: BUILD_OPERATOR_STRING (">>");
12043     case URSHIFT_EXPR: BUILD_OPERATOR_STRING (">>>");
12044     case BIT_AND_EXPR: BUILD_OPERATOR_STRING ("&");
12045     case BIT_XOR_EXPR: BUILD_OPERATOR_STRING ("^");
12046     case BIT_IOR_EXPR: BUILD_OPERATOR_STRING ("|");
12047     case TRUTH_ANDIF_EXPR: BUILD_OPERATOR_STRING ("&&");
12048     case TRUTH_ORIF_EXPR: BUILD_OPERATOR_STRING ("||");
12049     case EQ_EXPR: BUILD_OPERATOR_STRING ("==");
12050     case NE_EXPR: BUILD_OPERATOR_STRING ("!=");
12051     case GT_EXPR: BUILD_OPERATOR_STRING (">");
12052     case GE_EXPR: BUILD_OPERATOR_STRING (">=");
12053     case LT_EXPR: BUILD_OPERATOR_STRING ("<");
12054     case LE_EXPR: BUILD_OPERATOR_STRING ("<=");
12055     case UNARY_PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
12056     case NEGATE_EXPR: BUILD_OPERATOR_STRING ("-");
12057     case TRUTH_NOT_EXPR: BUILD_OPERATOR_STRING ("!");
12058     case BIT_NOT_EXPR: BUILD_OPERATOR_STRING ("~");
12059     case PREINCREMENT_EXPR:     /* Fall through */
12060     case POSTINCREMENT_EXPR: BUILD_OPERATOR_STRING ("++");
12061     case PREDECREMENT_EXPR:     /* Fall through */
12062     case POSTDECREMENT_EXPR: BUILD_OPERATOR_STRING ("--");
12063     default:
12064       fatal ("unregistered operator %s - operator_string",
12065              tree_code_name [TREE_CODE (node)]);
12066     }
12067   return NULL;
12068 #undef BUILD_OPERATOR_STRING
12069 }
12070
12071 /* Return 1 if VAR_ACCESS1 is equivalent to VAR_ACCESS2.  */
12072
12073 static int
12074 java_decl_equiv (var_acc1, var_acc2)
12075      tree var_acc1, var_acc2;
12076 {
12077   if (JDECL_P (var_acc1))
12078     return (var_acc1 == var_acc2);
12079   
12080   return (TREE_CODE (var_acc1) == COMPONENT_REF
12081           && TREE_CODE (var_acc2) == COMPONENT_REF
12082           && TREE_OPERAND (TREE_OPERAND (var_acc1, 0), 0)
12083              == TREE_OPERAND (TREE_OPERAND (var_acc2, 0), 0)
12084           && TREE_OPERAND (var_acc1, 1) == TREE_OPERAND (var_acc2, 1));
12085 }
12086
12087 /* Return a non zero value if CODE is one of the operators that can be
12088    used in conjunction with the `=' operator in a compound assignment.  */
12089
12090 static int
12091 binop_compound_p (code)
12092     enum tree_code code;
12093 {
12094   int i;
12095   for (i = 0; i < BINOP_COMPOUND_CANDIDATES; i++)
12096     if (binop_lookup [i] == code)
12097       break;
12098
12099   return i < BINOP_COMPOUND_CANDIDATES;
12100 }
12101
12102 /* Reorganize after a fold to get SAVE_EXPR to generate what we want.  */
12103
12104 static tree
12105 java_refold (t)
12106      tree t;
12107 {
12108   tree c, b, ns, decl;
12109
12110   if (TREE_CODE (t) != MODIFY_EXPR)
12111     return t;
12112
12113   c = TREE_OPERAND (t, 1);
12114   if (! (c && TREE_CODE (c) == COMPOUND_EXPR
12115          && TREE_CODE (TREE_OPERAND (c, 0)) == MODIFY_EXPR
12116          && binop_compound_p (TREE_CODE (TREE_OPERAND (c, 1)))))
12117     return t;
12118
12119   /* Now the left branch of the binary operator. */
12120   b = TREE_OPERAND (TREE_OPERAND (c, 1), 0);
12121   if (! (b && TREE_CODE (b) == NOP_EXPR 
12122          && TREE_CODE (TREE_OPERAND (b, 0)) == SAVE_EXPR))
12123     return t;
12124
12125   ns = TREE_OPERAND (TREE_OPERAND (b, 0), 0);
12126   if (! (ns && TREE_CODE (ns) == NOP_EXPR
12127          && TREE_CODE (TREE_OPERAND (ns, 0)) == SAVE_EXPR))
12128     return t;
12129
12130   decl = TREE_OPERAND (TREE_OPERAND (ns, 0), 0);
12131   if ((JDECL_P (decl) || TREE_CODE (decl) == COMPONENT_REF)
12132       /* It's got to be the an equivalent decl */
12133       && java_decl_equiv (decl, TREE_OPERAND (TREE_OPERAND (c, 0), 0)))
12134     {
12135       /* Shorten the NOP_EXPR/SAVE_EXPR path. */
12136       TREE_OPERAND (TREE_OPERAND (c, 1), 0) = TREE_OPERAND (ns, 0);
12137       /* Substitute the COMPOUND_EXPR by the BINOP_EXPR */
12138       TREE_OPERAND (t, 1) = TREE_OPERAND (c, 1);
12139       /* Change the right part of the BINOP_EXPR */
12140       TREE_OPERAND (TREE_OPERAND (t, 1), 1) = TREE_OPERAND (c, 0);
12141     }
12142
12143   return t;
12144 }
12145
12146 /* Binary operators (15.16 up to 15.18). We return error_mark_node on
12147    errors but we modify NODE so that it contains the type computed
12148    according to the expression, when it's fixed. Otherwise, we write
12149    error_mark_node as the type. It allows us to further the analysis
12150    of remaining nodes and detects more errors in certain cases.  */
12151
12152 static tree
12153 patch_binop (node, wfl_op1, wfl_op2)
12154      tree node;
12155      tree wfl_op1;
12156      tree wfl_op2;
12157 {
12158   tree op1 = TREE_OPERAND (node, 0);
12159   tree op2 = TREE_OPERAND (node, 1);
12160   tree op1_type = TREE_TYPE (op1);
12161   tree op2_type = TREE_TYPE (op2);
12162   tree prom_type = NULL_TREE, cn;
12163   int code = TREE_CODE (node);
12164
12165   /* If 1, tell the routine that we have to return error_mark_node
12166      after checking for the initialization of the RHS */
12167   int error_found = 0;
12168
12169   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
12170
12171   switch (code)
12172     {
12173     /* 15.16 Multiplicative operators */
12174     case MULT_EXPR:             /* 15.16.1 Multiplication Operator * */
12175     case RDIV_EXPR:             /* 15.16.2 Division Operator / */
12176     case TRUNC_DIV_EXPR:        /* 15.16.2 Integral type Division Operator / */
12177     case TRUNC_MOD_EXPR:        /* 15.16.3 Remainder operator % */
12178       if (!JPRIMITIVE_TYPE_P (op1_type) || !JPRIMITIVE_TYPE_P (op2_type))
12179         {
12180           if (!JPRIMITIVE_TYPE_P (op1_type))
12181             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
12182           if (!JPRIMITIVE_TYPE_P (op2_type) && (op1_type != op2_type))
12183             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
12184           TREE_TYPE (node) = error_mark_node;
12185           error_found = 1;
12186           break;
12187         }
12188       prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12189       /* Change the division operator if necessary */
12190       if (code == RDIV_EXPR && TREE_CODE (prom_type) == INTEGER_TYPE)
12191         TREE_SET_CODE (node, TRUNC_DIV_EXPR);
12192
12193       if (TREE_CODE (prom_type) == INTEGER_TYPE
12194           && flag_use_divide_subroutine
12195           && ! flag_emit_class_files
12196           && (code == RDIV_EXPR || code == TRUNC_MOD_EXPR))
12197         return build_java_soft_divmod (TREE_CODE (node), prom_type, op1, op2);
12198  
12199       /* This one is more complicated. FLOATs are processed by a
12200          function call to soft_fmod. Duplicate the value of the
12201          COMPOUND_ASSIGN_P flag. */
12202       if (code == TRUNC_MOD_EXPR)
12203         {
12204           tree mod = build_java_binop (TRUNC_MOD_EXPR, prom_type, op1, op2);
12205           COMPOUND_ASSIGN_P (mod) = COMPOUND_ASSIGN_P (node);
12206           TREE_SIDE_EFFECTS (mod)
12207             = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
12208           return mod;
12209         }
12210       break;
12211
12212     /* 15.17 Additive Operators */
12213     case PLUS_EXPR:             /* 15.17.1 String Concatenation Operator + */
12214
12215       /* Operation is valid if either one argument is a string
12216          constant, a String object or a StringBuffer crafted for the
12217          purpose of the a previous usage of the String concatenation
12218          operator */
12219
12220       if (TREE_CODE (op1) == STRING_CST 
12221           || TREE_CODE (op2) == STRING_CST
12222           || JSTRING_TYPE_P (op1_type)
12223           || JSTRING_TYPE_P (op2_type)
12224           || IS_CRAFTED_STRING_BUFFER_P (op1)
12225           || IS_CRAFTED_STRING_BUFFER_P (op2))
12226         return build_string_concatenation (op1, op2);
12227
12228     case MINUS_EXPR:            /* 15.17.2 Additive Operators (+ and -) for
12229                                    Numeric Types */
12230       if (!JPRIMITIVE_TYPE_P (op1_type) || !JPRIMITIVE_TYPE_P (op2_type))
12231         {
12232           if (!JPRIMITIVE_TYPE_P (op1_type))
12233             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
12234           if (!JPRIMITIVE_TYPE_P (op2_type) && (op1_type != op2_type))
12235             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
12236           TREE_TYPE (node) = error_mark_node;
12237           error_found = 1;
12238           break;
12239         }
12240       prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12241       break;
12242
12243     /* 15.18 Shift Operators */
12244     case LSHIFT_EXPR:
12245     case RSHIFT_EXPR:
12246     case URSHIFT_EXPR:
12247       if (!JINTEGRAL_TYPE_P (op1_type) || !JINTEGRAL_TYPE_P (op2_type))
12248         {
12249           if (!JINTEGRAL_TYPE_P (op1_type))
12250             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
12251           else
12252             {
12253               if (JPRIMITIVE_TYPE_P (op2_type))
12254                 parse_error_context (wfl_operator,
12255                                      "Incompatible type for `%s'. Explicit cast needed to convert shift distance from `%s' to integral",
12256                                      operator_string (node),
12257                                      lang_printable_name (op2_type, 0));
12258               else
12259                 parse_error_context (wfl_operator,
12260                                      "Incompatible type for `%s'. Can't convert shift distance from `%s' to integral", 
12261                                      operator_string (node),
12262                                      lang_printable_name (op2_type, 0));
12263             }
12264           TREE_TYPE (node) = error_mark_node;
12265           error_found = 1;
12266           break;
12267         }
12268
12269       /* Unary numeric promotion (5.6.1) is performed on each operand
12270          separatly */
12271       op1 = do_unary_numeric_promotion (op1);
12272       op2 = do_unary_numeric_promotion (op2);
12273
12274       /* The type of the shift expression is the type of the promoted
12275          type of the left-hand operand */
12276       prom_type = TREE_TYPE (op1);
12277
12278       /* Shift int only up to 0x1f and long up to 0x3f */
12279       if (prom_type == int_type_node)
12280         op2 = fold (build (BIT_AND_EXPR, int_type_node, op2, 
12281                            build_int_2 (0x1f, 0)));
12282       else
12283         op2 = fold (build (BIT_AND_EXPR, int_type_node, op2, 
12284                            build_int_2 (0x3f, 0)));
12285
12286       /* The >>> operator is a >> operating on unsigned quantities */
12287       if (code == URSHIFT_EXPR && ! flag_emit_class_files)
12288         {
12289           tree to_return;
12290           tree utype = unsigned_type (prom_type);
12291           op1 = convert (utype, op1);
12292           TREE_SET_CODE (node, RSHIFT_EXPR);
12293           TREE_OPERAND (node, 0) = op1;
12294           TREE_OPERAND (node, 1) = op2;
12295           TREE_TYPE (node) = utype;
12296           to_return = convert (prom_type, node);
12297           /* Copy the original value of the COMPOUND_ASSIGN_P flag */
12298           COMPOUND_ASSIGN_P (to_return) = COMPOUND_ASSIGN_P (node);
12299           TREE_SIDE_EFFECTS (to_return)
12300             = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
12301           return to_return;
12302         }
12303       break;
12304
12305       /* 15.19.1 Type Comparison Operator instaceof */
12306     case INSTANCEOF_EXPR:
12307
12308       TREE_TYPE (node) = boolean_type_node;
12309
12310       if (!(op2_type = resolve_type_during_patch (op2)))
12311         return error_mark_node;
12312
12313       /* The first operand must be a reference type or the null type */
12314       if (!JREFERENCE_TYPE_P (op1_type) && op1 != null_pointer_node)
12315         error_found = 1;        /* Error reported further below */
12316
12317       /* The second operand must be a reference type */
12318       if (!JREFERENCE_TYPE_P (op2_type))
12319         {
12320           SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
12321           parse_error_context
12322             (wfl_operator, "Invalid argument `%s' for `instanceof'",
12323              lang_printable_name (op2_type, 0));
12324           error_found = 1;
12325         }
12326
12327       if (!error_found && valid_ref_assignconv_cast_p (op1_type, op2_type, 1))
12328         {
12329           /* If the first operand is null, the result is always false */
12330           if (op1 == null_pointer_node)
12331             return boolean_false_node;
12332           else if (flag_emit_class_files)
12333             {
12334               TREE_OPERAND (node, 1) = op2_type;
12335               TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1);
12336               return node;
12337             }
12338           /* Otherwise we have to invoke instance of to figure it out */
12339           else
12340             {
12341               tree call =
12342                 build (CALL_EXPR, boolean_type_node,
12343                        build_address_of (soft_instanceof_node),
12344                        tree_cons 
12345                        (NULL_TREE, op1,
12346                         build_tree_list (NULL_TREE,
12347                                          build_class_ref (op2_type))),
12348                        NULL_TREE);
12349               TREE_SIDE_EFFECTS (call) = TREE_SIDE_EFFECTS (op1);
12350               return call;
12351             }
12352         }
12353       /* There is no way the expression operand can be an instance of
12354          the type operand. This is a compile time error. */
12355       else
12356         {
12357           char *t1 = xstrdup (lang_printable_name (op1_type, 0));
12358           SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
12359           parse_error_context 
12360             (wfl_operator, "Impossible for `%s' to be instance of `%s'",
12361              t1, lang_printable_name (op2_type, 0));
12362           free (t1);
12363           error_found = 1;
12364         }
12365       
12366       break;
12367
12368       /* 15.21 Bitwise and Logical Operators */
12369     case BIT_AND_EXPR:
12370     case BIT_XOR_EXPR:
12371     case BIT_IOR_EXPR:
12372       if (JINTEGRAL_TYPE_P (op1_type) && JINTEGRAL_TYPE_P (op2_type))
12373         /* Binary numeric promotion is performed on both operand and the
12374            expression retain that type */
12375         prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12376
12377       else if (TREE_CODE (op1_type) == BOOLEAN_TYPE 
12378                && TREE_CODE (op1_type) == BOOLEAN_TYPE)
12379         /* The type of the bitwise operator expression is BOOLEAN */
12380         prom_type = boolean_type_node;
12381       else
12382         {
12383           if (!JINTEGRAL_TYPE_P (op1_type))
12384             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
12385           if (!JINTEGRAL_TYPE_P (op2_type) && (op1_type != op2_type))
12386             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op2_type);
12387           TREE_TYPE (node) = error_mark_node;
12388           error_found = 1;
12389           /* Insert a break here if adding thing before the switch's
12390              break for this case */
12391         }
12392       break;
12393
12394       /* 15.22 Conditional-And Operator */
12395     case TRUTH_ANDIF_EXPR:
12396       /* 15.23 Conditional-Or Operator */
12397     case TRUTH_ORIF_EXPR:
12398       /* Operands must be of BOOLEAN type */
12399       if (TREE_CODE (op1_type) != BOOLEAN_TYPE || 
12400           TREE_CODE (op2_type) != BOOLEAN_TYPE)
12401         {
12402           if (TREE_CODE (op1_type) != BOOLEAN_TYPE)
12403             ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op1_type);
12404           if (TREE_CODE (op2_type) != BOOLEAN_TYPE && (op1_type != op2_type))
12405             ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op2_type);
12406           TREE_TYPE (node) = boolean_type_node;
12407           error_found = 1;
12408           break;
12409         }
12410       /* The type of the conditional operators is BOOLEAN */
12411       prom_type = boolean_type_node;
12412       break;
12413
12414       /* 15.19.1 Numerical Comparison Operators <, <=, >, >= */
12415     case LT_EXPR:
12416     case GT_EXPR:
12417     case LE_EXPR:
12418     case GE_EXPR:
12419       /* The type of each of the operands must be a primitive numeric
12420          type */
12421       if (!JNUMERIC_TYPE_P (op1_type) || ! JNUMERIC_TYPE_P (op2_type))
12422         {
12423           if (!JNUMERIC_TYPE_P (op1_type))
12424             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
12425           if (!JNUMERIC_TYPE_P (op2_type) && (op1_type != op2_type))
12426             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
12427           TREE_TYPE (node) = boolean_type_node;
12428           error_found = 1;
12429           break;
12430         }
12431       /* Binary numeric promotion is performed on the operands */
12432       binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12433       /* The type of the relation expression is always BOOLEAN */
12434       prom_type = boolean_type_node;
12435       break;
12436
12437       /* 15.20 Equality Operator */
12438     case EQ_EXPR:
12439     case NE_EXPR:
12440       /* It's time for us to patch the strings. */
12441       if ((cn = patch_string (op1))) 
12442        {
12443          op1 = cn;
12444          op1_type = TREE_TYPE (op1);
12445        }
12446       if ((cn = patch_string (op2))) 
12447        {
12448          op2 = cn;
12449          op2_type = TREE_TYPE (op2);
12450        }
12451       
12452       /* 15.20.1 Numerical Equality Operators == and != */
12453       /* Binary numeric promotion is performed on the operands */
12454       if (JNUMERIC_TYPE_P (op1_type) && JNUMERIC_TYPE_P (op2_type))
12455         binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12456       
12457       /* 15.20.2 Boolean Equality Operators == and != */
12458       else if (TREE_CODE (op1_type) == BOOLEAN_TYPE &&
12459           TREE_CODE (op2_type) == BOOLEAN_TYPE)
12460         ;                       /* Nothing to do here */
12461       
12462       /* 15.20.3 Reference Equality Operators == and != */
12463       /* Types have to be either references or the null type. If
12464          they're references, it must be possible to convert either
12465          type to the other by casting conversion. */
12466       else if (op1 == null_pointer_node || op2 == null_pointer_node 
12467                || (JREFERENCE_TYPE_P (op1_type) && JREFERENCE_TYPE_P (op2_type)
12468                    && (valid_ref_assignconv_cast_p (op1_type, op2_type, 1)
12469                        || valid_ref_assignconv_cast_p (op2_type, 
12470                                                        op1_type, 1))))
12471         ;                       /* Nothing to do here */
12472           
12473       /* Else we have an error figure what can't be converted into
12474          what and report the error */
12475       else
12476         {
12477           char *t1;
12478           t1 = xstrdup (lang_printable_name (op1_type, 0));
12479           parse_error_context 
12480             (wfl_operator,
12481              "Incompatible type for `%s'. Can't convert `%s' to `%s'",
12482              operator_string (node), t1, 
12483              lang_printable_name (op2_type, 0));
12484           free (t1);
12485           TREE_TYPE (node) = boolean_type_node;
12486           error_found = 1;
12487           break;
12488         }
12489       prom_type = boolean_type_node;
12490       break;
12491     }
12492
12493   if (error_found)
12494     return error_mark_node;
12495
12496   TREE_OPERAND (node, 0) = op1;
12497   TREE_OPERAND (node, 1) = op2;
12498   TREE_TYPE (node) = prom_type;
12499   TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
12500   
12501   if (flag_emit_xref)
12502     return node;
12503
12504   /* fold does not respect side-effect order as required for Java but not C.
12505    * Also, it sometimes create SAVE_EXPRs which are bad when emitting
12506    * bytecode.
12507    */
12508   if (flag_emit_class_files ? (TREE_CONSTANT (op1) && TREE_CONSTANT (op2))
12509       : ! TREE_SIDE_EFFECTS (node))
12510     node = fold (node);
12511   return node;
12512 }
12513
12514 /* Concatenate the STRING_CST CSTE and STRING. When AFTER is a non
12515    zero value, the value of CSTE comes after the valude of STRING */
12516
12517 static tree
12518 do_merge_string_cste (cste, string, string_len, after)
12519      tree cste;
12520      const char *string;
12521      int string_len, after;
12522 {
12523   int len = TREE_STRING_LENGTH (cste) + string_len;
12524   const char *old = TREE_STRING_POINTER (cste);
12525   TREE_STRING_LENGTH (cste) = len;
12526   TREE_STRING_POINTER (cste) = obstack_alloc (expression_obstack, len+1);
12527   if (after)
12528     {
12529       strcpy (TREE_STRING_POINTER (cste), string);
12530       strcat (TREE_STRING_POINTER (cste), old);
12531     }
12532   else
12533     {
12534       strcpy (TREE_STRING_POINTER (cste), old);
12535       strcat (TREE_STRING_POINTER (cste), string);
12536     }
12537   return cste;
12538 }
12539
12540 /* Tries to merge OP1 (a STRING_CST) and OP2 (if suitable). Return a
12541    new STRING_CST on success, NULL_TREE on failure */
12542
12543 static tree
12544 merge_string_cste (op1, op2, after)
12545      tree op1, op2;
12546      int after;
12547 {
12548   /* Handle two string constants right away */
12549   if (TREE_CODE (op2) == STRING_CST)
12550     return do_merge_string_cste (op1, TREE_STRING_POINTER (op2), 
12551                                  TREE_STRING_LENGTH (op2), after);
12552   
12553   /* Reasonable integer constant can be treated right away */
12554   if (TREE_CODE (op2) == INTEGER_CST && !TREE_CONSTANT_OVERFLOW (op2))
12555     {
12556       static const char *boolean_true = "true";
12557       static const char *boolean_false = "false";
12558       static const char *null_pointer = "null";
12559       char ch[3];
12560       const char *string;
12561       
12562       if (op2 == boolean_true_node)
12563         string = boolean_true;
12564       else if (op2 == boolean_false_node)
12565         string = boolean_false;
12566       else if (op2 == null_pointer_node)
12567         string = null_pointer;
12568       else if (TREE_TYPE (op2) == char_type_node)
12569         {
12570           ch[0] = (char )TREE_INT_CST_LOW (op2);
12571           ch[1] = '\0';
12572           string = ch;
12573         }
12574       else
12575           string = print_int_node (op2);
12576       
12577       return do_merge_string_cste (op1, string, strlen (string), after);
12578     }
12579   return NULL_TREE;
12580 }
12581
12582 /* Tries to statically concatenate OP1 and OP2 if possible. Either one
12583    has to be a STRING_CST and the other part must be a STRING_CST or a
12584    INTEGRAL constant. Return a new STRING_CST if the operation
12585    succeed, NULL_TREE otherwise.
12586
12587    If the case we want to optimize for space, we might want to return
12588    NULL_TREE for each invocation of this routine. FIXME */
12589
12590 static tree
12591 string_constant_concatenation (op1, op2)
12592      tree op1, op2;
12593 {
12594   if (TREE_CODE (op1) == STRING_CST || (TREE_CODE (op2) == STRING_CST))
12595     {
12596       tree string, rest;
12597       int invert;
12598       
12599       string = (TREE_CODE (op1) == STRING_CST ? op1 : op2);
12600       rest   = (string == op1 ? op2 : op1);
12601       invert = (string == op1 ? 0 : 1 );
12602       
12603       /* Walk REST, only if it looks reasonable */
12604       if (TREE_CODE (rest) != STRING_CST
12605           && !IS_CRAFTED_STRING_BUFFER_P (rest)
12606           && !JSTRING_TYPE_P (TREE_TYPE (rest))
12607           && TREE_CODE (rest) == EXPR_WITH_FILE_LOCATION)
12608         {
12609           rest = java_complete_tree (rest);
12610           if (rest == error_mark_node)
12611             return error_mark_node;
12612           rest = fold (rest);
12613         }
12614       return merge_string_cste (string, rest, invert);
12615     }
12616   return NULL_TREE;
12617 }
12618
12619 /* Implement the `+' operator. Does static optimization if possible,
12620    otherwise create (if necessary) and append elements to a
12621    StringBuffer. The StringBuffer will be carried around until it is
12622    used for a function call or an assignment. Then toString() will be
12623    called on it to turn it into a String object. */
12624
12625 static tree
12626 build_string_concatenation (op1, op2)
12627      tree op1, op2;
12628 {
12629   tree result;
12630   int side_effects = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
12631
12632   if (flag_emit_xref)
12633     return build (PLUS_EXPR, string_type_node, op1, op2);
12634   
12635   /* Try to do some static optimization */
12636   if ((result = string_constant_concatenation (op1, op2)))
12637     return result;
12638
12639   /* Discard empty strings on either side of the expression */
12640   if (TREE_CODE (op1) == STRING_CST && TREE_STRING_LENGTH (op1) == 0)
12641     {
12642       op1 = op2;
12643       op2 = NULL_TREE;
12644     }
12645   else if (TREE_CODE (op2) == STRING_CST && TREE_STRING_LENGTH (op2) == 0)
12646     op2 = NULL_TREE;
12647
12648   /* If operands are string constant, turn then into object references */
12649   if (TREE_CODE (op1) == STRING_CST)
12650     op1 = patch_string_cst (op1);
12651   if (op2 && TREE_CODE (op2) == STRING_CST)
12652     op2 = patch_string_cst (op2);
12653
12654   /* If either one of the constant is null and the other non null
12655      operand is a String object, return it. */
12656   if (JSTRING_TYPE_P (TREE_TYPE (op1)) && !op2)
12657     return op1;
12658
12659   /* If OP1 isn't already a StringBuffer, create and
12660      initialize a new one */
12661   if (!IS_CRAFTED_STRING_BUFFER_P (op1))
12662     {
12663       /* Two solutions here: 
12664          1) OP1 is a constant string reference, we call new StringBuffer(OP1)
12665          2) OP1 is something else, we call new StringBuffer().append(OP1).  */
12666       if (TREE_CONSTANT (op1) && JSTRING_TYPE_P (TREE_TYPE (op1)))
12667         op1 = BUILD_STRING_BUFFER (op1);
12668       else
12669         {
12670           tree aNew = BUILD_STRING_BUFFER (NULL_TREE);
12671           op1 = make_qualified_primary (aNew, BUILD_APPEND (op1), 0);
12672         }
12673     }
12674
12675   if (op2)
12676     {
12677       /* OP1 is no longer the last node holding a crafted StringBuffer */
12678       IS_CRAFTED_STRING_BUFFER_P (op1) = 0;
12679       /* Create a node for `{new...,xxx}.append (op2)' */
12680       if (op2)
12681         op1 = make_qualified_primary (op1, BUILD_APPEND (op2), 0);
12682     }
12683
12684   /* Mark the last node holding a crafted StringBuffer */
12685   IS_CRAFTED_STRING_BUFFER_P (op1) = 1;
12686
12687   TREE_SIDE_EFFECTS (op1) = side_effects;
12688   return op1;
12689 }
12690
12691 /* Patch the string node NODE. NODE can be a STRING_CST of a crafted
12692    StringBuffer. If no string were found to be patched, return
12693    NULL. */
12694
12695 static tree
12696 patch_string (node)
12697     tree node;
12698 {
12699   if (node == error_mark_node)
12700     return error_mark_node;
12701   if (TREE_CODE (node) == STRING_CST)
12702     return patch_string_cst (node);
12703   else if (IS_CRAFTED_STRING_BUFFER_P (node))
12704     {
12705       int saved = ctxp->explicit_constructor_p;
12706       tree invoke = build_method_invocation (wfl_to_string, NULL_TREE);
12707       tree ret;
12708       /* Temporary disable forbid the use of `this'. */
12709       ctxp->explicit_constructor_p = 0;
12710       ret = java_complete_tree (make_qualified_primary (node, invoke, 0));
12711       /* String concatenation arguments must be evaluated in order too. */
12712       ret = force_evaluation_order (ret);
12713       /* Restore it at its previous value */
12714       ctxp->explicit_constructor_p = saved;
12715       return ret;
12716     }
12717   return NULL_TREE;
12718 }
12719
12720 /* Build the internal representation of a string constant.  */
12721
12722 static tree
12723 patch_string_cst (node)
12724      tree node;
12725 {
12726   int location;
12727   if (! flag_emit_class_files)
12728     {
12729       push_obstacks (&permanent_obstack, &permanent_obstack);
12730       node = get_identifier (TREE_STRING_POINTER (node));
12731       location = alloc_name_constant (CONSTANT_String, node);
12732       node = build_ref_from_constant_pool (location);
12733       pop_obstacks ();
12734     }
12735   TREE_TYPE (node) = string_ptr_type_node;
12736   TREE_CONSTANT (node) = 1;
12737   return node;
12738 }
12739
12740 /* Build an incomplete unary operator expression. */
12741
12742 static tree
12743 build_unaryop (op_token, op_location, op1)
12744      int op_token, op_location;
12745      tree op1;
12746 {
12747   enum tree_code op;
12748   tree unaryop;
12749   switch (op_token)
12750     {
12751     case PLUS_TK: op = UNARY_PLUS_EXPR; break;
12752     case MINUS_TK: op = NEGATE_EXPR; break;
12753     case NEG_TK: op = TRUTH_NOT_EXPR; break;
12754     case NOT_TK: op = BIT_NOT_EXPR; break;
12755     default: fatal ("Unknown token `%d' for unary operator - build_unaryop",
12756                     op_token);
12757     }
12758
12759   unaryop = build1 (op, NULL_TREE, op1);
12760   TREE_SIDE_EFFECTS (unaryop) = 1;
12761   /* Store the location of the operator, for better error report. The
12762      string of the operator will be rebuild based on the OP value. */
12763   EXPR_WFL_LINECOL (unaryop) = op_location;
12764   return unaryop;
12765 }
12766
12767 /* Special case for the ++/-- operators, since they require an extra
12768    argument to build, which is set to NULL and patched
12769    later. IS_POST_P is 1 if the operator, 0 otherwise.  */
12770
12771 static tree
12772 build_incdec (op_token, op_location, op1, is_post_p)
12773      int op_token, op_location;
12774      tree op1;
12775      int is_post_p;
12776 {
12777   static enum tree_code lookup [2][2] = 
12778     {
12779       { PREDECREMENT_EXPR, PREINCREMENT_EXPR, },
12780       { POSTDECREMENT_EXPR, POSTINCREMENT_EXPR, },
12781     };
12782   tree node = build (lookup [is_post_p][(op_token - DECR_TK)], 
12783                      NULL_TREE, op1, NULL_TREE);
12784   TREE_SIDE_EFFECTS (node) = 1;
12785   /* Store the location of the operator, for better error report. The
12786      string of the operator will be rebuild based on the OP value. */
12787   EXPR_WFL_LINECOL (node) = op_location;
12788   return node;
12789 }     
12790
12791 /* Build an incomplete cast operator, based on the use of the
12792    CONVERT_EXPR. Note that TREE_TYPE of the constructed node is
12793    set. java_complete_tree is trained to walk a CONVERT_EXPR even
12794    though its type is already set.  */
12795
12796 static tree
12797 build_cast (location, type, exp)
12798      int location;
12799      tree type, exp;
12800 {
12801   tree node = build1 (CONVERT_EXPR, type, exp);
12802   EXPR_WFL_LINECOL (node) = location;
12803   return node;
12804 }
12805
12806 /* Build an incomplete class reference operator.  */
12807 static tree
12808 build_incomplete_class_ref (location, class_name)
12809     int location;
12810     tree class_name;
12811 {
12812   tree node = build1 (CLASS_LITERAL, NULL_TREE, class_name);
12813   EXPR_WFL_LINECOL (node) = location;
12814   return node;
12815 }
12816
12817 /* Complete an incomplete class reference operator.  */
12818 static tree
12819 patch_incomplete_class_ref (node)
12820     tree node;
12821 {
12822   tree type = TREE_OPERAND (node, 0);
12823   tree ref_type;
12824
12825   if (!(ref_type = resolve_type_during_patch (type)))
12826     return error_mark_node;
12827
12828   if (!flag_emit_class_files || JPRIMITIVE_TYPE_P (ref_type))
12829     return build_class_ref (ref_type);
12830
12831   /* If we're emitting class files and we have to deal with non
12832      primitive types, we invoke (and consider generating) the
12833      synthetic static method `class$'. */
12834   if (!TYPE_DOT_CLASS (current_class))
12835       build_dot_class_method (current_class);
12836   ref_type = 
12837     build_dot_class_method_invocation (DECL_NAME (TYPE_NAME (ref_type)));
12838   return java_complete_tree (ref_type);
12839 }
12840
12841 /* 15.14 Unary operators. We return error_mark_node in case of error,
12842    but preserve the type of NODE if the type is fixed.  */
12843
12844 static tree
12845 patch_unaryop (node, wfl_op)
12846      tree node;
12847      tree wfl_op;
12848 {
12849   tree op = TREE_OPERAND (node, 0);
12850   tree op_type = TREE_TYPE (op);
12851   tree prom_type = NULL_TREE, value, decl;
12852   int outer_field_flag = 0;
12853   int code = TREE_CODE (node);
12854   int error_found = 0;
12855
12856   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
12857
12858   switch (code)
12859     {
12860       /* 15.13.2 Postfix Increment Operator ++ */
12861     case POSTINCREMENT_EXPR:
12862       /* 15.13.3 Postfix Increment Operator -- */
12863     case POSTDECREMENT_EXPR:
12864       /* 15.14.1 Prefix Increment Operator ++ */
12865     case PREINCREMENT_EXPR:
12866       /* 15.14.2 Prefix Decrement Operator -- */
12867     case PREDECREMENT_EXPR:
12868       op = decl = strip_out_static_field_access_decl (op);
12869       outer_field_flag = outer_field_expanded_access_p (op, NULL, NULL, NULL);
12870       /* We might be trying to change an outer field accessed using
12871          access method. */
12872       if (outer_field_flag)
12873         {
12874           /* Retrieve the decl of the field we're trying to access. We
12875              do that by first retrieving the function we would call to
12876              access the field. It has been already verified that this
12877              field isn't final */
12878           if (flag_emit_class_files)
12879             decl = TREE_OPERAND (op, 0);
12880           else
12881             decl = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (op, 0), 0), 0);
12882           decl = DECL_FUNCTION_ACCESS_DECL (decl);
12883         }
12884       /* We really should have a JAVA_ARRAY_EXPR to avoid this */
12885       else if (!JDECL_P (decl) 
12886           && TREE_CODE (decl) != COMPONENT_REF
12887           && !(flag_emit_class_files && TREE_CODE (decl) == ARRAY_REF)
12888           && TREE_CODE (decl) != INDIRECT_REF
12889           && !(TREE_CODE (decl) == COMPOUND_EXPR
12890                && TREE_OPERAND (decl, 1)
12891                && (TREE_CODE (TREE_OPERAND (decl, 1)) == INDIRECT_REF)))
12892         {
12893           tree lvalue;
12894           /* Before screaming, check that we're not in fact trying to
12895              increment a optimized static final access, in which case
12896              we issue an different error message. */
12897           if (!(TREE_CODE (wfl_op) == EXPR_WITH_FILE_LOCATION
12898                 && resolve_expression_name (wfl_op, &lvalue)
12899                 && check_final_assignment (lvalue, wfl_op)))
12900             parse_error_context (wfl_operator, "Invalid argument to `%s'",
12901                                  operator_string (node));
12902           TREE_TYPE (node) = error_mark_node;
12903           error_found = 1;
12904         }
12905       
12906       if (check_final_assignment (op, wfl_op))
12907         error_found = 1;
12908
12909       /* From now on, we know that op if a variable and that it has a
12910          valid wfl. We use wfl_op to locate errors related to the
12911          ++/-- operand. */
12912       else if (!JNUMERIC_TYPE_P (op_type))
12913         {
12914           parse_error_context
12915             (wfl_op, "Invalid argument type `%s' to `%s'",
12916              lang_printable_name (op_type, 0), operator_string (node));
12917           TREE_TYPE (node) = error_mark_node;
12918           error_found = 1;
12919         }
12920       else
12921         {
12922           /* Before the addition, binary numeric promotion is performed on
12923              both operands, if really necessary */
12924           if (JINTEGRAL_TYPE_P (op_type))
12925             {
12926               value = build_int_2 (1, 0);
12927               TREE_TYPE (value) = TREE_TYPE (node) = op_type;
12928             }
12929           else
12930             {
12931               value = build_int_2 (1, 0);
12932               TREE_TYPE (node) = 
12933                 binary_numeric_promotion (op_type, 
12934                                           TREE_TYPE (value), &op, &value);
12935             }
12936
12937           /* We remember we might be accessing an outer field */
12938           if (outer_field_flag)
12939             {
12940               /* We re-generate an access to the field */
12941               value = build (PLUS_EXPR, TREE_TYPE (op), 
12942                              build_outer_field_access (wfl_op, decl), value);
12943                                                     
12944               /* And we patch the original access$() into a write 
12945                  with plus_op as a rhs */
12946               return outer_field_access_fix (node, op, value);
12947             }
12948
12949           /* And write back into the node. */
12950           TREE_OPERAND (node, 0) = op;
12951           TREE_OPERAND (node, 1) = value;
12952           /* Convert the overall back into its original type, if
12953              necessary, and return */
12954           if (JINTEGRAL_TYPE_P (op_type))
12955             return fold (node);
12956           else
12957             return fold (convert (op_type, node));
12958         }
12959       break;
12960
12961       /* 15.14.3 Unary Plus Operator + */
12962     case UNARY_PLUS_EXPR:
12963       /* 15.14.4 Unary Minus Operator - */
12964     case NEGATE_EXPR:
12965       if (!JNUMERIC_TYPE_P (op_type))
12966         {
12967           ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op_type);
12968           TREE_TYPE (node) = error_mark_node;
12969           error_found = 1;
12970         }
12971       /* Unary numeric promotion is performed on operand */
12972       else
12973         {
12974           op = do_unary_numeric_promotion (op);
12975           prom_type = TREE_TYPE (op);
12976           if (code == UNARY_PLUS_EXPR)
12977             return fold (op);
12978         }
12979       break;
12980
12981       /* 15.14.5 Bitwise Complement Operator ~ */
12982     case BIT_NOT_EXPR:
12983       if (!JINTEGRAL_TYPE_P (op_type))
12984         {
12985           ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op_type);
12986           TREE_TYPE (node) = error_mark_node;
12987           error_found = 1;
12988         }
12989       else
12990         {
12991           op = do_unary_numeric_promotion (op);
12992           prom_type = TREE_TYPE (op);
12993         }
12994       break;
12995
12996       /* 15.14.6 Logical Complement Operator ! */
12997     case TRUTH_NOT_EXPR:
12998       if (TREE_CODE (op_type) != BOOLEAN_TYPE)
12999         {
13000           ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op_type);
13001           /* But the type is known. We will report an error if further
13002              attempt of a assignment is made with this rhs */
13003           TREE_TYPE (node) = boolean_type_node;
13004           error_found = 1;
13005         }
13006       else
13007         prom_type = boolean_type_node;
13008       break;
13009
13010       /* 15.15 Cast Expression */
13011     case CONVERT_EXPR:
13012       value = patch_cast (node, wfl_operator);
13013       if (value == error_mark_node)
13014         {
13015           /* If this cast is part of an assignment, we tell the code
13016              that deals with it not to complain about a mismatch,
13017              because things have been cast, anyways */
13018           TREE_TYPE (node) = error_mark_node;
13019           error_found = 1;
13020         }
13021       else
13022         {
13023           value = fold (value);
13024           TREE_SIDE_EFFECTS (value) = TREE_SIDE_EFFECTS (op);
13025           return value;
13026         }
13027       break;
13028     }
13029   
13030   if (error_found)
13031     return error_mark_node;
13032
13033   /* There are cases where node has been replaced by something else
13034      and we don't end up returning here: UNARY_PLUS_EXPR,
13035      CONVERT_EXPR, {POST,PRE}{INCR,DECR}EMENT_EXPR. */
13036   TREE_OPERAND (node, 0) = fold (op);
13037   TREE_TYPE (node) = prom_type;
13038   TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op);
13039   return fold (node);
13040 }
13041
13042 /* Generic type resolution that sometimes takes place during node
13043    patching. Returned the resolved type or generate an error
13044    message. Return the resolved type or NULL_TREE.  */
13045
13046 static tree
13047 resolve_type_during_patch (type)
13048      tree type;
13049 {
13050   if (unresolved_type_p (type, NULL))
13051     {
13052       tree type_decl = resolve_no_layout (EXPR_WFL_NODE (type), NULL_TREE);
13053       if (!type_decl)
13054         {
13055           parse_error_context (type, 
13056                                "Class `%s' not found in type declaration",
13057                                IDENTIFIER_POINTER (EXPR_WFL_NODE (type)));
13058           return NULL_TREE;
13059         }
13060       else
13061         {
13062           CLASS_LOADED_P (TREE_TYPE (type_decl)) = 1;
13063           return TREE_TYPE (type_decl);
13064         }
13065     }
13066   return type;
13067 }
13068 /* 5.5 Casting Conversion. error_mark_node is returned if an error is
13069    found. Otherwise NODE or something meant to replace it is returned.  */
13070
13071 static tree
13072 patch_cast (node, wfl_operator)
13073      tree node;
13074      tree wfl_operator;
13075 {
13076   tree op = TREE_OPERAND (node, 0);
13077   tree op_type = TREE_TYPE (op);
13078   tree cast_type = TREE_TYPE (node);
13079   char *t1;
13080
13081   /* First resolve OP_TYPE if unresolved */
13082   if (!(cast_type = resolve_type_during_patch (cast_type)))
13083     return error_mark_node;
13084
13085   /* Check on cast that are proven correct at compile time */
13086   if (JNUMERIC_TYPE_P (cast_type) && JNUMERIC_TYPE_P (op_type))
13087     {
13088       /* Same type */
13089       if (cast_type == op_type)
13090         return node;
13091
13092       /* float and double type are converted to the original type main
13093          variant and then to the target type. */
13094       if (JFLOAT_TYPE_P (op_type) && TREE_CODE (cast_type) == CHAR_TYPE)
13095         op = convert (integer_type_node, op);
13096
13097       /* Try widening/narowwing convertion. Potentially, things need
13098          to be worked out in gcc so we implement the extreme cases
13099          correctly. fold_convert() needs to be fixed. */
13100       return convert (cast_type, op);
13101     }
13102
13103   /* It's also valid to cast a boolean into a boolean */
13104   if (op_type == boolean_type_node && cast_type == boolean_type_node)
13105     return node;
13106
13107   /* null can be casted to references */
13108   if (op == null_pointer_node && JREFERENCE_TYPE_P (cast_type))
13109     return build_null_of_type (cast_type);
13110
13111   /* The remaining legal casts involve conversion between reference
13112      types. Check for their compile time correctness. */
13113   if (JREFERENCE_TYPE_P (op_type) && JREFERENCE_TYPE_P (cast_type) 
13114       && valid_ref_assignconv_cast_p (op_type, cast_type, 1))
13115     {
13116       TREE_TYPE (node) = promote_type (cast_type);
13117       /* Now, the case can be determined correct at compile time if
13118          OP_TYPE can be converted into CAST_TYPE by assignment
13119          conversion (5.2) */
13120
13121       if (valid_ref_assignconv_cast_p (op_type, cast_type, 0))
13122         {
13123           TREE_SET_CODE (node, NOP_EXPR);
13124           return node;
13125         }
13126
13127       if (flag_emit_class_files)
13128         {
13129           TREE_SET_CODE (node, CONVERT_EXPR);
13130           return node;
13131         }
13132
13133       /* The cast requires a run-time check */
13134       return build (CALL_EXPR, promote_type (cast_type),
13135                     build_address_of (soft_checkcast_node),
13136                     tree_cons (NULL_TREE, build_class_ref (cast_type),
13137                                build_tree_list (NULL_TREE, op)),
13138                     NULL_TREE);
13139     }
13140
13141   /* Any other casts are proven incorrect at compile time */
13142   t1 = xstrdup (lang_printable_name (op_type, 0));
13143   parse_error_context (wfl_operator, "Invalid cast from `%s' to `%s'",
13144                        t1, lang_printable_name (cast_type, 0));
13145   free (t1);
13146   return error_mark_node;
13147 }
13148
13149 /* Build a null constant and give it the type TYPE.  */
13150
13151 static tree
13152 build_null_of_type (type)
13153      tree type;
13154 {
13155   tree node = build_int_2 (0, 0);
13156   TREE_TYPE (node) = promote_type (type);
13157   return node;
13158 }
13159
13160 /* Build an ARRAY_REF incomplete tree node. Note that operand 1 isn't
13161    a list of indices. */
13162 static tree
13163 build_array_ref (location, array, index)
13164      int location;
13165      tree array, index;
13166 {
13167   tree node = build (ARRAY_REF, NULL_TREE, array, index);
13168   EXPR_WFL_LINECOL (node) = location;
13169   return node;
13170 }
13171
13172 /* 15.12 Array Access Expression */
13173
13174 static tree
13175 patch_array_ref (node)
13176      tree node;
13177 {
13178   tree array = TREE_OPERAND (node, 0);
13179   tree array_type  = TREE_TYPE (array);
13180   tree index = TREE_OPERAND (node, 1);
13181   tree index_type = TREE_TYPE (index);
13182   int error_found = 0;
13183
13184   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13185
13186   if (TREE_CODE (array_type) == POINTER_TYPE)
13187     array_type = TREE_TYPE (array_type);
13188
13189   /* The array reference must be an array */
13190   if (!TYPE_ARRAY_P (array_type))
13191     {
13192       parse_error_context 
13193         (wfl_operator,
13194          "`[]' can only be applied to arrays. It can't be applied to `%s'",
13195          lang_printable_name (array_type, 0));
13196       TREE_TYPE (node) = error_mark_node;
13197       error_found = 1;
13198     }
13199
13200   /* The array index undergoes unary numeric promotion. The promoted
13201      type must be int */
13202   index = do_unary_numeric_promotion (index);
13203   if (TREE_TYPE (index) != int_type_node)
13204     {
13205       if (valid_cast_to_p (index_type, int_type_node))
13206         parse_error_context (wfl_operator,
13207    "Incompatible type for `[]'. Explicit cast needed to convert `%s' to `int'",
13208                              lang_printable_name (index_type, 0));
13209       else
13210         parse_error_context (wfl_operator,
13211           "Incompatible type for `[]'. Can't convert `%s' to `int'",
13212                              lang_printable_name (index_type, 0));
13213       TREE_TYPE (node) = error_mark_node;
13214       error_found = 1;
13215     }
13216
13217   if (error_found)
13218     return error_mark_node;
13219
13220   array_type = TYPE_ARRAY_ELEMENT (array_type);
13221
13222   if (flag_emit_class_files || flag_emit_xref)
13223     {
13224       TREE_OPERAND (node, 0) = array;
13225       TREE_OPERAND (node, 1) = index;
13226     }
13227   else
13228     {
13229       /* The save_expr is for correct evaluation order.  It would be cleaner
13230          to use force_evaluation_order (see comment there), but that is
13231          difficult when we also have to deal with bounds checking. */
13232       if (TREE_SIDE_EFFECTS (index))
13233         array = save_expr (array);
13234       node = build_java_arrayaccess (array, array_type, index);
13235       if (TREE_SIDE_EFFECTS (index))
13236         node = build (COMPOUND_EXPR, array_type, array, node);
13237     }
13238   TREE_TYPE (node) = array_type;
13239   return node;
13240 }
13241
13242 /* 15.9 Array Creation Expressions */
13243
13244 static tree
13245 build_newarray_node (type, dims, extra_dims)
13246      tree type;
13247      tree dims;
13248      int extra_dims;
13249 {
13250   tree node =
13251     build (NEW_ARRAY_EXPR, NULL_TREE, type, nreverse (dims), 
13252            build_int_2 (extra_dims, 0));
13253   return node;
13254 }
13255
13256 static tree
13257 patch_newarray (node)
13258      tree node;
13259 {
13260   tree type = TREE_OPERAND (node, 0);
13261   tree dims = TREE_OPERAND (node, 1);
13262   tree cdim, array_type;
13263   int error_found = 0;
13264   int ndims = 0;
13265   int xdims = TREE_INT_CST_LOW (TREE_OPERAND (node, 2));
13266
13267   /* Dimension types are verified. It's better for the types to be
13268      verified in order. */
13269   for (cdim = dims, ndims = 0; cdim; cdim = TREE_CHAIN (cdim), ndims++ )
13270     {
13271       int dim_error = 0;
13272       tree dim = TREE_VALUE (cdim);
13273
13274       /* Dim might have been saved during its evaluation */
13275       dim = (TREE_CODE (dim) == SAVE_EXPR ? dim = TREE_OPERAND (dim, 0) : dim);
13276
13277       /* The type of each specified dimension must be an integral type. */
13278       if (!JINTEGRAL_TYPE_P (TREE_TYPE (dim)))
13279         dim_error = 1;
13280
13281       /* Each expression undergoes an unary numeric promotion (5.6.1) and the
13282          promoted type must be int. */
13283       else
13284         {
13285           dim = do_unary_numeric_promotion (dim);
13286           if (TREE_TYPE (dim) != int_type_node)
13287             dim_error = 1;
13288         }
13289
13290       /* Report errors on types here */
13291       if (dim_error)
13292         {
13293           parse_error_context 
13294             (TREE_PURPOSE (cdim), 
13295              "Incompatible type for dimension in array creation expression. %s convert `%s' to `int'", 
13296              (valid_cast_to_p (TREE_TYPE (dim), int_type_node) ?
13297               "Explicit cast needed to" : "Can't"),
13298              lang_printable_name (TREE_TYPE (dim), 0));
13299           error_found = 1;
13300         }
13301
13302       TREE_PURPOSE (cdim) = NULL_TREE;
13303     }
13304
13305   /* Resolve array base type if unresolved */
13306   if (!(type = resolve_type_during_patch (type)))
13307     error_found = 1;
13308
13309   if (error_found)
13310     {
13311       /* We don't want further evaluation of this bogus array creation
13312          operation */
13313       TREE_TYPE (node) = error_mark_node;
13314       return error_mark_node;
13315     }
13316
13317   /* Set array_type to the actual (promoted) array type of the result. */
13318   if (TREE_CODE (type) == RECORD_TYPE)
13319     type = build_pointer_type (type);
13320   while (--xdims >= 0)
13321     {
13322       type = promote_type (build_java_array_type (type, -1));
13323     }
13324   dims = nreverse (dims);
13325   array_type = type;
13326   for (cdim = dims; cdim; cdim = TREE_CHAIN (cdim))
13327     {
13328       type = array_type;
13329       array_type
13330         = build_java_array_type (type,
13331                                  TREE_CODE (cdim) == INTEGER_CST
13332                                  ? (HOST_WIDE_INT) TREE_INT_CST_LOW (cdim)
13333                                  : -1);
13334       array_type = promote_type (array_type);
13335     }
13336   dims = nreverse (dims);
13337
13338   /* The node is transformed into a function call. Things are done
13339      differently according to the number of dimensions. If the number
13340      of dimension is equal to 1, then the nature of the base type
13341      (primitive or not) matters. */
13342   if (ndims == 1)
13343     return build_new_array (type, TREE_VALUE (dims));
13344   
13345   /* Can't reuse what's already written in expr.c because it uses the
13346      JVM stack representation. Provide a build_multianewarray. FIXME */
13347   return build (CALL_EXPR, array_type,
13348                 build_address_of (soft_multianewarray_node),
13349                 tree_cons (NULL_TREE, build_class_ref (TREE_TYPE (array_type)),
13350                            tree_cons (NULL_TREE, 
13351                                       build_int_2 (ndims, 0), dims )),
13352                 NULL_TREE);
13353 }
13354
13355 /* 10.6 Array initializer.  */
13356
13357 /* Build a wfl for array element that don't have one, so we can
13358    pin-point errors.  */
13359
13360 static tree
13361 maybe_build_array_element_wfl (node)
13362      tree node;
13363 {
13364   if (TREE_CODE (node) != EXPR_WITH_FILE_LOCATION)
13365     return build_expr_wfl (NULL_TREE, ctxp->filename,
13366                            ctxp->elc.line, ctxp->elc.prev_col);
13367   else
13368     return NULL_TREE;
13369 }
13370
13371 /* Build a NEW_ARRAY_INIT that features a CONSTRUCTOR node. This makes
13372    identification of initialized arrays easier to detect during walk
13373    and expansion.  */
13374
13375 static tree
13376 build_new_array_init (location, values)
13377      int location;
13378      tree values;
13379 {
13380   tree constructor = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, values);
13381   tree to_return = build1 (NEW_ARRAY_INIT, NULL_TREE, constructor);
13382   EXPR_WFL_LINECOL (to_return) = location;
13383   return to_return;
13384 }
13385
13386 /* Expand a NEW_ARRAY_INIT node. Return error_mark_node if an error
13387    occurred.  Otherwise return NODE after having set its type
13388    appropriately.  */
13389
13390 static tree
13391 patch_new_array_init (type, node)
13392      tree type, node;
13393 {
13394   int error_seen = 0;
13395   tree current, element_type;
13396   HOST_WIDE_INT length;
13397   int all_constant = 1;
13398   tree init = TREE_OPERAND (node, 0);
13399
13400   if (TREE_CODE (type) != POINTER_TYPE || ! TYPE_ARRAY_P (TREE_TYPE (type)))
13401     {
13402       parse_error_context (node,
13403                            "Invalid array initializer for non-array type `%s'",
13404                            lang_printable_name (type, 1));
13405       return error_mark_node;
13406     }
13407   type = TREE_TYPE (type);
13408   element_type = TYPE_ARRAY_ELEMENT (type);
13409
13410   CONSTRUCTOR_ELTS (init) = nreverse (CONSTRUCTOR_ELTS (init));
13411
13412   for (length = 0, current = CONSTRUCTOR_ELTS (init);
13413        current;  length++, current = TREE_CHAIN (current))
13414     {
13415       tree elt = TREE_VALUE (current);
13416       if (elt == NULL_TREE || TREE_CODE (elt) != NEW_ARRAY_INIT)
13417         {
13418           error_seen |= array_constructor_check_entry (element_type, current);
13419           elt = TREE_VALUE (current);
13420           /* When compiling to native code, STRING_CST is converted to
13421              INDIRECT_REF, but still with a TREE_CONSTANT flag. */
13422           if (! TREE_CONSTANT (elt) || TREE_CODE (elt) == INDIRECT_REF)
13423             all_constant = 0;
13424         }
13425       else
13426         {
13427           TREE_VALUE (current) = patch_new_array_init (element_type, elt);
13428           TREE_PURPOSE (current) = NULL_TREE;
13429           all_constant = 0;
13430         }
13431       if (elt && TREE_VALUE (elt) == error_mark_node)
13432         error_seen = 1;
13433     }
13434
13435   if (error_seen)
13436     return error_mark_node;
13437
13438   /* Create a new type. We can't reuse the one we have here by
13439      patching its dimension because it originally is of dimension -1
13440      hence reused by gcc. This would prevent triangular arrays. */
13441   type = build_java_array_type (element_type, length);
13442   TREE_TYPE (init) = TREE_TYPE (TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (type))));
13443   TREE_TYPE (node) = promote_type (type);
13444   TREE_CONSTANT (init) = all_constant;
13445   TREE_CONSTANT (node) = all_constant;
13446   return node;
13447 }
13448
13449 /* Verify that one entry of the initializer element list can be
13450    assigned to the array base type. Report 1 if an error occurred, 0
13451    otherwise.  */
13452
13453 static int
13454 array_constructor_check_entry (type, entry)
13455      tree type, entry;
13456 {
13457   char *array_type_string = NULL;       /* For error reports */
13458   tree value, type_value, new_value, wfl_value, patched;
13459   int error_seen = 0;
13460
13461   new_value = NULL_TREE;
13462   wfl_value = TREE_VALUE (entry);
13463
13464   push_obstacks (&permanent_obstack, &permanent_obstack);
13465   value = java_complete_tree (TREE_VALUE (entry));
13466   /* patch_string return error_mark_node if arg is error_mark_node */
13467   if ((patched = patch_string (value)))
13468     value = patched;
13469   if (value == error_mark_node)
13470     return 1;
13471   
13472   type_value = TREE_TYPE (value);
13473   
13474   /* At anytime, try_builtin_assignconv can report a warning on
13475      constant overflow during narrowing. */
13476   SET_WFL_OPERATOR (wfl_operator, TREE_PURPOSE (entry), wfl_value);
13477   new_value = try_builtin_assignconv (wfl_operator, type, value);
13478   if (!new_value && (new_value = try_reference_assignconv (type, value)))
13479     type_value = promote_type (type);
13480
13481   pop_obstacks ();
13482   /* Check and report errors */
13483   if (!new_value)
13484     {
13485       const char *msg = (!valid_cast_to_p (type_value, type) ?
13486                    "Can't" : "Explicit cast needed to");
13487       if (!array_type_string)
13488         array_type_string = xstrdup (lang_printable_name (type, 1));
13489       parse_error_context 
13490         (wfl_operator, "Incompatible type for array. %s convert `%s' to `%s'",
13491          msg, lang_printable_name (type_value, 1), array_type_string);
13492       error_seen = 1;
13493     }
13494   
13495   if (new_value)
13496     {
13497       new_value = maybe_build_primttype_type_ref (new_value, wfl_operator);
13498       TREE_VALUE (entry) = new_value;
13499     }
13500
13501   if (array_type_string)
13502     free (array_type_string);
13503
13504   TREE_PURPOSE (entry) = NULL_TREE;
13505   return error_seen;
13506 }
13507
13508 static tree
13509 build_this (location)
13510      int location;
13511 {
13512   tree node = build_wfl_node (this_identifier_node);
13513   TREE_SET_CODE (node, THIS_EXPR);
13514   EXPR_WFL_LINECOL (node) = location;
13515   return node;
13516 }
13517
13518 /* 14.15 The return statement. It builds a modify expression that
13519    assigns the returned value to the RESULT_DECL that hold the value
13520    to be returned. */
13521
13522 static tree
13523 build_return (location, op)
13524      int location;
13525      tree op;
13526 {
13527   tree node = build1 (RETURN_EXPR, NULL_TREE, op);
13528   EXPR_WFL_LINECOL (node) = location;
13529   node = build_debugable_stmt (location, node);
13530   return node;
13531 }
13532
13533 static tree
13534 patch_return (node)
13535      tree node;
13536 {
13537   tree return_exp = TREE_OPERAND (node, 0);
13538   tree meth = current_function_decl;
13539   tree mtype = TREE_TYPE (TREE_TYPE (current_function_decl));
13540   int error_found = 0;
13541
13542   TREE_TYPE (node) = error_mark_node;
13543   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13544
13545   /* It's invalid to have a return value within a function that is
13546      declared with the keyword void or that is a constructor */
13547   if (return_exp && (mtype == void_type_node || DECL_CONSTRUCTOR_P (meth)))
13548     error_found = 1;
13549
13550   /* It's invalid to use a return statement in a static block */
13551   if (DECL_CLINIT_P (current_function_decl))
13552     error_found = 1;
13553
13554   /* It's invalid to have a no return value within a function that
13555      isn't declared with the keyword `void' */
13556   if (!return_exp && (mtype != void_type_node && !DECL_CONSTRUCTOR_P (meth)))
13557     error_found = 2;
13558   
13559   if (in_instance_initializer)
13560     error_found = 1;
13561
13562   if (error_found)
13563     {
13564       if (in_instance_initializer)
13565         parse_error_context (wfl_operator,
13566                              "`return' inside instance initializer");
13567         
13568       else if (DECL_CLINIT_P (current_function_decl))
13569         parse_error_context (wfl_operator,
13570                              "`return' inside static initializer");
13571
13572       else if (!DECL_CONSTRUCTOR_P (meth))
13573         {
13574           char *t = xstrdup (lang_printable_name (mtype, 0));
13575           parse_error_context (wfl_operator, 
13576                                "`return' with%s value from `%s %s'",
13577                                (error_found == 1 ? "" : "out"), 
13578                                t, lang_printable_name (meth, 0));
13579           free (t);
13580         }
13581       else
13582         parse_error_context (wfl_operator, 
13583                              "`return' with value from constructor `%s'",
13584                              lang_printable_name (meth, 0));
13585       return error_mark_node;
13586     }
13587
13588   /* If we have a return_exp, build a modify expression and expand
13589      it. Note: at that point, the assignment is declared valid, but we
13590      may want to carry some more hacks */
13591   if (return_exp)
13592     {
13593       tree exp = java_complete_tree (return_exp);
13594       tree modify, patched;
13595
13596       /* If the function returned value and EXP are booleans, EXP has
13597       to be converted into the type of DECL_RESULT, which is integer
13598       (see complete_start_java_method) */
13599       if (TREE_TYPE (exp) == boolean_type_node &&
13600           TREE_TYPE (TREE_TYPE (meth)) == boolean_type_node)
13601         exp = convert_to_integer (TREE_TYPE (DECL_RESULT (meth)), exp);
13602
13603       /* `null' can be assigned to a function returning a reference */
13604       if (JREFERENCE_TYPE_P (TREE_TYPE (TREE_TYPE (meth))) &&
13605           exp == null_pointer_node)
13606         exp = build_null_of_type (TREE_TYPE (TREE_TYPE (meth)));
13607
13608       if ((patched = patch_string (exp)))
13609         exp = patched;
13610       
13611       modify = build (MODIFY_EXPR, NULL_TREE, DECL_RESULT (meth), exp);
13612       EXPR_WFL_LINECOL (modify) = EXPR_WFL_LINECOL (node);
13613       modify = java_complete_tree (modify);
13614
13615       if (modify != error_mark_node)
13616         {
13617           TREE_SIDE_EFFECTS (modify) = 1;
13618           TREE_OPERAND (node, 0) = modify;
13619         }
13620       else
13621         return error_mark_node;
13622     }
13623   TREE_TYPE (node) = void_type_node;
13624   TREE_SIDE_EFFECTS (node) = 1;
13625   return node;
13626 }
13627
13628 /* 14.8 The if Statement */
13629
13630 static tree
13631 build_if_else_statement (location, expression, if_body, else_body)
13632      int location;
13633      tree expression, if_body, else_body;
13634 {
13635   tree node;
13636   if (!else_body)
13637     else_body = empty_stmt_node;
13638   node = build (COND_EXPR, NULL_TREE, expression, if_body, else_body);
13639   EXPR_WFL_LINECOL (node) = location;
13640   node = build_debugable_stmt (location, node);
13641   return node;
13642 }
13643
13644 static tree
13645 patch_if_else_statement (node)
13646      tree node;
13647 {
13648   tree expression = TREE_OPERAND (node, 0);
13649
13650   TREE_TYPE (node) = error_mark_node;
13651   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13652
13653   /* The type of expression must be boolean */
13654   if (TREE_TYPE (expression) != boolean_type_node
13655       && TREE_TYPE (expression) != promoted_boolean_type_node)
13656     {
13657       parse_error_context 
13658         (wfl_operator, 
13659          "Incompatible type for `if'. Can't convert `%s' to `boolean'", 
13660          lang_printable_name (TREE_TYPE (expression), 0));
13661       return error_mark_node;
13662     }
13663   
13664   TREE_TYPE (node) = void_type_node;
13665   TREE_SIDE_EFFECTS (node) = 1;
13666   CAN_COMPLETE_NORMALLY (node)
13667     = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1))
13668     | CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 2));
13669   return node;
13670 }
13671
13672 /* 14.6 Labeled Statements */
13673
13674 /* Action taken when a lableled statement is parsed. a new
13675    LABELED_BLOCK_EXPR is created. No statement is attached to the
13676    label, yet.  LABEL can be NULL_TREE for artificially-generated blocks. */
13677
13678 static tree
13679 build_labeled_block (location, label)
13680      int location;
13681      tree label;
13682 {
13683   tree label_name ;
13684   tree label_decl, node;
13685   if (label == NULL_TREE || label == continue_identifier_node)
13686     label_name = label;
13687   else
13688     {
13689       label_name = merge_qualified_name (label_id, label);
13690       /* Issue an error if we try to reuse a label that was previously
13691          declared */
13692       if (IDENTIFIER_LOCAL_VALUE (label_name))
13693         {
13694           EXPR_WFL_LINECOL (wfl_operator) = location;
13695           parse_error_context (wfl_operator,
13696             "Declaration of `%s' shadows a previous label declaration",
13697                                IDENTIFIER_POINTER (label));
13698           EXPR_WFL_LINECOL (wfl_operator) = 
13699             EXPR_WFL_LINECOL (IDENTIFIER_LOCAL_VALUE (label_name));
13700           parse_error_context (wfl_operator,
13701             "This is the location of the previous declaration of label `%s'",
13702                                IDENTIFIER_POINTER (label));
13703           java_error_count--;
13704         }
13705     }
13706
13707   label_decl = create_label_decl (label_name);
13708   node = build (LABELED_BLOCK_EXPR, NULL_TREE, label_decl, NULL_TREE);
13709   EXPR_WFL_LINECOL (node) = location;
13710   TREE_SIDE_EFFECTS (node) = 1;
13711   return node;
13712 }
13713
13714 /* A labeled statement LBE is attached a statement.  */
13715
13716 static tree
13717 finish_labeled_statement (lbe, statement)
13718      tree lbe;                  /* Labeled block expr */
13719      tree statement;
13720 {
13721   /* In anyways, tie the loop to its statement */
13722   LABELED_BLOCK_BODY (lbe) = statement;
13723   pop_labeled_block ();
13724   POP_LABELED_BLOCK ();
13725   return lbe;
13726 }
13727
13728 /* 14.10, 14.11, 14.12 Loop Statements */
13729
13730 /* Create an empty LOOP_EXPR and make it the last in the nested loop
13731    list. */
13732
13733 static tree
13734 build_new_loop (loop_body)
13735      tree loop_body;
13736 {
13737   tree loop =  build (LOOP_EXPR, NULL_TREE, loop_body);
13738   TREE_SIDE_EFFECTS (loop) = 1;
13739   PUSH_LOOP (loop);
13740   return loop;
13741 }
13742
13743 /* Create a loop body according to the following structure:
13744      COMPOUND_EXPR
13745        COMPOUND_EXPR            (loop main body)
13746          EXIT_EXPR              (this order is for while/for loops.
13747          LABELED_BLOCK_EXPR      the order is reversed for do loops)
13748            LABEL_DECL           (a continue occuring here branches at the 
13749            BODY                  end of this labeled block)
13750        INCREMENT                (if any)
13751
13752   REVERSED, if non zero, tells that the loop condition expr comes
13753   after the body, like in the do-while loop.
13754
13755   To obtain a loop, the loop body structure described above is
13756   encapsulated within a LOOP_EXPR surrounded by a LABELED_BLOCK_EXPR:
13757
13758    LABELED_BLOCK_EXPR
13759      LABEL_DECL                   (use this label to exit the loop)
13760      LOOP_EXPR
13761        <structure described above> */
13762
13763 static tree
13764 build_loop_body (location, condition, reversed)
13765      int location;
13766      tree condition;
13767      int reversed;
13768 {
13769   tree first, second, body;
13770
13771   condition = build (EXIT_EXPR, NULL_TREE, condition); /* Force walk */
13772   EXPR_WFL_LINECOL (condition) = location; /* For accurate error report */
13773   condition = build_debugable_stmt (location, condition);
13774   TREE_SIDE_EFFECTS (condition) = 1;
13775
13776   body = build_labeled_block (0, continue_identifier_node);
13777   first = (reversed ? body : condition);
13778   second = (reversed ? condition : body);
13779   return 
13780     build (COMPOUND_EXPR, NULL_TREE, 
13781            build (COMPOUND_EXPR, NULL_TREE, first, second), empty_stmt_node);
13782 }
13783
13784 /* Install CONDITION (if any) and loop BODY (using REVERSED to tell
13785    their order) on the current loop. Unlink the current loop from the
13786    loop list.  */
13787
13788 static tree
13789 finish_loop_body (location, condition, body, reversed)
13790      int location;
13791      tree condition, body;
13792      int reversed;
13793 {
13794   tree to_return = ctxp->current_loop;
13795   tree loop_body = LOOP_EXPR_BODY (to_return);
13796   if (condition)
13797     {
13798       tree cnode = LOOP_EXPR_BODY_CONDITION_EXPR (loop_body, reversed);
13799       /* We wrapped the EXIT_EXPR around a WFL so we can debug it.
13800          The real EXIT_EXPR is one operand further. */
13801       EXPR_WFL_LINECOL (cnode) = location;
13802       /* This one is for accurate error reports */
13803       EXPR_WFL_LINECOL (TREE_OPERAND (cnode, 0)) = location;
13804       TREE_OPERAND (TREE_OPERAND (cnode, 0), 0) = condition;
13805     }
13806   LOOP_EXPR_BODY_BODY_EXPR (loop_body, reversed) = body;
13807   POP_LOOP ();
13808   return to_return;
13809 }
13810
13811 /* Tailored version of finish_loop_body for FOR loops, when FOR
13812    loops feature the condition part */
13813
13814 static tree
13815 finish_for_loop (location, condition, update, body)
13816     int location;
13817     tree condition, update, body;
13818 {
13819   /* Put the condition and the loop body in place */
13820   tree loop = finish_loop_body (location, condition, body, 0);
13821   /* LOOP is the current loop which has been now popped of the loop
13822      stack. Install the update block */
13823   LOOP_EXPR_BODY_UPDATE_BLOCK (LOOP_EXPR_BODY (loop)) = update;
13824   return loop;
13825 }
13826
13827 /* Try to find the loop a block might be related to. This comprises
13828    the case where the LOOP_EXPR is found as the second operand of a
13829    COMPOUND_EXPR, because the loop happens to have an initialization
13830    part, then expressed as the first operand of the COMPOUND_EXPR. If
13831    the search finds something, 1 is returned. Otherwise, 0 is
13832    returned. The search is assumed to start from a
13833    LABELED_BLOCK_EXPR's block.  */
13834
13835 static tree
13836 search_loop (statement)
13837     tree statement;
13838 {
13839   if (TREE_CODE (statement) == LOOP_EXPR)
13840     return statement;
13841
13842   if (TREE_CODE (statement) == BLOCK)
13843     statement = BLOCK_SUBBLOCKS (statement);
13844   else
13845     return NULL_TREE;
13846
13847   if (statement && TREE_CODE (statement) == COMPOUND_EXPR)
13848     while (statement && TREE_CODE (statement) == COMPOUND_EXPR)
13849       statement = TREE_OPERAND (statement, 1);
13850
13851   return (TREE_CODE (statement) == LOOP_EXPR
13852           && FOR_LOOP_P (statement) ? statement : NULL_TREE);
13853 }
13854
13855 /* Return 1 if LOOP can be found in the labeled block BLOCK. 0 is
13856    returned otherwise.  */
13857
13858 static int
13859 labeled_block_contains_loop_p (block, loop)
13860     tree block, loop;
13861 {
13862   if (!block)
13863     return 0;
13864
13865   if (LABELED_BLOCK_BODY (block) == loop)
13866     return 1;
13867
13868   if (FOR_LOOP_P (loop) && search_loop (LABELED_BLOCK_BODY (block)) == loop)
13869     return 1;
13870
13871   return 0;
13872 }
13873
13874 /* If the loop isn't surrounded by a labeled statement, create one and
13875    insert LOOP as its body.  */
13876
13877 static tree
13878 patch_loop_statement (loop)
13879      tree loop;
13880 {
13881   tree loop_label;
13882
13883   TREE_TYPE (loop) = void_type_node;
13884   if (labeled_block_contains_loop_p (ctxp->current_labeled_block, loop))
13885     return loop;
13886
13887   loop_label = build_labeled_block (0, NULL_TREE);
13888   /* LOOP is an EXPR node, so it should have a valid EXPR_WFL_LINECOL
13889      that LOOP_LABEL could enquire about, for a better accuracy. FIXME */
13890   LABELED_BLOCK_BODY (loop_label) = loop;
13891   PUSH_LABELED_BLOCK (loop_label);
13892   return loop_label;
13893 }
13894
13895 /* 14.13, 14.14: break and continue Statements */
13896
13897 /* Build a break or a continue statement. a null NAME indicates an
13898    unlabeled break/continue statement.  */
13899
13900 static tree
13901 build_bc_statement (location, is_break, name)
13902      int location, is_break;
13903      tree name;
13904 {
13905   tree break_continue, label_block_expr = NULL_TREE;
13906
13907   if (name)
13908     {
13909       if (!(label_block_expr = IDENTIFIER_LOCAL_VALUE 
13910             (merge_qualified_name (label_id, EXPR_WFL_NODE (name)))))
13911         /* Null means that we don't have a target for this named
13912            break/continue. In this case, we make the target to be the
13913            label name, so that the error can be reported accuratly in
13914            patch_bc_statement. */
13915         label_block_expr = EXPR_WFL_NODE (name);
13916     }
13917   /* Unlabeled break/continue will be handled during the
13918      break/continue patch operation */
13919   break_continue 
13920     = build (EXIT_BLOCK_EXPR, NULL_TREE, label_block_expr, NULL_TREE);
13921
13922   IS_BREAK_STMT_P (break_continue) = is_break;
13923   TREE_SIDE_EFFECTS (break_continue) = 1;
13924   EXPR_WFL_LINECOL (break_continue) = location;
13925   break_continue = build_debugable_stmt (location, break_continue);
13926   return break_continue;
13927 }
13928
13929 /* Verification of a break/continue statement. */
13930
13931 static tree
13932 patch_bc_statement (node)
13933      tree node;
13934 {
13935   tree bc_label = EXIT_BLOCK_LABELED_BLOCK (node), target_stmt;
13936   tree labeled_block = ctxp->current_labeled_block;
13937   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13938  
13939   /* Having an identifier here means that the target is unknown. */
13940   if (bc_label != NULL_TREE && TREE_CODE (bc_label) == IDENTIFIER_NODE)
13941     {
13942       parse_error_context (wfl_operator, "No label definition found for `%s'",
13943                            IDENTIFIER_POINTER (bc_label));
13944       return error_mark_node;
13945     }
13946   if (! IS_BREAK_STMT_P (node))
13947     {
13948       /* It's a continue statement. */
13949       for (;; labeled_block = TREE_CHAIN (labeled_block))
13950         {
13951           if (labeled_block == NULL_TREE)
13952             {
13953               if (bc_label == NULL_TREE)
13954                 parse_error_context (wfl_operator,
13955                                      "`continue' must be in loop");
13956               else
13957                 parse_error_context 
13958                   (wfl_operator, "continue label `%s' does not name a loop",
13959                    IDENTIFIER_POINTER (bc_label));
13960               return error_mark_node;
13961             }
13962           if ((DECL_NAME (LABELED_BLOCK_LABEL (labeled_block))
13963                == continue_identifier_node)
13964               && (bc_label == NULL_TREE
13965                   || TREE_CHAIN (labeled_block) == bc_label))
13966             {
13967               bc_label = labeled_block;
13968               break;
13969             }
13970         }
13971     }
13972   else if (!bc_label)
13973     { 
13974       for (;; labeled_block = TREE_CHAIN (labeled_block))
13975         {
13976           if (labeled_block == NULL_TREE)
13977             {
13978               parse_error_context (wfl_operator,
13979                                      "`break' must be in loop or switch");
13980               return error_mark_node;
13981             }
13982           target_stmt = LABELED_BLOCK_BODY (labeled_block);
13983           if (TREE_CODE (target_stmt) == SWITCH_EXPR
13984               || search_loop (target_stmt))
13985             {
13986               bc_label = labeled_block;
13987               break;
13988             }
13989         }
13990     }
13991
13992   EXIT_BLOCK_LABELED_BLOCK (node) = bc_label;
13993   CAN_COMPLETE_NORMALLY (bc_label) = 1;
13994
13995   /* Our break/continue don't return values. */
13996   TREE_TYPE (node) = void_type_node;
13997   /* Encapsulate the break within a compound statement so that it's
13998      expanded all the times by expand_expr (and not clobbered
13999      sometimes, like after a if statement) */
14000   node = add_stmt_to_compound (NULL_TREE, void_type_node, node);
14001   TREE_SIDE_EFFECTS (node) = 1;
14002   return node;
14003 }
14004
14005 /* Process the exit expression belonging to a loop. Its type must be
14006    boolean.  */
14007
14008 static tree
14009 patch_exit_expr (node)
14010      tree node;
14011 {
14012   tree expression = TREE_OPERAND (node, 0);
14013   TREE_TYPE (node) = error_mark_node;
14014   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14015
14016   /* The type of expression must be boolean */
14017   if (TREE_TYPE (expression) != boolean_type_node)
14018     {
14019       parse_error_context 
14020         (wfl_operator, 
14021     "Incompatible type for loop conditional. Can't convert `%s' to `boolean'", 
14022          lang_printable_name (TREE_TYPE (expression), 0));
14023       return error_mark_node;
14024     }
14025   /* Now we know things are allright, invert the condition, fold and
14026      return */
14027   TREE_OPERAND (node, 0) = 
14028     fold (build1 (TRUTH_NOT_EXPR, boolean_type_node, expression));
14029
14030   if (! integer_zerop (TREE_OPERAND (node, 0))
14031       && ctxp->current_loop != NULL_TREE
14032       && TREE_CODE (ctxp->current_loop) == LOOP_EXPR)
14033     CAN_COMPLETE_NORMALLY (ctxp->current_loop) = 1;
14034   if (! integer_onep (TREE_OPERAND (node, 0)))
14035     CAN_COMPLETE_NORMALLY (node) = 1;
14036
14037
14038   TREE_TYPE (node) = void_type_node;
14039   return node;
14040 }
14041
14042 /* 14.9 Switch statement */
14043
14044 static tree
14045 patch_switch_statement (node)
14046      tree node;
14047 {
14048   tree se = TREE_OPERAND (node, 0), se_type;
14049
14050   /* Complete the switch expression */
14051   se = TREE_OPERAND (node, 0) = java_complete_tree (se);
14052   se_type = TREE_TYPE (se);
14053   /* The type of the switch expression must be char, byte, short or
14054      int */
14055   if (!JINTEGRAL_TYPE_P (se_type))
14056     {
14057       EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14058       parse_error_context (wfl_operator,
14059           "Incompatible type for `switch'. Can't convert `%s' to `int'",
14060                            lang_printable_name (se_type, 0));
14061       /* This is what java_complete_tree will check */
14062       TREE_OPERAND (node, 0) = error_mark_node;
14063       return error_mark_node;
14064     }
14065
14066   TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
14067
14068   /* Ready to return */
14069   if (TREE_CODE (TREE_OPERAND (node, 1)) == ERROR_MARK)
14070     {
14071       TREE_TYPE (node) = error_mark_node;
14072       return error_mark_node;
14073     }
14074   TREE_TYPE (node) = void_type_node;
14075   TREE_SIDE_EFFECTS (node) = 1;
14076   CAN_COMPLETE_NORMALLY (node)
14077     = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)) 
14078       || ! SWITCH_HAS_DEFAULT (node);
14079   return node;
14080 }
14081
14082 /* 14.18 The try/catch statements */
14083
14084 static tree
14085 build_try_statement (location, try_block, catches)
14086      int location;
14087      tree try_block, catches;
14088 {
14089   tree node = build (TRY_EXPR, NULL_TREE, try_block, catches);
14090   EXPR_WFL_LINECOL (node) = location;
14091   return node;
14092 }
14093
14094 static tree
14095 build_try_finally_statement (location, try_block, finally)
14096      int location;
14097      tree try_block, finally;
14098 {
14099   tree node = build (TRY_FINALLY_EXPR, NULL_TREE, try_block, finally);
14100   EXPR_WFL_LINECOL (node) = location;
14101   return node;
14102 }
14103
14104 static tree
14105 patch_try_statement (node)
14106      tree node;
14107 {
14108   int error_found = 0;
14109   tree try = TREE_OPERAND (node, 0);
14110   /* Exception handlers are considered in left to right order */
14111   tree catch = nreverse (TREE_OPERAND (node, 1));
14112   tree current, caught_type_list = NULL_TREE;
14113
14114   /* Check catch clauses, if any. Every time we find an error, we try
14115      to process the next catch clause. We process the catch clause before
14116      the try block so that when processing the try block we can check thrown
14117      exceptions againts the caught type list. */
14118   for (current = catch; current; current = TREE_CHAIN (current))
14119     {
14120       tree carg_decl, carg_type;
14121       tree sub_current, catch_block, catch_clause;
14122       int unreachable;
14123
14124       /* At this point, the structure of the catch clause is
14125            CATCH_EXPR           (catch node)
14126              BLOCK              (with the decl of the parameter)
14127                COMPOUND_EXPR
14128                  MODIFY_EXPR   (assignment of the catch parameter)
14129                  BLOCK          (catch clause block)
14130        */
14131       catch_clause = TREE_OPERAND (current, 0);
14132       carg_decl = BLOCK_EXPR_DECLS (catch_clause);
14133       carg_type = TREE_TYPE (TREE_TYPE (carg_decl));
14134
14135       /* Catch clauses can't have more than one parameter declared,
14136          but it's already enforced by the grammar. Make sure that the
14137          only parameter of the clause statement in of class Throwable
14138          or a subclass of Throwable, but that was done earlier. The
14139          catch clause parameter type has also been resolved. */
14140       
14141       /* Just make sure that the catch clause parameter type inherits
14142          from java.lang.Throwable */
14143       if (!inherits_from_p (carg_type, throwable_type_node))
14144         {
14145           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
14146           parse_error_context (wfl_operator,
14147                                "Can't catch class `%s'. Catch clause parameter type must be a subclass of class `java.lang.Throwable'",
14148                                lang_printable_name (carg_type, 0));
14149           error_found = 1;
14150           continue;
14151         }
14152       
14153       /* Partial check for unreachable catch statement: The catch
14154          clause is reachable iff is no earlier catch block A in
14155          the try statement such that the type of the catch
14156          clause's parameter is the same as or a subclass of the
14157          type of A's parameter */
14158       unreachable = 0;
14159       for (sub_current = catch;
14160            sub_current != current; sub_current = TREE_CHAIN (sub_current))
14161         {
14162           tree sub_catch_clause, decl;
14163           sub_catch_clause = TREE_OPERAND (sub_current, 0);
14164           decl = BLOCK_EXPR_DECLS (sub_catch_clause);
14165
14166           if (inherits_from_p (carg_type, TREE_TYPE (TREE_TYPE (decl))))
14167             {
14168               EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
14169               parse_error_context 
14170                 (wfl_operator,
14171                  "`catch' not reached because of the catch clause at line %d",
14172                  EXPR_WFL_LINENO (sub_current));
14173               unreachable = error_found = 1;
14174               break;
14175             }
14176         }
14177       /* Complete the catch clause block */
14178       catch_block = java_complete_tree (TREE_OPERAND (current, 0));
14179       if (catch_block == error_mark_node)
14180         {
14181           error_found = 1;
14182           continue;
14183         }
14184       if (CAN_COMPLETE_NORMALLY (catch_block))
14185         CAN_COMPLETE_NORMALLY (node) = 1;
14186       TREE_OPERAND (current, 0) = catch_block;
14187
14188       if (unreachable)
14189         continue;
14190
14191       /* Things to do here: the exception must be thrown */
14192
14193       /* Link this type to the caught type list */
14194       caught_type_list = tree_cons (NULL_TREE, carg_type, caught_type_list);
14195     }
14196
14197   PUSH_EXCEPTIONS (caught_type_list);
14198   if ((try = java_complete_tree (try)) == error_mark_node)
14199     error_found = 1;
14200   if (CAN_COMPLETE_NORMALLY (try))
14201     CAN_COMPLETE_NORMALLY (node) = 1;
14202   POP_EXCEPTIONS ();
14203
14204   /* Verification ends here */
14205   if (error_found) 
14206     return error_mark_node;
14207
14208   TREE_OPERAND (node, 0) = try;
14209   TREE_OPERAND (node, 1) = catch;
14210   TREE_TYPE (node) = void_type_node;
14211   return node;
14212 }
14213
14214 /* 14.17 The synchronized Statement */
14215
14216 static tree
14217 patch_synchronized_statement (node, wfl_op1)
14218     tree node, wfl_op1;
14219 {
14220   tree expr = java_complete_tree (TREE_OPERAND (node, 0));
14221   tree block = TREE_OPERAND (node, 1);
14222
14223   tree enter, exit, expr_decl, assignment;
14224
14225   if (expr == error_mark_node)
14226     {
14227       block = java_complete_tree (block);
14228       return expr;
14229     }
14230
14231   /* The TYPE of expr must be a reference type */
14232   if (!JREFERENCE_TYPE_P (TREE_TYPE (expr)))
14233     {
14234       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
14235       parse_error_context (wfl_operator, "Incompatible type for `synchronized'. Can't convert `%s' to `java.lang.Object'",
14236                            lang_printable_name (TREE_TYPE (expr), 0));
14237       return error_mark_node;
14238     }
14239
14240   if (flag_emit_xref)
14241     {
14242       TREE_OPERAND (node, 0) = expr;
14243       TREE_OPERAND (node, 1) = java_complete_tree (block);
14244       CAN_COMPLETE_NORMALLY (node) = 1;
14245       return node;
14246     }
14247
14248   /* Generate a try-finally for the synchronized statement, except
14249      that the handler that catches all throw exception calls
14250      _Jv_MonitorExit and then rethrow the exception.
14251      The synchronized statement is then implemented as:
14252      TRY 
14253        {
14254          _Jv_MonitorEnter (expression)
14255          synchronized_block
14256          _Jv_MonitorExit (expression)
14257        }
14258      CATCH_ALL
14259        {
14260          e = _Jv_exception_info ();
14261          _Jv_MonitorExit (expression)
14262          Throw (e);
14263        } */
14264
14265   expr_decl = build_decl (VAR_DECL, generate_name (), TREE_TYPE (expr));
14266   BUILD_MONITOR_ENTER (enter, expr_decl);
14267   BUILD_MONITOR_EXIT (exit, expr_decl);
14268   CAN_COMPLETE_NORMALLY (enter) = 1;
14269   CAN_COMPLETE_NORMALLY (exit) = 1;
14270   assignment = build (MODIFY_EXPR, NULL_TREE, expr_decl, expr);
14271   TREE_SIDE_EFFECTS (assignment) = 1;
14272   node = build1 (CLEANUP_POINT_EXPR, NULL_TREE,
14273                  build (COMPOUND_EXPR, NULL_TREE,
14274                         build (WITH_CLEANUP_EXPR, NULL_TREE,
14275                                build (COMPOUND_EXPR, NULL_TREE,
14276                                       assignment, enter),
14277                                NULL_TREE, exit),
14278                         block));
14279   node = build_expr_block (node, expr_decl);
14280
14281   return java_complete_tree (node);
14282 }
14283
14284 /* 14.16 The throw Statement */
14285
14286 static tree
14287 patch_throw_statement (node, wfl_op1)
14288     tree node, wfl_op1;
14289 {
14290   tree expr = TREE_OPERAND (node, 0);
14291   tree type = TREE_TYPE (expr);
14292   int unchecked_ok = 0, tryblock_throws_ok = 0;
14293
14294   /* Thrown expression must be assignable to java.lang.Throwable */
14295   if (!try_reference_assignconv (throwable_type_node, expr))
14296     {
14297       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
14298       parse_error_context (wfl_operator,
14299     "Can't throw `%s'; it must be a subclass of class `java.lang.Throwable'",
14300                            lang_printable_name (type, 0));
14301       /* If the thrown expression was a reference, we further the
14302          compile-time check. */
14303       if (!JREFERENCE_TYPE_P (type))
14304         return error_mark_node;
14305     }
14306
14307   /* At least one of the following must be true */
14308
14309   /* The type of the throw expression is a not checked exception,
14310      i.e. is a unchecked expression. */
14311   unchecked_ok = IS_UNCHECKED_EXCEPTION_P (TREE_TYPE (type));
14312
14313   SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
14314   /* An instance can't throw a checked excetion unless that exception
14315      is explicitely declared in the `throws' clause of each
14316      constructor. This doesn't apply to anonymous classes, since they
14317      don't have declared constructors. */
14318   if (!unchecked_ok 
14319       && in_instance_initializer && !ANONYMOUS_CLASS_P (current_class))
14320     {
14321       tree current;
14322       for (current = TYPE_METHODS (current_class); current; 
14323            current = TREE_CHAIN (current))
14324         if (DECL_CONSTRUCTOR_P (current) 
14325             && !check_thrown_exceptions_do (TREE_TYPE (expr)))
14326           {
14327             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)", 
14328                                  lang_printable_name (TREE_TYPE (expr), 0));
14329             return error_mark_node;
14330           }
14331     }
14332
14333   /* Throw is contained in a try statement and at least one catch
14334      clause can receive the thrown expression or the current method is
14335      declared to throw such an exception. Or, the throw statement is
14336      contained in a method or constructor declaration and the type of
14337      the Expression is assignable to at least one type listed in the
14338      throws clause the declaration. */
14339   if (!unchecked_ok)
14340     tryblock_throws_ok = check_thrown_exceptions_do (TREE_TYPE (expr));
14341   if (!(unchecked_ok || tryblock_throws_ok))
14342     {
14343       /* If there is a surrounding try block that has no matching
14344          clatch clause, report it first. A surrounding try block exits
14345          only if there is something after the list of checked
14346          exception thrown by the current function (if any). */
14347       if (IN_TRY_BLOCK_P ())
14348         parse_error_context (wfl_operator, "Checked exception `%s' can't be caught by any of the catch clause(s) of the surrounding `try' block",
14349                              lang_printable_name (type, 0));
14350       /* If we have no surrounding try statement and the method doesn't have
14351          any throws, report it now. FIXME */
14352
14353       /* We report that the exception can't be throw from a try block
14354          in all circumstances but when the `throw' is inside a static
14355          block. */
14356       else if (!EXCEPTIONS_P (currently_caught_type_list) 
14357                && !tryblock_throws_ok)
14358         {
14359           if (DECL_CLINIT_P (current_function_decl))
14360             parse_error_context (wfl_operator,
14361                    "Checked exception `%s' can't be thrown in initializer",
14362                                  lang_printable_name (type, 0));
14363           else
14364             parse_error_context (wfl_operator,
14365                    "Checked exception `%s' isn't thrown from a `try' block", 
14366                                  lang_printable_name (type, 0));
14367         }
14368       /* Otherwise, the current method doesn't have the appropriate
14369          throws declaration */
14370       else
14371         parse_error_context (wfl_operator, "Checked exception `%s' doesn't match any of current method's `throws' declaration(s)", 
14372                              lang_printable_name (type, 0));
14373       return error_mark_node;
14374     }
14375
14376   if (! flag_emit_class_files && ! flag_emit_xref)
14377     BUILD_THROW (node, expr);
14378
14379   /* If doing xrefs, keep the location where the `throw' was seen. */
14380   if (flag_emit_xref)
14381     EXPR_WFL_LINECOL (node) = EXPR_WFL_LINECOL (wfl_op1);
14382   return node;
14383 }
14384
14385 /* Check that exception said to be thrown by method DECL can be
14386    effectively caught from where DECL is invoked.  */
14387
14388 static void
14389 check_thrown_exceptions (location, decl)
14390      int location;
14391      tree decl;
14392 {
14393   tree throws;
14394   /* For all the unchecked exceptions thrown by DECL */
14395   for (throws = DECL_FUNCTION_THROWS (decl); throws; 
14396        throws = TREE_CHAIN (throws)) 
14397     if (!check_thrown_exceptions_do (TREE_VALUE (throws)))
14398       {
14399 #if 1
14400         /* Temporary hack to suppresses errors about cloning arrays. FIXME */
14401         if (DECL_NAME (decl) == get_identifier ("clone"))
14402           continue;
14403 #endif
14404         EXPR_WFL_LINECOL (wfl_operator) = location;
14405         if (DECL_FINIT_P (current_function_decl))
14406           parse_error_context
14407             (wfl_operator, "Exception `%s' can't be thrown in initializer",
14408              lang_printable_name (TREE_VALUE (throws), 0));
14409         else 
14410           {
14411             parse_error_context 
14412               (wfl_operator, "Exception `%s' must be caught, or it must be declared in the `throws' clause of `%s'", 
14413                lang_printable_name (TREE_VALUE (throws), 0),
14414                (DECL_INIT_P (current_function_decl) ?
14415                 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))) :
14416                 IDENTIFIER_POINTER (DECL_NAME (current_function_decl))));
14417           }
14418       }
14419 }
14420
14421 /* Return 1 if checked EXCEPTION is caught at the current nesting level of
14422    try-catch blocks, OR is listed in the `throws' clause of the
14423    current method.  */
14424
14425 static int
14426 check_thrown_exceptions_do (exception)
14427      tree exception;
14428 {
14429   tree list = currently_caught_type_list;
14430   resolve_and_layout (exception, NULL_TREE);
14431   /* First, all the nested try-catch-finally at that stage. The
14432      last element contains `throws' clause exceptions, if any. */
14433   if (IS_UNCHECKED_EXCEPTION_P (exception))
14434     return 1;
14435   while (list)
14436     {
14437       tree caught;
14438       for (caught = TREE_VALUE (list); caught; caught = TREE_CHAIN (caught))
14439         if (valid_ref_assignconv_cast_p (exception, TREE_VALUE (caught), 0))
14440           return 1;
14441       list = TREE_CHAIN (list);
14442     }
14443   return 0;
14444 }
14445
14446 static void
14447 purge_unchecked_exceptions (mdecl)
14448      tree mdecl;
14449 {
14450   tree throws = DECL_FUNCTION_THROWS (mdecl);
14451   tree new = NULL_TREE;
14452
14453   while (throws)
14454     {
14455       tree next = TREE_CHAIN (throws);
14456       if (!IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (throws)))
14457         {
14458           TREE_CHAIN (throws) = new;
14459           new = throws;
14460         }
14461       throws = next;
14462     }
14463   /* List is inverted here, but it doesn't matter */
14464   DECL_FUNCTION_THROWS (mdecl) = new;
14465 }
14466
14467 /* 15.24 Conditional Operator ?: */
14468
14469 static tree
14470 patch_conditional_expr (node, wfl_cond, wfl_op1)
14471      tree node, wfl_cond, wfl_op1;
14472 {
14473   tree cond = TREE_OPERAND (node, 0);
14474   tree op1 = TREE_OPERAND (node, 1);
14475   tree op2 = TREE_OPERAND (node, 2);
14476   tree resulting_type = NULL_TREE;
14477   tree t1, t2, patched;
14478   int error_found = 0;
14479
14480   /* Operands of ?: might be StringBuffers crafted as a result of a
14481      string concatenation. Obtain a descent operand here.  */
14482   if ((patched = patch_string (op1)))
14483     TREE_OPERAND (node, 1) = op1 = patched;
14484   if ((patched = patch_string (op2)))
14485     TREE_OPERAND (node, 2) = op2 = patched;
14486
14487   t1 = TREE_TYPE (op1);
14488   t2 = TREE_TYPE (op2);
14489
14490   /* The first expression must be a boolean */
14491   if (TREE_TYPE (cond) != boolean_type_node)
14492     {
14493       SET_WFL_OPERATOR (wfl_operator, node, wfl_cond);
14494       parse_error_context (wfl_operator,
14495                "Incompatible type for `?:'. Can't convert `%s' to `boolean'",
14496                            lang_printable_name (TREE_TYPE (cond), 0));
14497       error_found = 1;
14498     }
14499
14500   /* Second and third can be numeric, boolean (i.e. primitive),
14501      references or null. Anything else results in an error */
14502   if (!((JNUMERIC_TYPE_P (t1) && JNUMERIC_TYPE_P (t2))
14503         || ((JREFERENCE_TYPE_P (t1) || op1 == null_pointer_node) 
14504             && (JREFERENCE_TYPE_P (t2) || op2 == null_pointer_node))
14505         || (t1 == boolean_type_node && t2 == boolean_type_node)))
14506     error_found = 1;
14507
14508   /* Determine the type of the conditional expression. Same types are
14509      easy to deal with */
14510   else if (t1 == t2)
14511     resulting_type = t1;
14512
14513   /* There are different rules for numeric types */
14514   else if (JNUMERIC_TYPE_P (t1))
14515     {
14516       /* if byte/short found, the resulting type is short */
14517       if ((t1 == byte_type_node && t2 == short_type_node)
14518           || (t1 == short_type_node && t2 == byte_type_node))
14519         resulting_type = short_type_node;
14520
14521       /* If t1 is a constant int and t2 is of type byte, short or char
14522          and t1's value fits in t2, then the resulting type is t2 */
14523       else if ((t1 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 1)))
14524           && JBSC_TYPE_P (t2) && int_fits_type_p (TREE_OPERAND (node, 1), t2))
14525         resulting_type = t2;
14526
14527       /* If t2 is a constant int and t1 is of type byte, short or char
14528          and t2's value fits in t1, then the resulting type is t1 */
14529       else if ((t2 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 2)))
14530           && JBSC_TYPE_P (t1) && int_fits_type_p (TREE_OPERAND (node, 2), t1))
14531         resulting_type = t1;
14532
14533       /* Otherwise, binary numeric promotion is applied and the
14534          resulting type is the promoted type of operand 1 and 2 */
14535       else 
14536         resulting_type = binary_numeric_promotion (t1, t2, 
14537                                                    &TREE_OPERAND (node, 1), 
14538                                                    &TREE_OPERAND (node, 2));
14539     }
14540
14541   /* Cases of a reference and a null type */
14542   else if (JREFERENCE_TYPE_P (t1) && op2 == null_pointer_node)
14543     resulting_type = t1;
14544
14545   else if (JREFERENCE_TYPE_P (t2) && op1 == null_pointer_node)
14546     resulting_type = t2;
14547
14548   /* Last case: different reference types. If a type can be converted
14549      into the other one by assignment conversion, the latter
14550      determines the type of the expression */
14551   else if ((resulting_type = try_reference_assignconv (t1, op2)))
14552     resulting_type = promote_type (t1);
14553
14554   else if ((resulting_type = try_reference_assignconv (t2, op1)))
14555     resulting_type = promote_type (t2);
14556
14557   /* If we don't have any resulting type, we're in trouble */
14558   if (!resulting_type)
14559     {
14560       char *t = xstrdup (lang_printable_name (t1, 0));
14561       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
14562       parse_error_context (wfl_operator,
14563                  "Incompatible type for `?:'. Can't convert `%s' to `%s'",
14564                            t, lang_printable_name (t2, 0));
14565       free (t);
14566       error_found = 1;
14567     }
14568
14569   if (error_found)
14570     {
14571       TREE_TYPE (node) = error_mark_node;
14572       return error_mark_node;
14573     }
14574
14575   TREE_TYPE (node) = resulting_type;
14576   TREE_SET_CODE (node, COND_EXPR);
14577   CAN_COMPLETE_NORMALLY (node) = 1;
14578   return node;
14579 }
14580
14581 /* Try to constant fold NODE.
14582    If NODE is not a constant expression, return NULL_EXPR.
14583    CONTEXT is a static final VAR_DECL whose initializer we are folding. */
14584
14585 static tree
14586 fold_constant_for_init (node, context)
14587      tree node;
14588      tree context;
14589 {
14590   tree op0, op1, val;
14591   enum tree_code code = TREE_CODE (node);
14592
14593   if (code == STRING_CST)
14594     return node;
14595
14596   if (code == INTEGER_CST || code == REAL_CST)
14597     return convert (TREE_TYPE (context), node);
14598   if (TREE_TYPE (node) != NULL_TREE && code != VAR_DECL && code != FIELD_DECL)
14599     return NULL_TREE;
14600
14601   switch (code)
14602     {
14603     case PLUS_EXPR:
14604     case MINUS_EXPR:
14605     case MULT_EXPR:
14606     case TRUNC_MOD_EXPR:
14607     case RDIV_EXPR:
14608     case LSHIFT_EXPR:
14609     case RSHIFT_EXPR:
14610     case URSHIFT_EXPR:
14611     case BIT_AND_EXPR:
14612     case BIT_XOR_EXPR:
14613     case BIT_IOR_EXPR:
14614     case TRUTH_ANDIF_EXPR:
14615     case TRUTH_ORIF_EXPR:
14616     case EQ_EXPR: 
14617     case NE_EXPR:
14618     case GT_EXPR:
14619     case GE_EXPR:
14620     case LT_EXPR:
14621     case LE_EXPR:
14622       op0 = TREE_OPERAND (node, 0);
14623       op1 = TREE_OPERAND (node, 1);
14624       val = fold_constant_for_init (op0, context);
14625       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14626         return NULL_TREE;
14627       TREE_OPERAND (node, 0) = val;
14628       val = fold_constant_for_init (op1, context);
14629       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14630         return NULL_TREE;
14631       TREE_OPERAND (node, 1) = val;
14632       return patch_binop (node, op0, op1);
14633
14634     case UNARY_PLUS_EXPR:
14635     case NEGATE_EXPR:
14636     case TRUTH_NOT_EXPR:
14637     case BIT_NOT_EXPR:
14638     case CONVERT_EXPR:
14639       op0 = TREE_OPERAND (node, 0);
14640       val = fold_constant_for_init (op0, context);
14641       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14642         return NULL_TREE;
14643       TREE_OPERAND (node, 0) = val;
14644       return patch_unaryop (node, op0);
14645       break;
14646
14647     case COND_EXPR:
14648       val = fold_constant_for_init (TREE_OPERAND (node, 0), context);
14649       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14650         return NULL_TREE;
14651       TREE_OPERAND (node, 0) = val;
14652       val = fold_constant_for_init (TREE_OPERAND (node, 1), context);
14653       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14654         return NULL_TREE;
14655       TREE_OPERAND (node, 1) = val;
14656       val = fold_constant_for_init (TREE_OPERAND (node, 2), context);
14657       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14658         return NULL_TREE;
14659       TREE_OPERAND (node, 2) = val;
14660       return integer_zerop (TREE_OPERAND (node, 0)) ? TREE_OPERAND (node, 1)
14661         : TREE_OPERAND (node, 2);
14662
14663     case VAR_DECL:
14664     case FIELD_DECL:
14665       if (! FIELD_FINAL (node)
14666           || DECL_INITIAL (node) == NULL_TREE)
14667         return NULL_TREE;
14668       val = DECL_INITIAL (node);
14669       /* Guard against infinite recursion. */
14670       DECL_INITIAL (node) = NULL_TREE;
14671       val = fold_constant_for_init (val, node);
14672       DECL_INITIAL (node) = val;
14673       return val;
14674
14675     case EXPR_WITH_FILE_LOCATION:
14676       /* Compare java_complete_tree and resolve_expression_name. */
14677       if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
14678           || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
14679         {
14680           tree name = EXPR_WFL_NODE (node);
14681           tree decl;
14682           if (PRIMARY_P (node))
14683             return NULL_TREE;
14684           else if (! QUALIFIED_P (name))
14685             {
14686               decl = lookup_field_wrapper (DECL_CONTEXT (context), name);
14687               if (decl == NULL_TREE 
14688                   || (! FIELD_STATIC (decl) && ! FIELD_FINAL (decl)))
14689                 return NULL_TREE;
14690               return fold_constant_for_init (decl, decl);
14691             }
14692           else
14693             {
14694               /* Wait until the USE_COMPONENT_REF re-write.  FIXME. */
14695               qualify_ambiguous_name (node);
14696               if (resolve_field_access (node, &decl, NULL)
14697                   && decl != NULL_TREE)
14698                 return fold_constant_for_init (decl, decl);
14699               return NULL_TREE;
14700             }
14701         }
14702       else
14703         {
14704           op0 = TREE_OPERAND (node, 0);
14705           val = fold_constant_for_init (op0, context);
14706           if (val == NULL_TREE || ! TREE_CONSTANT (val))
14707             return NULL_TREE;
14708           TREE_OPERAND (node, 0) = val;
14709           return val;
14710         }
14711
14712 #ifdef USE_COMPONENT_REF
14713     case IDENTIFIER:
14714     case COMPONENT_REF:
14715       ?;
14716 #endif
14717
14718     default:
14719       return NULL_TREE;
14720     }
14721 }
14722
14723 #ifdef USE_COMPONENT_REF
14724 /* Context is 'T' for TypeName, 'P' for PackageName,
14725    'M' for MethodName, 'E' for ExpressionName, and 'A' for AmbiguousName. */
14726
14727 tree
14728 resolve_simple_name (name, context)
14729      tree name;
14730      int context;
14731 {
14732 }
14733
14734 tree
14735 resolve_qualified_name (name, context)
14736      tree name;
14737      int context;
14738 {
14739 }
14740 #endif