OSDN Git Service

2000-06-09 Bryce McKinlay <bryce@albatross.co.nz>
[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 void find_in_imports PARAMS ((tree));
103 static void check_inner_class_access PARAMS ((tree, tree, tree));
104 static int check_pkg_class_access PARAMS ((tree, tree));
105 static void register_package PARAMS ((tree));
106 static tree resolve_package PARAMS ((tree, tree *));
107 static tree lookup_package_type PARAMS ((const char *, int));
108 static tree lookup_package_type_and_set_next PARAMS ((const char *, int, tree *));
109 static tree resolve_class PARAMS ((tree, tree, tree, tree));
110 static void declare_local_variables PARAMS ((int, tree, tree));
111 static void source_start_java_method PARAMS ((tree));
112 static void source_end_java_method PARAMS ((void));
113 static void expand_start_java_method PARAMS ((tree));
114 static tree find_name_in_single_imports PARAMS ((tree));
115 static void check_abstract_method_header PARAMS ((tree));
116 static tree lookup_java_interface_method2 PARAMS ((tree, tree));
117 static tree resolve_expression_name PARAMS ((tree, tree *));
118 static tree maybe_create_class_interface_decl PARAMS ((tree, tree, tree, tree));
119 static int check_class_interface_creation PARAMS ((int, int, tree, 
120                                                   tree, tree, tree));
121 static tree patch_method_invocation PARAMS ((tree, tree, tree, 
122                                             int *, tree *));
123 static int breakdown_qualified PARAMS ((tree *, tree *, tree));
124 static tree resolve_and_layout PARAMS ((tree, tree));
125 static tree qualify_and_find PARAMS ((tree, tree, tree));
126 static tree resolve_no_layout PARAMS ((tree, tree));
127 static int invocation_mode PARAMS ((tree, int));
128 static tree find_applicable_accessible_methods_list PARAMS ((int, tree, 
129                                                             tree, tree));
130 static void search_applicable_methods_list PARAMS ((int, tree, tree, tree, 
131                                                    tree *, tree *));
132 static tree find_most_specific_methods_list PARAMS ((tree));
133 static int argument_types_convertible PARAMS ((tree, tree));
134 static tree patch_invoke PARAMS ((tree, tree, tree));
135 static int maybe_use_access_method PARAMS ((int, tree *, tree *));
136 static tree lookup_method_invoke PARAMS ((int, tree, tree, tree, tree));
137 static tree register_incomplete_type PARAMS ((int, tree, tree, tree));
138 static tree obtain_incomplete_type PARAMS ((tree));
139 static tree java_complete_lhs PARAMS ((tree));
140 static tree java_complete_tree PARAMS ((tree));
141 static tree maybe_generate_pre_expand_clinit PARAMS ((tree));
142 static int maybe_yank_clinit PARAMS ((tree));
143 static void java_complete_expand_method PARAMS ((tree));
144 static int  unresolved_type_p PARAMS ((tree, tree *));
145 static void create_jdep_list PARAMS ((struct parser_ctxt *));
146 static tree build_expr_block PARAMS ((tree, tree));
147 static tree enter_block PARAMS ((void));
148 static tree enter_a_block PARAMS ((tree));
149 static tree exit_block PARAMS ((void));
150 static tree lookup_name_in_blocks PARAMS ((tree));
151 static void maybe_absorb_scoping_blocks PARAMS ((void));
152 static tree build_method_invocation PARAMS ((tree, tree));
153 static tree build_new_invocation PARAMS ((tree, tree));
154 static tree build_assignment PARAMS ((int, int, tree, tree));
155 static tree build_binop PARAMS ((enum tree_code, int, tree, tree));
156 static int check_final_assignment PARAMS ((tree ,tree));
157 static tree patch_assignment PARAMS ((tree, tree, tree ));
158 static tree patch_binop PARAMS ((tree, tree, tree));
159 static tree build_unaryop PARAMS ((int, int, tree));
160 static tree build_incdec PARAMS ((int, int, tree, int));
161 static tree patch_unaryop PARAMS ((tree, tree));
162 static tree build_cast PARAMS ((int, tree, tree));
163 static tree build_null_of_type PARAMS ((tree));
164 static tree patch_cast PARAMS ((tree, tree));
165 static int valid_ref_assignconv_cast_p PARAMS ((tree, tree, int));
166 static int valid_builtin_assignconv_identity_widening_p PARAMS ((tree, tree));
167 static int valid_cast_to_p PARAMS ((tree, tree));
168 static int valid_method_invocation_conversion_p PARAMS ((tree, tree));
169 static tree try_builtin_assignconv PARAMS ((tree, tree, tree));
170 static tree try_reference_assignconv PARAMS ((tree, tree));
171 static tree build_unresolved_array_type PARAMS ((tree));
172 static tree build_array_from_name PARAMS ((tree, tree, tree, tree *));
173 static tree build_array_ref PARAMS ((int, tree, tree));
174 static tree patch_array_ref PARAMS ((tree));
175 static tree make_qualified_name PARAMS ((tree, tree, int));
176 static tree merge_qualified_name PARAMS ((tree, tree));
177 static tree make_qualified_primary PARAMS ((tree, tree, int));
178 static int resolve_qualified_expression_name PARAMS ((tree, tree *, 
179                                                      tree *, tree *));
180 static void qualify_ambiguous_name PARAMS ((tree));
181 static tree resolve_field_access PARAMS ((tree, tree *, tree *));
182 static tree build_newarray_node PARAMS ((tree, tree, int));
183 static tree patch_newarray PARAMS ((tree));
184 static tree resolve_type_during_patch PARAMS ((tree));
185 static tree build_this PARAMS ((int));
186 static tree build_wfl_wrap PARAMS ((tree, int));
187 static tree build_return PARAMS ((int, tree));
188 static tree patch_return PARAMS ((tree));
189 static tree maybe_access_field PARAMS ((tree, tree, tree));
190 static int complete_function_arguments PARAMS ((tree));
191 static int check_for_static_method_reference PARAMS ((tree, tree, tree, 
192                                                       tree, tree));
193 static int not_accessible_p PARAMS ((tree, tree, int));
194 static void check_deprecation PARAMS ((tree, tree));
195 static int class_in_current_package PARAMS ((tree));
196 static tree build_if_else_statement PARAMS ((int, tree, tree, tree));
197 static tree patch_if_else_statement PARAMS ((tree));
198 static tree add_stmt_to_compound PARAMS ((tree, tree, tree));
199 static tree add_stmt_to_block PARAMS ((tree, tree, tree));
200 static tree patch_exit_expr PARAMS ((tree));
201 static tree build_labeled_block PARAMS ((int, tree));
202 static tree finish_labeled_statement PARAMS ((tree, tree));
203 static tree build_bc_statement PARAMS ((int, int, tree));
204 static tree patch_bc_statement PARAMS ((tree));
205 static tree patch_loop_statement PARAMS ((tree));
206 static tree build_new_loop PARAMS ((tree));
207 static tree build_loop_body PARAMS ((int, tree, int));
208 static tree finish_loop_body PARAMS ((int, tree, tree, int));
209 static tree build_debugable_stmt PARAMS ((int, tree));
210 static tree finish_for_loop PARAMS ((int, tree, tree, tree));
211 static tree patch_switch_statement PARAMS ((tree));
212 static tree string_constant_concatenation PARAMS ((tree, tree));
213 static tree build_string_concatenation PARAMS ((tree, tree));
214 static tree patch_string_cst PARAMS ((tree));
215 static tree patch_string PARAMS ((tree));
216 static tree build_try_statement PARAMS ((int, tree, tree));
217 static tree build_try_finally_statement PARAMS ((int, tree, tree));
218 static tree patch_try_statement PARAMS ((tree));
219 static tree patch_synchronized_statement PARAMS ((tree, tree));
220 static tree patch_throw_statement PARAMS ((tree, tree));
221 static void check_thrown_exceptions PARAMS ((int, tree));
222 static int check_thrown_exceptions_do PARAMS ((tree));
223 static void purge_unchecked_exceptions PARAMS ((tree));
224 static void check_throws_clauses PARAMS ((tree, tree, tree));
225 static void finish_method_declaration PARAMS ((tree));
226 static tree build_super_invocation PARAMS ((tree));
227 static int verify_constructor_circularity PARAMS ((tree, tree));
228 static char *constructor_circularity_msg PARAMS ((tree, tree));
229 static tree build_this_super_qualified_invocation PARAMS ((int, tree, tree,
230                                                           int, int));
231 static const char *get_printable_method_name PARAMS ((tree));
232 static tree patch_conditional_expr PARAMS ((tree, tree, tree));
233 static tree generate_finit PARAMS ((tree));
234 static void add_instance_initializer PARAMS ((tree));
235 static void fix_constructors PARAMS ((tree));
236 static tree build_alias_initializer_parameter_list PARAMS ((int, tree,
237                                                             tree, int *));
238 static void craft_constructor PARAMS ((tree, tree));
239 static int verify_constructor_super PARAMS ((tree));
240 static tree create_artificial_method PARAMS ((tree, int, tree, tree, tree));
241 static void start_artificial_method_body PARAMS ((tree));
242 static void end_artificial_method_body PARAMS ((tree));
243 static int check_method_redefinition PARAMS ((tree, tree));
244 static int reset_method_name PARAMS ((tree));
245 static int check_method_types_complete PARAMS ((tree));
246 static void java_check_regular_methods PARAMS ((tree));
247 static void java_check_abstract_methods PARAMS ((tree));
248 static tree maybe_build_primttype_type_ref PARAMS ((tree, tree));
249 static void unreachable_stmt_error PARAMS ((tree));
250 static tree find_expr_with_wfl PARAMS ((tree));
251 static void missing_return_error PARAMS ((tree));
252 static tree build_new_array_init PARAMS ((int, tree));
253 static tree patch_new_array_init PARAMS ((tree, tree));
254 static tree maybe_build_array_element_wfl PARAMS ((tree));
255 static int array_constructor_check_entry PARAMS ((tree, tree));
256 static const char *purify_type_name PARAMS ((const char *));
257 static tree fold_constant_for_init PARAMS ((tree, tree));
258 static tree strip_out_static_field_access_decl PARAMS ((tree));
259 static jdeplist *reverse_jdep_list PARAMS ((struct parser_ctxt *));
260 static void static_ref_err PARAMS ((tree, tree, tree));
261 static void parser_add_interface PARAMS ((tree, tree, tree));
262 static void add_superinterfaces PARAMS ((tree, tree));
263 static tree jdep_resolve_class PARAMS ((jdep *));
264 static int note_possible_classname PARAMS ((const char *, int));
265 static void java_complete_expand_classes PARAMS ((void));
266 static void java_complete_expand_class PARAMS ((tree));
267 static void java_complete_expand_methods PARAMS ((tree));
268 static tree cut_identifier_in_qualified PARAMS ((tree));
269 static tree java_stabilize_reference PARAMS ((tree));
270 static tree do_unary_numeric_promotion PARAMS ((tree));
271 static char * operator_string PARAMS ((tree));
272 static tree do_merge_string_cste PARAMS ((tree, const char *, int, int));
273 static tree merge_string_cste PARAMS ((tree, tree, int));
274 static tree java_refold PARAMS ((tree));
275 static int java_decl_equiv PARAMS ((tree, tree));
276 static int binop_compound_p PARAMS ((enum tree_code));
277 static tree search_loop PARAMS ((tree));
278 static int labeled_block_contains_loop_p PARAMS ((tree, tree));
279 static void check_abstract_method_definitions PARAMS ((int, tree, tree));
280 static void java_check_abstract_method_definitions PARAMS ((tree));
281 static void java_debug_context_do PARAMS ((int));
282 static void java_parser_context_push_initialized_field PARAMS ((void));
283 static void java_parser_context_pop_initialized_field PARAMS ((void));
284 static tree reorder_static_initialized PARAMS ((tree));
285 static void java_parser_context_suspend PARAMS ((void));
286 static void java_parser_context_resume PARAMS ((void));
287
288 /* JDK 1.1 work. FIXME */
289
290 static tree maybe_make_nested_class_name PARAMS ((tree));
291 static void make_nested_class_name PARAMS ((tree));
292 static void set_nested_class_simple_name_value PARAMS ((tree, int));
293 static void link_nested_class_to_enclosing PARAMS ((void));
294 static tree find_as_inner_class PARAMS ((tree, tree, tree));
295 static tree find_as_inner_class_do PARAMS ((tree, tree));
296 static int check_inner_class_redefinition PARAMS ((tree, tree));
297
298 static tree build_thisn_assign PARAMS ((void));
299 static tree build_current_thisn PARAMS ((tree));
300 static tree build_access_to_thisn PARAMS ((tree, tree, int));
301 static tree maybe_build_thisn_access_method PARAMS ((tree));
302
303 static tree build_outer_field_access PARAMS ((tree, tree));
304 static tree build_outer_field_access_methods PARAMS ((tree));
305 static tree build_outer_field_access_expr PARAMS ((int, tree, tree, 
306                                                   tree, tree));
307 static tree build_outer_method_access_method PARAMS ((tree));
308 static tree build_new_access_id PARAMS ((void));
309 static tree build_outer_field_access_method PARAMS ((tree, tree, tree,
310                                                     tree, tree));
311
312 static int outer_field_access_p PARAMS ((tree, tree));
313 static int outer_field_expanded_access_p PARAMS ((tree, tree *, 
314                                                  tree *, tree *));
315 static tree outer_field_access_fix PARAMS ((tree, tree, tree));
316 static tree build_incomplete_class_ref PARAMS ((int, tree));
317 static tree patch_incomplete_class_ref PARAMS ((tree));
318 static tree create_anonymous_class PARAMS ((int, tree));
319 static void patch_anonymous_class PARAMS ((tree, tree, tree));
320 static void add_inner_class_fields PARAMS ((tree, tree));
321
322 static tree build_dot_class_method PARAMS ((tree));
323 static tree build_dot_class_method_invocation PARAMS ((tree));
324 static void create_new_parser_context PARAMS ((int));
325
326 /* Number of error found so far. */
327 int java_error_count; 
328 /* Number of warning found so far. */
329 int java_warning_count;
330 /* Tell when not to fold, when doing xrefs */
331 int do_not_fold;
332 /* Cyclic inheritance report, as it can be set by layout_class */
333 char *cyclic_inheritance_report;
334
335 /* Tell when we're within an instance initializer */
336 static int in_instance_initializer;
337
338 /* The current parser context */
339 struct parser_ctxt *ctxp;
340
341 /* List of things that were analyzed for which code will be generated */
342 static struct parser_ctxt *ctxp_for_generation = NULL;
343
344 /* binop_lookup maps token to tree_code. It is used where binary
345    operations are involved and required by the parser. RDIV_EXPR
346    covers both integral/floating point division. The code is changed
347    once the type of both operator is worked out.  */
348
349 static enum tree_code binop_lookup[19] = 
350   { 
351     PLUS_EXPR, MINUS_EXPR, MULT_EXPR, RDIV_EXPR, TRUNC_MOD_EXPR,
352     LSHIFT_EXPR, RSHIFT_EXPR, URSHIFT_EXPR, 
353     BIT_AND_EXPR, BIT_XOR_EXPR, BIT_IOR_EXPR,
354     TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR,
355     EQ_EXPR, NE_EXPR, GT_EXPR, GE_EXPR, LT_EXPR, LE_EXPR,
356    };
357 #define BINOP_LOOKUP(VALUE)                                             \
358   binop_lookup [((VALUE) - PLUS_TK)%                                    \
359                 (sizeof (binop_lookup) / sizeof (binop_lookup[0]))]
360
361 /* This is the end index for binary operators that can also be used
362    in compound assignements. */
363 #define BINOP_COMPOUND_CANDIDATES 11
364
365 /* Fake WFL used to report error message. It is initialized once if
366    needed and reused with it's location information is overriden.  */
367 tree wfl_operator = NULL_TREE;
368
369 /* The "$L" identifier we use to create labels.  */
370 static tree label_id = NULL_TREE;
371
372 /* The "StringBuffer" identifier used for the String `+' operator. */
373 static tree wfl_string_buffer = NULL_TREE; 
374
375 /* The "append" identifier used for String `+' operator.  */
376 static tree wfl_append = NULL_TREE;
377
378 /* The "toString" identifier used for String `+' operator. */
379 static tree wfl_to_string = NULL_TREE;
380
381 /* The "java.lang" import qualified name.  */
382 static tree java_lang_id = NULL_TREE;
383
384 /* The generated `inst$' identifier used for generated enclosing
385    instance/field access functions.  */
386 static tree inst_id = NULL_TREE;
387
388 /* The "java.lang.Cloneable" qualified name.  */
389 static tree java_lang_cloneable = NULL_TREE;
390
391 /* Context and flag for static blocks */
392 static tree current_static_block = NULL_TREE;
393
394 /* The generated `write_parm_value$' identifier.  */
395 static tree wpv_id;
396
397 /* The list of all packages we've seen so far */
398 static tree package_list = NULL_TREE;
399  
400 /* Check modifiers. If one doesn't fit, retrieve it in its declaration
401    line and point it out.  */
402 /* Should point out the one that don't fit. ASCII/unicode, going
403    backward. FIXME */
404
405 #define check_modifiers(__message, __value, __mask) do {        \
406   if ((__value) & ~(__mask))                                    \
407     {                                                           \
408       int i, remainder = (__value) & ~(__mask);                 \
409       for (i = 0; i <= 10; i++)                                 \
410         if ((1 << i) & remainder)                               \
411           parse_error_context (ctxp->modifier_ctx [i], (__message), \
412                                java_accstring_lookup (1 << i)); \
413     }                                                           \
414 } while (0)
415
416 %}
417
418 %union {
419   tree node;
420   int sub_token;
421   struct {
422     int token;
423     int location;
424   } operator;
425   int value;
426 }
427
428 %{
429 #include "lex.c"
430 %}
431
432 %pure_parser
433
434 /* Things defined here have to match the order of what's in the
435    binop_lookup table.  */
436
437 %token   PLUS_TK         MINUS_TK        MULT_TK         DIV_TK    REM_TK
438 %token   LS_TK           SRS_TK          ZRS_TK
439 %token   AND_TK          XOR_TK          OR_TK
440 %token   BOOL_AND_TK BOOL_OR_TK 
441 %token   EQ_TK NEQ_TK GT_TK GTE_TK LT_TK LTE_TK
442
443 /* This maps to the same binop_lookup entry than the token above */
444
445 %token   PLUS_ASSIGN_TK  MINUS_ASSIGN_TK MULT_ASSIGN_TK DIV_ASSIGN_TK
446 %token   REM_ASSIGN_TK   
447 %token   LS_ASSIGN_TK    SRS_ASSIGN_TK   ZRS_ASSIGN_TK
448 %token   AND_ASSIGN_TK   XOR_ASSIGN_TK   OR_ASSIGN_TK
449
450
451 /* Modifier TOKEN have to be kept in this order. Don't scramble it */
452
453 %token   PUBLIC_TK       PRIVATE_TK         PROTECTED_TK
454 %token   STATIC_TK       FINAL_TK           SYNCHRONIZED_TK
455 %token   VOLATILE_TK     TRANSIENT_TK       NATIVE_TK
456 %token   PAD_TK          ABSTRACT_TK        MODIFIER_TK
457
458 /* Keep those two in order, too */
459 %token   DECR_TK INCR_TK
460
461 /* From now one, things can be in any order */
462
463 %token   DEFAULT_TK      IF_TK              THROW_TK
464 %token   BOOLEAN_TK      DO_TK              IMPLEMENTS_TK
465 %token   THROWS_TK       BREAK_TK           IMPORT_TK       
466 %token   ELSE_TK         INSTANCEOF_TK      RETURN_TK
467 %token   VOID_TK         CATCH_TK           INTERFACE_TK
468 %token   CASE_TK         EXTENDS_TK         FINALLY_TK
469 %token   SUPER_TK        WHILE_TK           CLASS_TK
470 %token   SWITCH_TK       CONST_TK           TRY_TK
471 %token   FOR_TK          NEW_TK             CONTINUE_TK
472 %token   GOTO_TK         PACKAGE_TK         THIS_TK
473
474 %token   BYTE_TK         SHORT_TK           INT_TK            LONG_TK
475 %token   CHAR_TK         INTEGRAL_TK
476
477 %token   FLOAT_TK        DOUBLE_TK          FP_TK
478
479 %token   ID_TK
480
481 %token   REL_QM_TK         REL_CL_TK NOT_TK  NEG_TK
482
483 %token   ASSIGN_ANY_TK   ASSIGN_TK
484 %token   OP_TK  CP_TK  OCB_TK  CCB_TK  OSB_TK  CSB_TK  SC_TK  C_TK DOT_TK
485
486 %token   STRING_LIT_TK   CHAR_LIT_TK        INT_LIT_TK        FP_LIT_TK
487 %token   TRUE_TK         FALSE_TK           BOOL_LIT_TK       NULL_TK
488
489 %type    <value>        modifiers MODIFIER_TK final synchronized
490
491 %type    <node>         super ID_TK identifier
492 %type    <node>         name simple_name qualified_name
493 %type    <node>         type_declaration compilation_unit
494                         field_declaration method_declaration extends_interfaces
495                         interfaces interface_type_list
496                         class_member_declaration
497                         import_declarations package_declaration 
498                         type_declarations interface_body
499                         interface_member_declaration constant_declaration
500                         interface_member_declarations interface_type
501                         abstract_method_declaration interface_type_list
502 %type    <node>         class_body_declaration class_member_declaration
503                         static_initializer constructor_declaration block
504 %type    <node>         class_body_declarations constructor_header
505 %type    <node>         class_or_interface_type class_type class_type_list
506                         constructor_declarator explicit_constructor_invocation
507 %type    <node>         dim_expr dim_exprs this_or_super throws
508
509 %type    <node>         variable_declarator_id variable_declarator
510                         variable_declarators variable_initializer
511                         variable_initializers constructor_body
512                         array_initializer
513
514 %type    <node>         class_body block_end constructor_block_end
515 %type    <node>         statement statement_without_trailing_substatement
516                         labeled_statement if_then_statement label_decl
517                         if_then_else_statement while_statement for_statement
518                         statement_nsi labeled_statement_nsi do_statement
519                         if_then_else_statement_nsi while_statement_nsi
520                         for_statement_nsi statement_expression_list for_init
521                         for_update statement_expression expression_statement
522                         primary_no_new_array expression primary
523                         array_creation_expression array_type
524                         class_instance_creation_expression field_access
525                         method_invocation array_access something_dot_new
526                         argument_list postfix_expression while_expression 
527                         post_increment_expression post_decrement_expression
528                         unary_expression_not_plus_minus unary_expression
529                         pre_increment_expression pre_decrement_expression
530                         unary_expression_not_plus_minus cast_expression
531                         multiplicative_expression additive_expression
532                         shift_expression relational_expression 
533                         equality_expression and_expression 
534                         exclusive_or_expression inclusive_or_expression
535                         conditional_and_expression conditional_or_expression
536                         conditional_expression assignment_expression
537                         left_hand_side assignment for_header for_begin
538                         constant_expression do_statement_begin empty_statement
539                         switch_statement synchronized_statement throw_statement
540                         try_statement switch_expression switch_block
541                         catches catch_clause catch_clause_parameter finally
542                         anonymous_class_creation
543 %type    <node>         return_statement break_statement continue_statement
544
545 %type    <operator>     ASSIGN_TK      MULT_ASSIGN_TK  DIV_ASSIGN_TK  
546 %type    <operator>     REM_ASSIGN_TK  PLUS_ASSIGN_TK  MINUS_ASSIGN_TK
547 %type    <operator>     LS_ASSIGN_TK   SRS_ASSIGN_TK   ZRS_ASSIGN_TK
548 %type    <operator>     AND_ASSIGN_TK  XOR_ASSIGN_TK   OR_ASSIGN_TK
549 %type    <operator>     ASSIGN_ANY_TK  assignment_operator
550 %token   <operator>     EQ_TK GTE_TK ZRS_TK SRS_TK GT_TK LTE_TK LS_TK 
551 %token   <operator>     BOOL_AND_TK AND_TK BOOL_OR_TK OR_TK INCR_TK PLUS_TK
552 %token   <operator>     DECR_TK MINUS_TK MULT_TK DIV_TK XOR_TK REM_TK NEQ_TK
553 %token   <operator>     NEG_TK REL_QM_TK REL_CL_TK NOT_TK LT_TK OCB_TK CCB_TK
554 %token   <operator>     OP_TK OSB_TK DOT_TK THROW_TK INSTANCEOF_TK
555 %type    <operator>     THIS_TK SUPER_TK RETURN_TK BREAK_TK CONTINUE_TK 
556 %type    <operator>     CASE_TK DEFAULT_TK TRY_TK CATCH_TK SYNCHRONIZED_TK
557 %type    <operator>     NEW_TK
558
559 %type    <node>         method_body 
560         
561 %type    <node>         literal INT_LIT_TK FP_LIT_TK BOOL_LIT_TK CHAR_LIT_TK
562                         STRING_LIT_TK NULL_TK VOID_TK
563
564 %type    <node>         IF_TK WHILE_TK FOR_TK
565
566 %type    <node>         formal_parameter_list formal_parameter
567                         method_declarator method_header
568
569 %type    <node>         primitive_type reference_type type 
570                         BOOLEAN_TK INTEGRAL_TK FP_TK
571
572 /* Added or modified JDK 1.1 rule types  */
573 %type    <node>         type_literals array_type_literal
574
575 %%
576 /* 19.2 Production from 2.3: The Syntactic Grammar  */
577 goal:
578         compilation_unit
579                 {}
580 ;
581
582 /* 19.3 Productions from 3: Lexical structure  */
583 literal:
584         INT_LIT_TK
585 |       FP_LIT_TK
586 |       BOOL_LIT_TK
587 |       CHAR_LIT_TK
588 |       STRING_LIT_TK
589 |       NULL_TK
590 ;
591
592 /* 19.4 Productions from 4: Types, Values and Variables  */
593 type:
594         primitive_type
595 |       reference_type
596 ;
597
598 primitive_type:
599         INTEGRAL_TK
600 |       FP_TK
601 |       BOOLEAN_TK
602 ;
603
604 reference_type:
605         class_or_interface_type
606 |       array_type
607 ;
608
609 class_or_interface_type:
610         name
611 ;
612
613 class_type:
614         class_or_interface_type /* Default rule */
615 ;
616
617 interface_type:
618          class_or_interface_type
619 ;
620
621 array_type:
622         primitive_type OSB_TK CSB_TK
623                 { 
624                   $$ = build_java_array_type ($1, -1);
625                   CLASS_LOADED_P ($$) = 1;
626                 }
627 |       name OSB_TK CSB_TK
628                 { $$ = build_unresolved_array_type ($1); }
629 |       array_type OSB_TK CSB_TK
630                 { $$ = build_unresolved_array_type ($1); }
631 |       primitive_type OSB_TK error
632                 {RULE ("']' expected"); RECOVER;}
633 |       array_type OSB_TK error
634                 {RULE ("']' expected"); RECOVER;}
635 ;
636
637 /* 19.5 Productions from 6: Names  */
638 name:
639         simple_name             /* Default rule */
640 |       qualified_name          /* Default rule */
641 ;
642
643 simple_name:
644         identifier              /* Default rule */
645 ;
646
647 qualified_name:
648         name DOT_TK identifier
649                 { $$ = make_qualified_name ($1, $3, $2.location); }
650 ;
651
652 identifier:
653         ID_TK
654 ;
655
656 /* 19.6: Production from 7: Packages  */
657 compilation_unit:
658                 {$$ = NULL;}
659 |       package_declaration
660 |       import_declarations
661 |       type_declarations
662 |       package_declaration import_declarations
663 |       package_declaration type_declarations
664 |       import_declarations type_declarations
665 |       package_declaration import_declarations type_declarations
666 ;
667
668 import_declarations:
669         import_declaration
670                 {
671                   $$ = NULL;
672                 }
673 |       import_declarations import_declaration
674                 {
675                   $$ = NULL;
676                 }
677 ;
678
679 type_declarations:
680         type_declaration
681 |       type_declarations type_declaration
682 ;
683
684 package_declaration:
685         PACKAGE_TK name SC_TK
686                 { 
687                   ctxp->package = EXPR_WFL_NODE ($2);
688                   register_package (ctxp->package);
689                 }
690 |       PACKAGE_TK error
691                 {yyerror ("Missing name"); RECOVER;}
692 |       PACKAGE_TK name error
693                 {yyerror ("';' expected"); RECOVER;}
694 ;
695
696 import_declaration:
697         single_type_import_declaration
698 |       type_import_on_demand_declaration
699 ;
700
701 single_type_import_declaration:
702         IMPORT_TK name SC_TK
703                 {
704                   tree name = EXPR_WFL_NODE ($2), last_name;
705                   int   i = IDENTIFIER_LENGTH (name)-1;
706                   const char *last = &IDENTIFIER_POINTER (name)[i];
707                   while (last != IDENTIFIER_POINTER (name))
708                     {
709                       if (last [0] == '.')
710                         break;
711                       last--;
712                     }
713                   last_name = get_identifier (++last);
714                   if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (last_name))
715                     {
716                       tree err = find_name_in_single_imports (last_name);
717                       if (err && err != name)
718                         parse_error_context
719                           ($2, "Ambiguous class: `%s' and `%s'",
720                            IDENTIFIER_POINTER (name), 
721                            IDENTIFIER_POINTER (err));
722                       else
723                         REGISTER_IMPORT ($2, last_name);
724                     }
725                   else
726                     REGISTER_IMPORT ($2, last_name);
727                 }
728 |       IMPORT_TK error
729                 {yyerror ("Missing name"); RECOVER;}
730 |       IMPORT_TK name error
731                 {yyerror ("';' expected"); RECOVER;}
732 ;
733
734 type_import_on_demand_declaration:
735         IMPORT_TK name DOT_TK MULT_TK SC_TK
736                 {
737                   tree name = EXPR_WFL_NODE ($2);
738                   /* Don't import java.lang.* twice. */
739                   if (name != java_lang_id)
740                     {
741                       read_import_dir ($2);
742                       ctxp->import_demand_list = 
743                         chainon (ctxp->import_demand_list,
744                                  build_tree_list ($2, NULL_TREE));
745                     }
746                 }
747 |       IMPORT_TK name DOT_TK error
748                 {yyerror ("'*' expected"); RECOVER;}
749 |       IMPORT_TK name DOT_TK MULT_TK error
750                 {yyerror ("';' expected"); RECOVER;}
751 ;
752
753 type_declaration:
754         class_declaration
755                 { end_class_declaration (0); }
756 |       interface_declaration
757                 { end_class_declaration (0); }
758 |       SC_TK
759                 { $$ = NULL; }
760 |       error
761                 {
762                   YYERROR_NOW;
763                   yyerror ("Class or interface declaration expected");
764                 }
765 ;
766
767 /* 19.7 Shortened from the original:
768    modifiers: modifier | modifiers modifier
769    modifier: any of public...  */
770 modifiers:
771         MODIFIER_TK
772                 {
773                   $$ = (1 << $1);
774                 }
775 |       modifiers MODIFIER_TK
776                 {
777                   int acc = (1 << $2);
778                   if ($$ & acc)
779                     parse_error_context 
780                       (ctxp->modifier_ctx [$2], "Modifier `%s' declared twice",
781                        java_accstring_lookup (acc));
782                   else
783                     {
784                       $$ |= acc;
785                     }
786                 }
787 ;
788
789 /* 19.8.1 Production from $8.1: Class Declaration */
790 class_declaration:
791         modifiers CLASS_TK identifier super interfaces
792                 { create_class ($1, $3, $4, $5); }
793         class_body
794 |       CLASS_TK identifier super interfaces 
795                 { create_class (0, $2, $3, $4); }
796         class_body
797 |       modifiers CLASS_TK error
798                 {yyerror ("Missing class name"); RECOVER;}
799 |       CLASS_TK error
800                 {yyerror ("Missing class name"); RECOVER;}
801 |       CLASS_TK identifier error
802                 {
803                   if (!ctxp->class_err) yyerror ("'{' expected"); 
804                   DRECOVER(class1);
805                 }
806 |       modifiers CLASS_TK identifier error
807                 {if (!ctxp->class_err) yyerror ("'{' expected"); RECOVER;}
808 ;
809
810 super:
811                 { $$ = NULL; }
812 |       EXTENDS_TK class_type
813                 { $$ = $2; }
814 |       EXTENDS_TK class_type error
815                 {yyerror ("'{' expected"); ctxp->class_err=1;}
816 |       EXTENDS_TK error
817                 {yyerror ("Missing super class name"); ctxp->class_err=1;}
818 ;
819
820 interfaces:
821                 { $$ = NULL_TREE; }
822 |       IMPLEMENTS_TK interface_type_list
823                 { $$ = $2; }
824 |       IMPLEMENTS_TK error
825                 {
826                   ctxp->class_err=1;
827                   yyerror ("Missing interface name"); 
828                 }
829 ;
830
831 interface_type_list:
832         interface_type
833                 { 
834                   ctxp->interface_number = 1;
835                   $$ = build_tree_list ($1, NULL_TREE);
836                 }
837 |       interface_type_list C_TK interface_type
838                 { 
839                   ctxp->interface_number++;
840                   $$ = chainon ($1, build_tree_list ($3, NULL_TREE));
841                 }
842 |       interface_type_list C_TK error
843                 {yyerror ("Missing interface name"); RECOVER;}
844 ;
845
846 class_body:
847         OCB_TK CCB_TK
848                 { 
849                   /* Store the location of the `}' when doing xrefs */
850                   if (flag_emit_xref)
851                     DECL_END_SOURCE_LINE (GET_CPC ()) = 
852                       EXPR_WFL_ADD_COL ($2.location, 1);
853                   $$ = GET_CPC ();
854                 }
855 |       OCB_TK class_body_declarations CCB_TK
856                 { 
857                   /* Store the location of the `}' when doing xrefs */
858                   if (flag_emit_xref)
859                     DECL_END_SOURCE_LINE (GET_CPC ()) = 
860                       EXPR_WFL_ADD_COL ($3.location, 1);
861                   $$ = GET_CPC ();
862                 }
863 ;
864
865 class_body_declarations:
866         class_body_declaration
867 |       class_body_declarations class_body_declaration
868 ;
869
870 class_body_declaration:
871         class_member_declaration
872 |       static_initializer
873 |       constructor_declaration
874 |       block                   /* Added, JDK1.1, instance initializer */
875                 {
876                   TREE_CHAIN ($1) = CPC_INSTANCE_INITIALIZER_STMT (ctxp);
877                   SET_CPC_INSTANCE_INITIALIZER_STMT (ctxp, $1);
878                 }
879 ;
880
881 class_member_declaration:
882         field_declaration
883 |       field_declaration SC_TK
884                 { $$ = $1; }
885 |       method_declaration
886 |       class_declaration       /* Added, JDK1.1 inner classes */
887                 { end_class_declaration (1); }
888 |       interface_declaration   /* Added, JDK1.1 inner interfaces */
889                 { end_class_declaration (1); }
890 ;
891
892 /* 19.8.2 Productions from 8.3: Field Declarations  */
893 field_declaration:
894         type variable_declarators SC_TK
895                 { register_fields (0, $1, $2); }
896 |       modifiers type variable_declarators SC_TK
897                 {
898                   check_modifiers 
899                     ("Illegal modifier `%s' for field declaration",
900                      $1, FIELD_MODIFIERS);
901                   check_modifiers_consistency ($1);
902                   register_fields ($1, $2, $3);
903                 }
904 ;
905
906 variable_declarators:
907         /* Should we use build_decl_list () instead ? FIXME */
908         variable_declarator     /* Default rule */
909 |       variable_declarators C_TK variable_declarator
910                 { $$ = chainon ($1, $3); }
911 |       variable_declarators C_TK error
912                 {yyerror ("Missing term"); RECOVER;}
913 ;
914
915 variable_declarator:
916         variable_declarator_id
917                 { $$ = build_tree_list ($1, NULL_TREE); }
918 |       variable_declarator_id ASSIGN_TK variable_initializer
919                 { 
920                   if (java_error_count)
921                     $3 = NULL_TREE;
922                   $$ = build_tree_list 
923                     ($1, build_assignment ($2.token, $2.location, $1, $3));
924                 }
925 |       variable_declarator_id ASSIGN_TK error
926                 {
927                   yyerror ("Missing variable initializer");
928                   $$ = build_tree_list ($1, NULL_TREE);
929                   RECOVER;
930                 }
931 |       variable_declarator_id ASSIGN_TK variable_initializer error
932                 {
933                   yyerror ("';' expected");
934                   $$ = build_tree_list ($1, NULL_TREE);
935                   RECOVER;
936                 }
937 ;
938
939 variable_declarator_id:
940         identifier
941 |       variable_declarator_id OSB_TK CSB_TK
942                 { $$ = build_unresolved_array_type ($1); }
943 |       identifier error
944                 {yyerror ("Invalid declaration"); DRECOVER(vdi);}
945 |       variable_declarator_id OSB_TK error
946                 {yyerror ("']' expected"); DRECOVER(vdi);}
947 |       variable_declarator_id CSB_TK error
948                 {yyerror ("Unbalanced ']'"); DRECOVER(vdi);}
949 ;
950
951 variable_initializer:
952         expression
953 |       array_initializer
954 ;
955
956 /* 19.8.3 Productions from 8.4: Method Declarations  */
957 method_declaration:
958         method_header 
959                 {
960                   current_function_decl = $1;
961                   if (current_function_decl
962                       && TREE_CODE (current_function_decl) == FUNCTION_DECL)
963                     source_start_java_method (current_function_decl);
964                   else
965                     current_function_decl = NULL_TREE;
966                 }
967         method_body
968                 { finish_method_declaration ($3); }
969 |       method_header error
970                 {YYNOT_TWICE yyerror ("'{' expected"); RECOVER;}
971 ;
972
973 method_header:  
974         type method_declarator throws
975                 { $$ = method_header (0, $1, $2, $3); }
976 |       VOID_TK method_declarator throws
977                 { $$ = method_header (0, void_type_node, $2, $3); }
978 |       modifiers type method_declarator throws
979                 { $$ = method_header ($1, $2, $3, $4); }
980 |       modifiers VOID_TK method_declarator throws
981                 { $$ = method_header ($1, void_type_node, $3, $4); }
982 |       type error
983                 {
984                   yyerror ("Invalid method declaration, method name required");
985                   RECOVER;
986                 }
987 |       modifiers type error
988                 {RECOVER;}
989 |       VOID_TK error
990                 {yyerror ("Identifier expected"); RECOVER;}
991 |       modifiers VOID_TK error
992                 {yyerror ("Identifier expected"); RECOVER;}
993 |       modifiers error
994                 {
995                   yyerror ("Invalid method declaration, return type required");
996                   RECOVER;
997                 }
998 ;
999
1000 method_declarator:
1001         identifier OP_TK CP_TK
1002                 { 
1003                   ctxp->formal_parameter_number = 0;
1004                   $$ = method_declarator ($1, NULL_TREE);
1005                 }
1006 |       identifier OP_TK formal_parameter_list CP_TK
1007                 { $$ = method_declarator ($1, $3); }
1008 |       method_declarator OSB_TK CSB_TK
1009                 {
1010                   EXPR_WFL_LINECOL (wfl_operator) = $2.location;
1011                   TREE_PURPOSE ($1) = 
1012                     build_unresolved_array_type (TREE_PURPOSE ($1));
1013                   parse_warning_context 
1014                     (wfl_operator, 
1015                      "Discouraged form of returned type specification");
1016                 }
1017 |       identifier OP_TK error
1018                 {yyerror ("')' expected"); DRECOVER(method_declarator);}
1019 |       method_declarator OSB_TK error
1020                 {yyerror ("']' expected"); RECOVER;}
1021 ;
1022
1023 formal_parameter_list:
1024         formal_parameter
1025                 {
1026                   ctxp->formal_parameter_number = 1;
1027                 }
1028 |       formal_parameter_list C_TK formal_parameter
1029                 {
1030                   ctxp->formal_parameter_number += 1;
1031                   $$ = chainon ($1, $3);
1032                 }
1033 |       formal_parameter_list C_TK error
1034                 { yyerror ("Missing formal parameter term"); RECOVER; }
1035 ;
1036
1037 formal_parameter:
1038         type variable_declarator_id
1039                 {
1040                   $$ = build_tree_list ($2, $1);
1041                 }
1042 |       final type variable_declarator_id /* Added, JDK1.1 final parms */
1043                 { 
1044                   $$ = build_tree_list ($3, $2);
1045                   ARG_FINAL_P ($$) = 1;
1046                 }
1047 |       type error
1048                 {
1049                   yyerror ("Missing identifier"); RECOVER;
1050                   $$ = NULL_TREE;
1051                 }
1052 |       final type error
1053                 {
1054                   yyerror ("Missing identifier"); RECOVER;
1055                   $$ = NULL_TREE;
1056                 }
1057 ;
1058
1059 final:
1060         modifiers
1061                 {
1062                   check_modifiers ("Illegal modifier `%s'. Only `final' was expected here",
1063                                    $1, ACC_FINAL);
1064                   if ($1 != ACC_FINAL)
1065                     MODIFIER_WFL (FINAL_TK) = build_wfl_node (NULL_TREE);
1066                 }
1067 ;
1068
1069 throws:
1070                 { $$ = NULL_TREE; }
1071 |       THROWS_TK class_type_list
1072                 { $$ = $2; }
1073 |       THROWS_TK error
1074                 {yyerror ("Missing class type term"); RECOVER;}
1075 ;
1076
1077 class_type_list:
1078         class_type
1079                 { $$ = build_tree_list ($1, $1); }
1080 |       class_type_list C_TK class_type
1081                 { $$ = tree_cons ($3, $3, $1); }
1082 |       class_type_list C_TK error
1083                 {yyerror ("Missing class type term"); RECOVER;}
1084 ;
1085
1086 method_body:
1087         block
1088 |       block SC_TK
1089 |       SC_TK
1090                 { $$ = NULL_TREE; } /* Probably not the right thing to do. */
1091 ;
1092
1093 /* 19.8.4 Productions from 8.5: Static Initializers  */
1094 static_initializer:
1095         static block
1096                 {
1097                   TREE_CHAIN ($2) = CPC_STATIC_INITIALIZER_STMT (ctxp);
1098                   SET_CPC_STATIC_INITIALIZER_STMT (ctxp, $2);
1099                 }
1100 |       static block SC_TK      /* Shouldn't be here. FIXME */
1101                 {
1102                   TREE_CHAIN ($2) = CPC_STATIC_INITIALIZER_STMT (ctxp);
1103                   SET_CPC_STATIC_INITIALIZER_STMT (ctxp, $2);
1104                 }
1105 ;
1106
1107 static:                         /* Test lval.sub_token here */
1108         modifiers
1109                 {
1110                   check_modifiers ("Illegal modifier `%s' for static initializer", $1, ACC_STATIC);
1111                   /* Can't have a static initializer in an innerclass */
1112                   if ($1 | ACC_STATIC &&
1113                       GET_CPC_LIST () && !TOPLEVEL_CLASS_DECL_P (GET_CPC ()))
1114                     parse_error_context 
1115                       (MODIFIER_WFL (STATIC_TK),
1116                        "Can't define static initializer in class `%s'. Static initializer can only be defined in top-level classes",
1117                        IDENTIFIER_POINTER (DECL_NAME (GET_CPC ())));
1118                   SOURCE_FRONTEND_DEBUG (("Modifiers: %d", $1));
1119                 }
1120 ;
1121
1122 /* 19.8.5 Productions from 8.6: Constructor Declarations  */
1123 constructor_declaration:
1124         constructor_header
1125                 {
1126                   current_function_decl = $1;
1127                   source_start_java_method (current_function_decl);
1128                 }
1129         constructor_body
1130                 { finish_method_declaration ($3); }
1131 ;
1132
1133 constructor_header:
1134         constructor_declarator throws
1135                 { $$ = method_header (0, NULL_TREE, $1, $2); }
1136 |       modifiers constructor_declarator throws
1137                 { $$ = method_header ($1, NULL_TREE, $2, $3); }
1138 ;
1139
1140 constructor_declarator:
1141         simple_name OP_TK CP_TK
1142                 { 
1143                   ctxp->formal_parameter_number = 0;  
1144                   $$ = method_declarator ($1, NULL_TREE);
1145                 }
1146 |       simple_name OP_TK formal_parameter_list CP_TK
1147                 { $$ = method_declarator ($1, $3); }
1148 ;
1149
1150 constructor_body:
1151         /* Unlike regular method, we always need a complete (empty)
1152            body so we can safely perform all the required code
1153            addition (super invocation and field initialization) */
1154         block_begin constructor_block_end
1155                 { 
1156                   BLOCK_EXPR_BODY ($2) = empty_stmt_node;
1157                   $$ = $2;
1158                 }
1159 |       block_begin explicit_constructor_invocation constructor_block_end
1160                 { $$ = $3; }
1161 |       block_begin block_statements constructor_block_end
1162                 { $$ = $3; }
1163 |       block_begin explicit_constructor_invocation block_statements constructor_block_end
1164                 { $$ = $4; }
1165 ;
1166
1167 constructor_block_end:
1168         block_end
1169 |       block_end SC_TK
1170
1171 /* Error recovery for that rule moved down expression_statement: rule.  */
1172 explicit_constructor_invocation:
1173         this_or_super OP_TK CP_TK SC_TK
1174                 { 
1175                   $$ = build_method_invocation ($1, NULL_TREE); 
1176                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $$);
1177                   $$ = java_method_add_stmt (current_function_decl, $$);
1178                 }
1179 |       this_or_super OP_TK argument_list CP_TK SC_TK
1180                 { 
1181                   $$ = build_method_invocation ($1, $3); 
1182                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $$);
1183                   $$ = java_method_add_stmt (current_function_decl, $$);
1184                 }
1185         /* Added, JDK1.1 inner classes. Modified because the rule
1186            'primary' couldn't work.  */
1187 |       name DOT_TK SUPER_TK OP_TK argument_list CP_TK SC_TK
1188                 {$$ = parse_jdk1_1_error ("explicit constructor invocation"); }
1189 |       name DOT_TK SUPER_TK OP_TK CP_TK SC_TK
1190                 {$$ = parse_jdk1_1_error ("explicit constructor invocation"); }
1191 ;
1192
1193 this_or_super:                  /* Added, simplifies error diagnostics */
1194         THIS_TK
1195                 {
1196                   tree wfl = build_wfl_node (this_identifier_node);
1197                   EXPR_WFL_LINECOL (wfl) = $1.location;
1198                   $$ = wfl;
1199                 }
1200 |       SUPER_TK
1201                 {
1202                   tree wfl = build_wfl_node (super_identifier_node);
1203                   EXPR_WFL_LINECOL (wfl) = $1.location;
1204                   $$ = wfl;
1205                 }
1206 ;
1207
1208 /* 19.9 Productions from 9: Interfaces  */
1209 /* 19.9.1 Productions from 9.1: Interfaces Declarations  */
1210 interface_declaration:
1211         INTERFACE_TK identifier
1212                 { create_interface (0, $2, NULL_TREE); }
1213         interface_body
1214 |       modifiers INTERFACE_TK identifier
1215                 { create_interface ($1, $3, NULL_TREE); }
1216         interface_body
1217 |       INTERFACE_TK identifier extends_interfaces
1218                 { create_interface (0, $2, $3); }
1219         interface_body
1220 |       modifiers INTERFACE_TK identifier extends_interfaces
1221                 { create_interface ($1, $3, $4); }
1222         interface_body
1223 |       INTERFACE_TK identifier error
1224                 {yyerror ("'{' expected"); RECOVER;}
1225 |       modifiers INTERFACE_TK identifier error
1226                 {yyerror ("'{' expected"); RECOVER;}
1227 ;
1228
1229 extends_interfaces:
1230         EXTENDS_TK interface_type
1231                 { 
1232                   ctxp->interface_number = 1;
1233                   $$ = build_tree_list ($2, NULL_TREE);
1234                 }
1235 |       extends_interfaces C_TK interface_type
1236                 { 
1237                   ctxp->interface_number++;
1238                   $$ = chainon ($1, build_tree_list ($3, NULL_TREE));
1239                 }
1240 |       EXTENDS_TK error
1241                 {yyerror ("Invalid interface type"); RECOVER;}
1242 |       extends_interfaces C_TK error
1243                 {yyerror ("Missing term"); RECOVER;}
1244 ;
1245
1246 interface_body:
1247         OCB_TK CCB_TK
1248                 { $$ = NULL_TREE; }
1249 |       OCB_TK interface_member_declarations CCB_TK
1250                 { $$ = NULL_TREE; }
1251 ;
1252
1253 interface_member_declarations:
1254         interface_member_declaration
1255 |       interface_member_declarations interface_member_declaration
1256 ;
1257
1258 interface_member_declaration:
1259         constant_declaration
1260 |       abstract_method_declaration
1261 |       class_declaration       /* Added, JDK1.1 inner classes */
1262                 { end_class_declaration (1); }
1263 |       interface_declaration   /* Added, JDK1.1 inner interfaces */
1264                 { end_class_declaration (1); }
1265 ;
1266
1267 constant_declaration:
1268         field_declaration
1269 ;
1270
1271 abstract_method_declaration:
1272         method_header SC_TK
1273                 { 
1274                   check_abstract_method_header ($1);
1275                   current_function_decl = NULL_TREE; /* FIXME ? */
1276                 }
1277 |       method_header error
1278                 {yyerror ("';' expected"); RECOVER;}
1279 ;
1280
1281 /* 19.10 Productions from 10: Arrays  */
1282 array_initializer:
1283         OCB_TK CCB_TK
1284                 { $$ = build_new_array_init ($1.location, NULL_TREE); }
1285 |       OCB_TK variable_initializers CCB_TK
1286                 { $$ = build_new_array_init ($1.location, $2); }
1287 |       OCB_TK variable_initializers C_TK CCB_TK
1288                 { $$ = build_new_array_init ($1.location, $2); }
1289 ;
1290
1291 variable_initializers:
1292         variable_initializer
1293                 { 
1294                   $$ = tree_cons (maybe_build_array_element_wfl ($1), 
1295                                   $1, NULL_TREE);
1296                 }
1297 |       variable_initializers C_TK variable_initializer
1298                 {
1299                   $$ = tree_cons (maybe_build_array_element_wfl ($3), $3, $1);
1300                 }
1301 |       variable_initializers C_TK error
1302                 {yyerror ("Missing term"); RECOVER;}
1303 ;
1304
1305 /* 19.11 Production from 14: Blocks and Statements  */
1306 block:
1307         OCB_TK CCB_TK
1308                 { 
1309                   /* Store the location of the `}' when doing xrefs */
1310                   if (current_function_decl && flag_emit_xref)
1311                     DECL_END_SOURCE_LINE (current_function_decl) = 
1312                       EXPR_WFL_ADD_COL ($2.location, 1);
1313                   $$ = empty_stmt_node; 
1314                 }
1315 |       block_begin block_statements block_end
1316                 { $$ = $3; }
1317 ;
1318
1319 block_begin:
1320         OCB_TK
1321                 { enter_block (); }
1322 ;
1323
1324 block_end:
1325         CCB_TK
1326                 { 
1327                   maybe_absorb_scoping_blocks ();
1328                   /* Store the location of the `}' when doing xrefs */
1329                   if (current_function_decl && flag_emit_xref)
1330                     DECL_END_SOURCE_LINE (current_function_decl) = 
1331                       EXPR_WFL_ADD_COL ($1.location, 1);                  
1332                   $$ = exit_block ();
1333                   if (!BLOCK_SUBBLOCKS ($$))
1334                     BLOCK_SUBBLOCKS ($$) = empty_stmt_node;
1335                 }
1336 ;
1337
1338 block_statements:
1339         block_statement
1340 |       block_statements block_statement
1341 ;
1342
1343 block_statement:
1344         local_variable_declaration_statement
1345 |       statement
1346                 { java_method_add_stmt (current_function_decl, $1); }
1347 |       class_declaration       /* Added, JDK1.1 local classes */
1348                 { 
1349                   LOCAL_CLASS_P (TREE_TYPE (GET_CPC ())) = 1;
1350                   end_class_declaration (1);
1351                 }
1352 ;
1353
1354 local_variable_declaration_statement:
1355         local_variable_declaration SC_TK /* Can't catch missing ';' here */
1356 ;
1357
1358 local_variable_declaration:
1359         type variable_declarators
1360                 { declare_local_variables (0, $1, $2); }
1361 |       final type variable_declarators /* Added, JDK1.1 final locals */
1362                 { declare_local_variables ($1, $2, $3); }
1363 ;
1364
1365 statement:
1366         statement_without_trailing_substatement
1367 |       labeled_statement
1368 |       if_then_statement
1369 |       if_then_else_statement
1370 |       while_statement
1371 |       for_statement
1372                 { $$ = exit_block (); }
1373 ;
1374
1375 statement_nsi:
1376         statement_without_trailing_substatement
1377 |       labeled_statement_nsi
1378 |       if_then_else_statement_nsi
1379 |       while_statement_nsi
1380 |       for_statement_nsi
1381                 { $$ = exit_block (); }
1382 ;
1383
1384 statement_without_trailing_substatement:
1385         block
1386 |       empty_statement
1387 |       expression_statement
1388 |       switch_statement
1389 |       do_statement
1390 |       break_statement
1391 |       continue_statement
1392 |       return_statement
1393 |       synchronized_statement
1394 |       throw_statement
1395 |       try_statement
1396 ;
1397
1398 empty_statement:
1399         SC_TK
1400                 { $$ = empty_stmt_node; }
1401 ;
1402
1403 label_decl:
1404         identifier REL_CL_TK
1405                 {
1406                   $$ = build_labeled_block (EXPR_WFL_LINECOL ($1), 
1407                                             EXPR_WFL_NODE ($1));
1408                   pushlevel (2);
1409                   push_labeled_block ($$);
1410                   PUSH_LABELED_BLOCK ($$);
1411                 }
1412 ;
1413
1414 labeled_statement:
1415         label_decl statement
1416                 { $$ = finish_labeled_statement ($1, $2); }
1417 |       identifier error
1418                 {yyerror ("':' expected"); RECOVER;}
1419 ;
1420
1421 labeled_statement_nsi:
1422         label_decl statement_nsi
1423                 { $$ = finish_labeled_statement ($1, $2); }
1424 ;
1425
1426 /* We concentrate here a bunch of error handling rules that we couldn't write
1427    earlier, because expression_statement catches a missing ';'.  */
1428 expression_statement:
1429         statement_expression SC_TK
1430                 {
1431                   /* We have a statement. Generate a WFL around it so
1432                      we can debug it */
1433                   $$ = build_expr_wfl ($1, input_filename, lineno, 0);
1434                   /* We know we have a statement, so set the debug
1435                      info to be eventually generate here. */
1436                   $$ = JAVA_MAYBE_GENERATE_DEBUG_INFO ($$);
1437                 }
1438 |       error SC_TK 
1439                 {
1440                   if (ctxp->prevent_ese != lineno)
1441                     yyerror ("Invalid expression statement");
1442                   DRECOVER (expr_stmt);
1443                 }
1444 |       error OCB_TK
1445                 {
1446                   if (ctxp->prevent_ese != lineno)
1447                     yyerror ("Invalid expression statement");
1448                   DRECOVER (expr_stmt);
1449                 }
1450 |       error CCB_TK
1451                 {
1452                   if (ctxp->prevent_ese != lineno)
1453                     yyerror ("Invalid expression statement");
1454                   DRECOVER (expr_stmt);
1455                 }
1456 |       this_or_super OP_TK error
1457                 {yyerror ("')' expected"); RECOVER;}
1458 |       this_or_super OP_TK CP_TK error
1459                 {
1460                   parse_ctor_invocation_error ();
1461                   RECOVER;
1462                 }
1463 |       this_or_super OP_TK argument_list error
1464                 {yyerror ("')' expected"); RECOVER;}
1465 |       this_or_super OP_TK argument_list CP_TK error
1466                 {
1467                   parse_ctor_invocation_error ();
1468                   RECOVER;
1469                 }
1470 |       name DOT_TK SUPER_TK error
1471                 {yyerror ("'(' expected"); RECOVER;}
1472 |       name DOT_TK SUPER_TK OP_TK error
1473                 {yyerror ("')' expected"); RECOVER;}
1474 |       name DOT_TK SUPER_TK OP_TK argument_list error
1475                 {yyerror ("')' expected"); RECOVER;}
1476 |       name DOT_TK SUPER_TK OP_TK argument_list CP_TK error
1477                 {yyerror ("';' expected"); RECOVER;}
1478 |       name DOT_TK SUPER_TK OP_TK CP_TK error
1479                 {yyerror ("';' expected"); RECOVER;}
1480 ;
1481
1482 statement_expression: 
1483         assignment
1484 |       pre_increment_expression
1485 |       pre_decrement_expression
1486 |       post_increment_expression
1487 |       post_decrement_expression
1488 |       method_invocation
1489 |       class_instance_creation_expression
1490 ;
1491
1492 if_then_statement:
1493         IF_TK OP_TK expression CP_TK statement
1494                 { 
1495                   $$ = build_if_else_statement ($2.location, $3, 
1496                                                 $5, NULL_TREE);
1497                 }
1498 |       IF_TK error
1499                 {yyerror ("'(' expected"); RECOVER;}
1500 |       IF_TK OP_TK error
1501                 {yyerror ("Missing term"); RECOVER;}
1502 |       IF_TK OP_TK expression error
1503                 {yyerror ("')' expected"); RECOVER;}
1504 ;
1505
1506 if_then_else_statement:
1507         IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement
1508                 { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
1509 ;
1510
1511 if_then_else_statement_nsi:
1512         IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement_nsi
1513                 { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
1514 ;
1515
1516 switch_statement:
1517         switch_expression
1518                 {
1519                   enter_block ();
1520                 }
1521         switch_block
1522                 { 
1523                   /* Make into "proper list" of COMPOUND_EXPRs.
1524                      I.e. make the last statment also have its own
1525                      COMPOUND_EXPR. */
1526                   maybe_absorb_scoping_blocks ();
1527                   TREE_OPERAND ($1, 1) = exit_block ();
1528                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $1);
1529                 }
1530 ;
1531
1532 switch_expression:
1533         SWITCH_TK OP_TK expression CP_TK
1534                 { 
1535                   $$ = build (SWITCH_EXPR, NULL_TREE, $3, NULL_TREE);
1536                   EXPR_WFL_LINECOL ($$) = $2.location;
1537                 }
1538 |       SWITCH_TK error
1539                 {yyerror ("'(' expected"); RECOVER;}
1540 |       SWITCH_TK OP_TK error
1541                 {yyerror ("Missing term or ')'"); DRECOVER(switch_statement);}
1542 |       SWITCH_TK OP_TK expression CP_TK error
1543                 {yyerror ("'{' expected"); RECOVER;}
1544 ;
1545
1546 /* Default assignment is there to avoid type node on switch_block
1547    node. */
1548
1549 switch_block:
1550         OCB_TK CCB_TK
1551                 { $$ = NULL_TREE; }
1552 |       OCB_TK switch_labels CCB_TK
1553                 { $$ = NULL_TREE; }
1554 |       OCB_TK switch_block_statement_groups CCB_TK
1555                 { $$ = NULL_TREE; }
1556 |       OCB_TK switch_block_statement_groups switch_labels CCB_TK
1557                 { $$ = NULL_TREE; }
1558 ;
1559
1560 switch_block_statement_groups: 
1561         switch_block_statement_group
1562 |       switch_block_statement_groups switch_block_statement_group
1563 ;
1564
1565 switch_block_statement_group:
1566         switch_labels block_statements
1567 ;
1568
1569 switch_labels:
1570         switch_label
1571 |       switch_labels switch_label
1572 ;
1573
1574 switch_label:
1575         CASE_TK constant_expression REL_CL_TK
1576                 { 
1577                   tree lab = build1 (CASE_EXPR, NULL_TREE, $2);
1578                   EXPR_WFL_LINECOL (lab) = $1.location;
1579                   java_method_add_stmt (current_function_decl, lab);
1580                 }
1581 |       DEFAULT_TK REL_CL_TK
1582                 { 
1583                   tree lab = build1 (DEFAULT_EXPR, NULL_TREE, NULL_TREE);
1584                   EXPR_WFL_LINECOL (lab) = $1.location;
1585                   java_method_add_stmt (current_function_decl, lab);
1586                 }
1587 |       CASE_TK error
1588                 {yyerror ("Missing or invalid constant expression"); RECOVER;}
1589 |       CASE_TK constant_expression error
1590                 {yyerror ("':' expected"); RECOVER;}
1591 |       DEFAULT_TK error
1592                 {yyerror ("':' expected"); RECOVER;}
1593 ;
1594
1595 while_expression:
1596         WHILE_TK OP_TK expression CP_TK
1597                 { 
1598                   tree body = build_loop_body ($2.location, $3, 0);
1599                   $$ = build_new_loop (body);
1600                 }
1601 ;
1602
1603 while_statement:
1604         while_expression statement
1605                 { $$ = finish_loop_body (0, NULL_TREE, $2, 0); }
1606 |       WHILE_TK error
1607                 {YYERROR_NOW; yyerror ("'(' expected"); RECOVER;}
1608 |       WHILE_TK OP_TK error
1609                 {yyerror ("Missing term and ')' expected"); RECOVER;}
1610 |       WHILE_TK OP_TK expression error
1611                 {yyerror ("')' expected"); RECOVER;}
1612 ;
1613
1614 while_statement_nsi:
1615         while_expression statement_nsi
1616                 { $$ = finish_loop_body (0, NULL_TREE, $2, 0); }
1617 ;
1618
1619 do_statement_begin:
1620         DO_TK
1621                 { 
1622                   tree body = build_loop_body (0, NULL_TREE, 1);
1623                   $$ = build_new_loop (body);
1624                 }
1625         /* Need error handing here. FIXME */
1626 ;
1627
1628 do_statement: 
1629         do_statement_begin statement WHILE_TK OP_TK expression CP_TK SC_TK
1630                 { $$ = finish_loop_body ($4.location, $5, $2, 1); }
1631 ;
1632
1633 for_statement:
1634         for_begin SC_TK expression SC_TK for_update CP_TK statement
1635                 {
1636                   if (TREE_CODE_CLASS (TREE_CODE ($3)) == 'c')
1637                     $3 = build_wfl_node ($3);
1638                   $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7);
1639                 }
1640 |       for_begin SC_TK SC_TK for_update CP_TK statement
1641                 { 
1642                   $$ = finish_for_loop (0, NULL_TREE, $4, $6);
1643                   /* We have not condition, so we get rid of the EXIT_EXPR */
1644                   LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) = 
1645                     empty_stmt_node;
1646                 }
1647 |       for_begin SC_TK error
1648                 {yyerror ("Invalid control expression"); RECOVER;}
1649 |       for_begin SC_TK expression SC_TK error
1650                 {yyerror ("Invalid update expression"); RECOVER;}
1651 |       for_begin SC_TK SC_TK error
1652                 {yyerror ("Invalid update expression"); RECOVER;}
1653 ;
1654
1655 for_statement_nsi:
1656         for_begin SC_TK expression SC_TK for_update CP_TK statement_nsi
1657                 { $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7);}
1658 |       for_begin SC_TK SC_TK for_update CP_TK statement_nsi
1659                 { 
1660                   $$ = finish_for_loop (0, NULL_TREE, $4, $6);
1661                   /* We have not condition, so we get rid of the EXIT_EXPR */
1662                   LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) = 
1663                     empty_stmt_node;
1664                 }
1665 ;
1666
1667 for_header:
1668         FOR_TK OP_TK
1669                 { 
1670                   /* This scope defined for local variable that may be
1671                      defined within the scope of the for loop */
1672                   enter_block (); 
1673                 }
1674 |       FOR_TK error
1675                 {yyerror ("'(' expected"); DRECOVER(for_1);}
1676 |       FOR_TK OP_TK error
1677                 {yyerror ("Invalid init statement"); RECOVER;}
1678 ;
1679
1680 for_begin:
1681         for_header for_init
1682                 { 
1683                   /* We now declare the loop body. The loop is
1684                      declared as a for loop. */
1685                   tree body = build_loop_body (0, NULL_TREE, 0);
1686                   $$ =  build_new_loop (body);
1687                   FOR_LOOP_P ($$) = 1;
1688                   /* The loop is added to the current block the for
1689                      statement is defined within */
1690                   java_method_add_stmt (current_function_decl, $$);
1691                 }
1692 ;
1693 for_init:                       /* Can be empty */
1694                 { $$ = empty_stmt_node; }
1695 |       statement_expression_list
1696                 { 
1697                   /* Init statement recorded within the previously
1698                      defined block scope */
1699                   $$ = java_method_add_stmt (current_function_decl, $1);
1700                 }
1701 |       local_variable_declaration
1702                 { 
1703                   /* Local variable are recorded within the previously
1704                      defined block scope */
1705                   $$ = NULL_TREE;
1706                 }
1707 |       statement_expression_list error
1708                 {yyerror ("';' expected"); DRECOVER(for_init_1);}
1709 ;
1710
1711 for_update:                     /* Can be empty */
1712                 {$$ = empty_stmt_node;}
1713 |       statement_expression_list
1714                 { $$ = build_debugable_stmt (BUILD_LOCATION (), $1); }
1715 ;
1716
1717 statement_expression_list:
1718         statement_expression
1719                 { $$ = add_stmt_to_compound (NULL_TREE, NULL_TREE, $1); }
1720 |       statement_expression_list C_TK statement_expression
1721                 { $$ = add_stmt_to_compound ($1, NULL_TREE, $3); }
1722 |       statement_expression_list C_TK error
1723                 {yyerror ("Missing term"); RECOVER;}
1724 ;
1725
1726 break_statement:
1727         BREAK_TK SC_TK
1728                 { $$ = build_bc_statement ($1.location, 1, NULL_TREE); }
1729 |       BREAK_TK identifier SC_TK
1730                 { $$ = build_bc_statement ($1.location, 1, $2); }
1731 |       BREAK_TK error
1732                 {yyerror ("Missing term"); RECOVER;}
1733 |       BREAK_TK identifier error
1734                 {yyerror ("';' expected"); RECOVER;}
1735 ;
1736
1737 continue_statement:
1738         CONTINUE_TK SC_TK
1739                 { $$ = build_bc_statement ($1.location, 0, NULL_TREE); }
1740 |       CONTINUE_TK identifier SC_TK
1741                 { $$ = build_bc_statement ($1.location, 0, $2); }
1742 |       CONTINUE_TK error
1743                 {yyerror ("Missing term"); RECOVER;}
1744 |       CONTINUE_TK identifier error
1745                 {yyerror ("';' expected"); RECOVER;}
1746 ;
1747
1748 return_statement:
1749         RETURN_TK SC_TK
1750                 { $$ = build_return ($1.location, NULL_TREE); }
1751 |       RETURN_TK expression SC_TK
1752                 { $$ = build_return ($1.location, $2); }
1753 |       RETURN_TK error
1754                 {yyerror ("Missing term"); RECOVER;}
1755 |       RETURN_TK expression error
1756                 {yyerror ("';' expected"); RECOVER;}
1757 ;
1758
1759 throw_statement:
1760         THROW_TK expression SC_TK
1761                 { 
1762                   $$ = build1 (THROW_EXPR, NULL_TREE, $2);
1763                   EXPR_WFL_LINECOL ($$) = $1.location;
1764                 }
1765 |       THROW_TK error
1766                 {yyerror ("Missing term"); RECOVER;}
1767 |       THROW_TK expression error
1768                 {yyerror ("';' expected"); RECOVER;}
1769 ;
1770
1771 synchronized_statement:
1772         synchronized OP_TK expression CP_TK block
1773                 { 
1774                   $$ = build (SYNCHRONIZED_EXPR, NULL_TREE, $3, $5);
1775                   EXPR_WFL_LINECOL ($$) = 
1776                     EXPR_WFL_LINECOL (MODIFIER_WFL (SYNCHRONIZED_TK));
1777                 }
1778 |       synchronized OP_TK expression CP_TK error
1779                 {yyerror ("'{' expected"); RECOVER;}
1780 |       synchronized error
1781                 {yyerror ("'(' expected"); RECOVER;}
1782 |       synchronized OP_TK error CP_TK
1783                 {yyerror ("Missing term"); RECOVER;}
1784 |       synchronized OP_TK error
1785                 {yyerror ("Missing term"); RECOVER;}
1786 ;
1787
1788 synchronized:
1789         modifiers
1790                 {
1791                   check_modifiers (
1792              "Illegal modifier `%s'. Only `synchronized' was expected here",
1793                                    $1, ACC_SYNCHRONIZED);
1794                   if ($1 != ACC_SYNCHRONIZED)
1795                     MODIFIER_WFL (SYNCHRONIZED_TK) = 
1796                       build_wfl_node (NULL_TREE);
1797                 }
1798 ;
1799
1800 try_statement:
1801         TRY_TK block catches
1802                 { $$ = build_try_statement ($1.location, $2, $3); }
1803 |       TRY_TK block finally
1804                 { $$ = build_try_finally_statement ($1.location, $2, $3); }
1805 |       TRY_TK block catches finally
1806                 { $$ = build_try_finally_statement 
1807                     ($1.location, build_try_statement ($1.location,
1808                                                        $2, $3), $4);
1809                 }
1810 |       TRY_TK error
1811                 {yyerror ("'{' expected"); DRECOVER (try_statement);}
1812 ;
1813
1814 catches:
1815         catch_clause
1816 |       catches catch_clause
1817                 { 
1818                   TREE_CHAIN ($2) = $1;
1819                   $$ = $2;
1820                 }
1821 ;
1822
1823 catch_clause:
1824         catch_clause_parameter block
1825                 { 
1826                   java_method_add_stmt (current_function_decl, $2);
1827                   exit_block ();
1828                   $$ = $1;
1829                 }
1830
1831 catch_clause_parameter:
1832         CATCH_TK OP_TK formal_parameter CP_TK
1833                 { 
1834                   /* We add a block to define a scope for
1835                      formal_parameter (CCBP). The formal parameter is
1836                      declared initialized by the appropriate function
1837                      call */
1838                   tree ccpb = enter_block ();
1839                   tree init = build_assignment (ASSIGN_TK, $2.location, 
1840                                                 TREE_PURPOSE ($3), 
1841                                                 soft_exceptioninfo_call_node);
1842                   declare_local_variables (0, TREE_VALUE ($3),
1843                                            build_tree_list (TREE_PURPOSE ($3),
1844                                                             init));
1845                   $$ = build1 (CATCH_EXPR, NULL_TREE, ccpb);
1846                   EXPR_WFL_LINECOL ($$) = $1.location;
1847                 }
1848 |       CATCH_TK error
1849                 {yyerror ("'(' expected"); RECOVER; $$ = NULL_TREE;}
1850 |       CATCH_TK OP_TK error 
1851                 {
1852                   yyerror ("Missing term or ')' expected"); 
1853                   RECOVER; $$ = NULL_TREE;
1854                 }
1855 |       CATCH_TK OP_TK error CP_TK /* That's for () */
1856                 {yyerror ("Missing term"); RECOVER; $$ = NULL_TREE;}
1857 ;
1858
1859 finally:
1860         FINALLY_TK block
1861                 { $$ = $2; }
1862 |       FINALLY_TK error
1863                 {yyerror ("'{' expected"); RECOVER; }
1864 ;
1865
1866 /* 19.12 Production from 15: Expressions  */
1867 primary:
1868         primary_no_new_array
1869 |       array_creation_expression
1870 ;
1871
1872 primary_no_new_array:
1873         literal
1874 |       THIS_TK
1875                 { $$ = build_this ($1.location); }
1876 |       OP_TK expression CP_TK
1877                 {$$ = $2;}
1878 |       class_instance_creation_expression
1879 |       field_access
1880 |       method_invocation
1881 |       array_access
1882 |       type_literals
1883         /* Added, JDK1.1 inner classes. Documentation is wrong
1884            refering to a 'ClassName' (class_name) rule that doesn't
1885            exist. Used name: instead.  */
1886 |       name DOT_TK THIS_TK
1887                 { 
1888                   tree wfl = build_wfl_node (this_identifier_node);
1889                   $$ = make_qualified_primary ($1, wfl, EXPR_WFL_LINECOL ($1));
1890                 }
1891 |       OP_TK expression error 
1892                 {yyerror ("')' expected"); RECOVER;}
1893 |       name DOT_TK error
1894                 {yyerror ("'class' or 'this' expected" ); RECOVER;}
1895 |       primitive_type DOT_TK error
1896                 {yyerror ("'class' expected" ); RECOVER;}
1897 |       VOID_TK DOT_TK error
1898                 {yyerror ("'class' expected" ); RECOVER;}
1899 ;
1900
1901 /* Added, JDK1.1 type literals. We can't use `type' directly, so we
1902    broke the rule down a bit. */
1903
1904 array_type_literal:
1905         primitive_type OSB_TK CSB_TK
1906                 { 
1907                   $$ = build_java_array_type ($1, -1);
1908                   CLASS_LOADED_P ($$) = 1;
1909                 }
1910 |       name OSB_TK CSB_TK
1911                 { $$ = build_unresolved_array_type ($1); }
1912 /* This triggers two reduce/reduce conflict between array_type_literal and
1913    dims. FIXME.
1914 |       array_type OSB_TK CSB_TK
1915                 { $$ = build_unresolved_array_type ($1); }
1916 */
1917 ;
1918
1919 type_literals:
1920         name DOT_TK CLASS_TK
1921                 { $$ = build_incomplete_class_ref ($2.location, $1); }
1922 |       array_type_literal DOT_TK CLASS_TK
1923                 { $$ = build_incomplete_class_ref ($2.location, $1); }
1924 |       primitive_type DOT_TK CLASS_TK
1925                 { $$ = build_class_ref ($1); }
1926 |       VOID_TK DOT_TK CLASS_TK
1927                 { $$ = build_class_ref (void_type_node); }
1928 ;
1929
1930 class_instance_creation_expression:
1931         NEW_TK class_type OP_TK argument_list CP_TK
1932                 { $$ = build_new_invocation ($2, $4); }
1933 |       NEW_TK class_type OP_TK CP_TK
1934                 { $$ = build_new_invocation ($2, NULL_TREE); }
1935 |       anonymous_class_creation
1936         /* Added, JDK1.1 inner classes, modified to use name or
1937            primary instead of primary solely which couldn't work in
1938            all situations.  */
1939 |       something_dot_new identifier OP_TK CP_TK
1940                 { 
1941                   tree ctor = build_new_invocation ($2, NULL_TREE);
1942                   $$ = make_qualified_primary ($1, ctor, 
1943                                                EXPR_WFL_LINECOL ($1));
1944                 }
1945 |       something_dot_new identifier OP_TK CP_TK class_body
1946 |       something_dot_new identifier OP_TK argument_list CP_TK
1947                 { 
1948                   tree ctor = build_new_invocation ($2, $4);
1949                   $$ = make_qualified_primary ($1, ctor, 
1950                                                EXPR_WFL_LINECOL ($1));
1951                 }
1952 |       something_dot_new identifier OP_TK argument_list CP_TK class_body
1953 |       NEW_TK error SC_TK 
1954                 {yyerror ("'(' expected"); DRECOVER(new_1);}
1955 |       NEW_TK class_type error
1956                 {yyerror ("'(' expected"); RECOVER;}
1957 |       NEW_TK class_type OP_TK error
1958                 {yyerror ("')' or term expected"); RECOVER;}
1959 |       NEW_TK class_type OP_TK argument_list error
1960                 {yyerror ("')' expected"); RECOVER;}
1961 |       something_dot_new error
1962                 {YYERROR_NOW; yyerror ("Identifier expected"); RECOVER;}
1963 |       something_dot_new identifier error
1964                 {yyerror ("'(' expected"); RECOVER;}
1965 ;
1966
1967 /* Created after JDK1.1 rules originally added to
1968    class_instance_creation_expression, but modified to use
1969    'class_type' instead of 'TypeName' (type_name) which is mentionned
1970    in the documentation but doesn't exist. */
1971
1972 anonymous_class_creation:
1973         NEW_TK class_type OP_TK argument_list CP_TK 
1974                 { create_anonymous_class ($1.location, $2); }
1975         class_body
1976                 { 
1977                   tree id = build_wfl_node (DECL_NAME (GET_CPC ()));
1978                   EXPR_WFL_LINECOL (id) = EXPR_WFL_LINECOL ($2);
1979
1980                   end_class_declaration (1);
1981
1982                   /* Now we can craft the new expression */
1983                   $$ = build_new_invocation (id, $4);
1984
1985                   /* Note that we can't possibly be here if
1986                      `class_type' is an interface (in which case the
1987                      anonymous class extends Object and implements
1988                      `class_type', hence its constructor can't have
1989                      arguments.) */
1990
1991                   /* Otherwise, the innerclass must feature a
1992                      constructor matching `argument_list'. Anonymous
1993                      classes are a bit special: it's impossible to
1994                      define constructor for them, hence constructors
1995                      must be generated following the hints provided by
1996                      the `new' expression. Whether a super constructor
1997                      of that nature exists or not is to be verified
1998                      later on in verify_constructor_super. 
1999
2000                      It's during the expansion of a `new' statement
2001                      refering to an anonymous class that a ctor will
2002                      be generated for the anonymous class, with the
2003                      right arguments. */
2004
2005                 }
2006 |       NEW_TK class_type OP_TK CP_TK 
2007                 { create_anonymous_class ($1.location, $2); }
2008         class_body         
2009                 { 
2010                   tree id = build_wfl_node (DECL_NAME (GET_CPC ()));
2011                   EXPR_WFL_LINECOL (id) = EXPR_WFL_LINECOL ($2);
2012
2013                   end_class_declaration (1);
2014
2015                   /* Now we can craft the new expression. The
2016                      statement doesn't need to be remember so that a
2017                      constructor can be generated, since its signature
2018                      is already known. */
2019                   $$ = build_new_invocation (id, NULL_TREE);
2020                 }
2021 ;
2022
2023 something_dot_new:              /* Added, not part of the specs. */
2024         name DOT_TK NEW_TK
2025                 { $$ = $1; }
2026 |       primary DOT_TK NEW_TK
2027                 { $$ = $1; }
2028 ;
2029
2030 argument_list:
2031         expression
2032                 { 
2033                   $$ = tree_cons (NULL_TREE, $1, NULL_TREE);
2034                   ctxp->formal_parameter_number = 1; 
2035                 }
2036 |       argument_list C_TK expression
2037                 {
2038                   ctxp->formal_parameter_number += 1;
2039                   $$ = tree_cons (NULL_TREE, $3, $1);
2040                 }
2041 |       argument_list C_TK error
2042                 {yyerror ("Missing term"); RECOVER;}
2043 ;
2044
2045 array_creation_expression:
2046         NEW_TK primitive_type dim_exprs
2047                 { $$ = build_newarray_node ($2, $3, 0); }
2048 |       NEW_TK class_or_interface_type dim_exprs
2049                 { $$ = build_newarray_node ($2, $3, 0); }
2050 |       NEW_TK primitive_type dim_exprs dims
2051                 { $$ = build_newarray_node ($2, $3, CURRENT_OSB (ctxp));}
2052 |       NEW_TK class_or_interface_type dim_exprs dims
2053                 { $$ = build_newarray_node ($2, $3, CURRENT_OSB (ctxp));}
2054         /* Added, JDK1.1 anonymous array. Initial documentation rule
2055            modified */
2056 |       NEW_TK class_or_interface_type dims array_initializer
2057                 {
2058                   char *sig;
2059                   while (CURRENT_OSB (ctxp)--)
2060                     obstack_1grow (&temporary_obstack, '[');
2061                   sig = obstack_finish (&temporary_obstack);
2062                   $$ = build (NEW_ANONYMOUS_ARRAY_EXPR, NULL_TREE,
2063                               $2, get_identifier (sig), $4);
2064                 }
2065 |       NEW_TK primitive_type dims array_initializer
2066                 { 
2067                   tree type = $2;
2068                   while (CURRENT_OSB (ctxp)--)
2069                     type = build_java_array_type (type, -1);
2070                   $$ = build (NEW_ANONYMOUS_ARRAY_EXPR, NULL_TREE, 
2071                               build_pointer_type (type), NULL_TREE, $4);
2072                 }
2073 |       NEW_TK error CSB_TK
2074                 {yyerror ("'[' expected"); DRECOVER ("]");}
2075 |       NEW_TK error OSB_TK
2076                 {yyerror ("']' expected"); RECOVER;}
2077 ;
2078
2079 dim_exprs:
2080         dim_expr
2081                 { $$ = build_tree_list (NULL_TREE, $1); }
2082 |       dim_exprs dim_expr
2083                 { $$ = tree_cons (NULL_TREE, $2, $$); }
2084 ;
2085
2086 dim_expr:
2087         OSB_TK expression CSB_TK
2088                 { 
2089                   if (JNUMERIC_TYPE_P (TREE_TYPE ($2)))
2090                     {
2091                       $2 = build_wfl_node ($2);
2092                       TREE_TYPE ($2) = NULL_TREE;
2093                     }
2094                   EXPR_WFL_LINECOL ($2) = $1.location;
2095                   $$ = $2;
2096                 }
2097 |       OSB_TK expression error
2098                 {yyerror ("']' expected"); RECOVER;}
2099 |       OSB_TK error
2100                 {
2101                   yyerror ("Missing term");
2102                   yyerror ("']' expected");
2103                   RECOVER;
2104                 }
2105 ;
2106
2107 dims:                           
2108         OSB_TK CSB_TK
2109                 { 
2110                   int allocate = 0;
2111                   /* If not initialized, allocate memory for the osb
2112                      numbers stack */
2113                   if (!ctxp->osb_limit)
2114                     {
2115                       allocate = ctxp->osb_limit = 32;
2116                       ctxp->osb_depth = -1;
2117                     }
2118                   /* If capacity overflown, reallocate a bigger chunk */
2119                   else if (ctxp->osb_depth+1 == ctxp->osb_limit)
2120                     allocate = ctxp->osb_limit << 1;
2121                   
2122                   if (allocate)
2123                     {
2124                       allocate *= sizeof (int);
2125                       if (ctxp->osb_number)
2126                         ctxp->osb_number = (int *)xrealloc (ctxp->osb_number,
2127                                                             allocate);
2128                       else
2129                         ctxp->osb_number = (int *)xmalloc (allocate);
2130                     }
2131                   ctxp->osb_depth++;
2132                   CURRENT_OSB (ctxp) = 1;
2133                 }
2134 |       dims OSB_TK CSB_TK
2135                 { CURRENT_OSB (ctxp)++; }
2136 |       dims OSB_TK error
2137                 { yyerror ("']' expected"); RECOVER;}
2138 ;
2139
2140 field_access:
2141         primary DOT_TK identifier
2142                 { $$ = make_qualified_primary ($1, $3, $2.location); }
2143                 /*  FIXME - REWRITE TO: 
2144                 { $$ = build_binop (COMPONENT_REF, $2.location, $1, $3); } */
2145 |       SUPER_TK DOT_TK identifier
2146                 {
2147                   tree super_wfl = 
2148                     build_wfl_node (super_identifier_node);
2149                   EXPR_WFL_LINECOL (super_wfl) = $1.location;
2150                   $$ = make_qualified_name (super_wfl, $3, $2.location);
2151                 }
2152 |       SUPER_TK error
2153                 {yyerror ("Field expected"); DRECOVER (super_field_acces);}
2154 ;
2155
2156 method_invocation:
2157         name OP_TK CP_TK
2158                 { $$ = build_method_invocation ($1, NULL_TREE); }
2159 |       name OP_TK argument_list CP_TK
2160                 { $$ = build_method_invocation ($1, $3); }
2161 |       primary DOT_TK identifier OP_TK CP_TK
2162                 { 
2163                   if (TREE_CODE ($1) == THIS_EXPR)
2164                     $$ = build_this_super_qualified_invocation 
2165                       (1, $3, NULL_TREE, 0, $2.location);
2166                   else
2167                     {
2168                       tree invok = build_method_invocation ($3, NULL_TREE);
2169                       $$ = make_qualified_primary ($1, invok, $2.location);
2170                     }
2171                 }
2172 |       primary DOT_TK identifier OP_TK argument_list CP_TK
2173                 { 
2174                   if (TREE_CODE ($1) == THIS_EXPR)
2175                     $$ = build_this_super_qualified_invocation 
2176                       (1, $3, $5, 0, $2.location);
2177                   else
2178                     {
2179                       tree invok = build_method_invocation ($3, $5);
2180                       $$ = make_qualified_primary ($1, invok, $2.location);
2181                     }
2182                 }
2183 |       SUPER_TK DOT_TK identifier OP_TK CP_TK
2184                 { 
2185                   $$ = build_this_super_qualified_invocation 
2186                     (0, $3, NULL_TREE, $1.location, $2.location);
2187                 }
2188 |       SUPER_TK DOT_TK identifier OP_TK argument_list CP_TK
2189                 {
2190                   $$ = build_this_super_qualified_invocation 
2191                     (0, $3, $5, $1.location, $2.location);
2192                 }
2193         /* Screws up thing. I let it here until I'm convinced it can
2194            be removed. FIXME
2195 |       primary DOT_TK error
2196                 {yyerror ("'(' expected"); DRECOVER(bad);} */
2197 |       SUPER_TK DOT_TK error CP_TK
2198                 { yyerror ("'(' expected"); DRECOVER (method_invocation); }
2199 |       SUPER_TK DOT_TK error DOT_TK
2200                 { yyerror ("'(' expected"); DRECOVER (method_invocation); }
2201 ;
2202
2203 array_access:
2204         name OSB_TK expression CSB_TK
2205                 { $$ = build_array_ref ($2.location, $1, $3); }
2206 |       primary_no_new_array OSB_TK expression CSB_TK
2207                 { $$ = build_array_ref ($2.location, $1, $3); }
2208 |       name OSB_TK error
2209                 {
2210                   yyerror ("Missing term and ']' expected");
2211                   DRECOVER(array_access);
2212                 }
2213 |       name OSB_TK expression error
2214                 {
2215                   yyerror ("']' expected");
2216                   DRECOVER(array_access);
2217                 }
2218 |       primary_no_new_array OSB_TK error
2219                 {
2220                   yyerror ("Missing term and ']' expected");
2221                   DRECOVER(array_access);
2222                 }
2223 |       primary_no_new_array OSB_TK expression error
2224                 {
2225                   yyerror ("']' expected");
2226                   DRECOVER(array_access);
2227                 }
2228 ;
2229
2230 postfix_expression:
2231         primary
2232 |       name
2233 |       post_increment_expression
2234 |       post_decrement_expression
2235 ;
2236
2237 post_increment_expression:
2238         postfix_expression INCR_TK
2239                 { $$ = build_incdec ($2.token, $2.location, $1, 1); }
2240 ;
2241
2242 post_decrement_expression:
2243         postfix_expression DECR_TK
2244                 { $$ = build_incdec ($2.token, $2.location, $1, 1); }
2245 ;
2246
2247 unary_expression:
2248         pre_increment_expression
2249 |       pre_decrement_expression
2250 |       PLUS_TK unary_expression
2251                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2252 |       MINUS_TK unary_expression
2253                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2254 |       unary_expression_not_plus_minus
2255 |       PLUS_TK error
2256                 {yyerror ("Missing term"); RECOVER}
2257 |       MINUS_TK error
2258                 {yyerror ("Missing term"); RECOVER}
2259 ;
2260
2261 pre_increment_expression:
2262         INCR_TK unary_expression
2263                 {$$ = build_incdec ($1.token, $1.location, $2, 0); }
2264 |       INCR_TK error
2265                 {yyerror ("Missing term"); RECOVER}
2266 ;
2267
2268 pre_decrement_expression:
2269         DECR_TK unary_expression
2270                 {$$ = build_incdec ($1.token, $1.location, $2, 0); }
2271 |       DECR_TK error
2272                 {yyerror ("Missing term"); RECOVER}
2273 ;
2274
2275 unary_expression_not_plus_minus:
2276         postfix_expression
2277 |       NOT_TK unary_expression
2278                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2279 |       NEG_TK unary_expression
2280                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2281 |       cast_expression
2282 |       NOT_TK error
2283                 {yyerror ("Missing term"); RECOVER}
2284 |       NEG_TK error
2285                 {yyerror ("Missing term"); RECOVER}
2286 ;
2287
2288 cast_expression:                /* Error handling here is potentially weak */
2289         OP_TK primitive_type dims CP_TK unary_expression
2290                 { 
2291                   tree type = $2;
2292                   while (CURRENT_OSB (ctxp)--)
2293                     type = build_java_array_type (type, -1);
2294                   ctxp->osb_depth--;
2295                   $$ = build_cast ($1.location, type, $5); 
2296                 }
2297 |       OP_TK primitive_type CP_TK unary_expression
2298                 { $$ = build_cast ($1.location, $2, $4); }
2299 |       OP_TK expression CP_TK unary_expression_not_plus_minus
2300                 { $$ = build_cast ($1.location, $2, $4); }
2301 |       OP_TK name dims CP_TK unary_expression_not_plus_minus
2302                 { 
2303                   const char *ptr;
2304                   while (CURRENT_OSB (ctxp)--)
2305                     obstack_1grow (&temporary_obstack, '[');
2306                   ctxp->osb_depth--;
2307                   obstack_grow0 (&temporary_obstack, 
2308                                  IDENTIFIER_POINTER (EXPR_WFL_NODE ($2)),
2309                                  IDENTIFIER_LENGTH (EXPR_WFL_NODE ($2)));
2310                   ptr = obstack_finish (&temporary_obstack);
2311                   EXPR_WFL_NODE ($2) = get_identifier (ptr);
2312                   $$ = build_cast ($1.location, $2, $5);
2313                 }
2314 |       OP_TK primitive_type OSB_TK error
2315                 {yyerror ("']' expected, invalid type expression");}
2316 |       OP_TK error
2317                 {
2318                   if (ctxp->prevent_ese != lineno)
2319                     yyerror ("Invalid type expression"); RECOVER;
2320                   RECOVER;
2321                 }
2322 |       OP_TK primitive_type dims CP_TK error
2323                 {yyerror ("Missing term"); RECOVER;}
2324 |       OP_TK primitive_type CP_TK error
2325                 {yyerror ("Missing term"); RECOVER;}
2326 |       OP_TK name dims CP_TK error
2327                 {yyerror ("Missing term"); RECOVER;}
2328 ;
2329
2330 multiplicative_expression:
2331         unary_expression
2332 |       multiplicative_expression MULT_TK unary_expression
2333                 { 
2334                   $$ = build_binop (BINOP_LOOKUP ($2.token), 
2335                                     $2.location, $1, $3);
2336                 }
2337 |       multiplicative_expression DIV_TK unary_expression
2338                 {
2339                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2340                                     $1, $3); 
2341                 }
2342 |       multiplicative_expression REM_TK unary_expression
2343                 {
2344                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2345                                     $1, $3); 
2346                 }
2347 |       multiplicative_expression MULT_TK error
2348                 {yyerror ("Missing term"); RECOVER;}
2349 |       multiplicative_expression DIV_TK error
2350                 {yyerror ("Missing term"); RECOVER;}
2351 |       multiplicative_expression REM_TK error
2352                 {yyerror ("Missing term"); RECOVER;}
2353 ;
2354
2355 additive_expression:
2356         multiplicative_expression
2357 |       additive_expression PLUS_TK multiplicative_expression
2358                 {
2359                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2360                                     $1, $3); 
2361                 }
2362 |       additive_expression MINUS_TK multiplicative_expression
2363                 {
2364                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2365                                     $1, $3); 
2366                 }
2367 |       additive_expression PLUS_TK error
2368                 {yyerror ("Missing term"); RECOVER;}
2369 |       additive_expression MINUS_TK error
2370                 {yyerror ("Missing term"); RECOVER;}
2371 ;
2372
2373 shift_expression:
2374         additive_expression
2375 |       shift_expression LS_TK additive_expression
2376                 {
2377                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2378                                     $1, $3); 
2379                 }
2380 |       shift_expression SRS_TK additive_expression
2381                 {
2382                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2383                                     $1, $3); 
2384                 }
2385 |       shift_expression ZRS_TK additive_expression
2386                 {
2387                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2388                                     $1, $3); 
2389                 }
2390 |       shift_expression LS_TK error
2391                 {yyerror ("Missing term"); RECOVER;}
2392 |       shift_expression SRS_TK error
2393                 {yyerror ("Missing term"); RECOVER;}
2394 |       shift_expression ZRS_TK error
2395                 {yyerror ("Missing term"); RECOVER;}
2396 ;
2397
2398 relational_expression:
2399         shift_expression
2400 |       relational_expression LT_TK shift_expression
2401                 {
2402                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2403                                     $1, $3); 
2404                 }
2405 |       relational_expression GT_TK shift_expression
2406                 {
2407                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2408                                     $1, $3); 
2409                 }
2410 |       relational_expression LTE_TK shift_expression
2411                 {
2412                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2413                                     $1, $3); 
2414                 }
2415 |       relational_expression GTE_TK shift_expression
2416                 {
2417                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2418                                     $1, $3); 
2419                 }
2420 |       relational_expression INSTANCEOF_TK reference_type
2421                 { $$ = build_binop (INSTANCEOF_EXPR, $2.location, $1, $3); }
2422 |       relational_expression LT_TK error
2423                 {yyerror ("Missing term"); RECOVER;}
2424 |       relational_expression GT_TK error
2425                 {yyerror ("Missing term"); RECOVER;}
2426 |       relational_expression LTE_TK error
2427                 {yyerror ("Missing term"); RECOVER;}
2428 |       relational_expression GTE_TK error
2429                 {yyerror ("Missing term"); RECOVER;}
2430 |       relational_expression INSTANCEOF_TK error
2431                 {yyerror ("Invalid reference type"); RECOVER;}
2432 ;
2433
2434 equality_expression:
2435         relational_expression
2436 |       equality_expression EQ_TK relational_expression
2437                 {
2438                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2439                                     $1, $3); 
2440                 }
2441 |       equality_expression NEQ_TK relational_expression
2442                 {
2443                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2444                                     $1, $3); 
2445                 }
2446 |       equality_expression EQ_TK error
2447                 {yyerror ("Missing term"); RECOVER;}
2448 |       equality_expression NEQ_TK error
2449                 {yyerror ("Missing term"); RECOVER;}
2450 ;
2451
2452 and_expression:
2453         equality_expression
2454 |       and_expression AND_TK equality_expression
2455                 {
2456                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2457                                     $1, $3); 
2458                 }
2459 |       and_expression AND_TK error
2460                 {yyerror ("Missing term"); RECOVER;}
2461 ;
2462
2463 exclusive_or_expression:
2464         and_expression
2465 |       exclusive_or_expression XOR_TK and_expression
2466                 {
2467                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2468                                     $1, $3); 
2469                 }
2470 |       exclusive_or_expression XOR_TK error
2471                 {yyerror ("Missing term"); RECOVER;}
2472 ;
2473
2474 inclusive_or_expression:
2475         exclusive_or_expression
2476 |       inclusive_or_expression OR_TK exclusive_or_expression
2477                 {
2478                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2479                                     $1, $3); 
2480                 }
2481 |       inclusive_or_expression OR_TK error
2482                 {yyerror ("Missing term"); RECOVER;}
2483 ;
2484
2485 conditional_and_expression:
2486         inclusive_or_expression
2487 |       conditional_and_expression BOOL_AND_TK inclusive_or_expression
2488                 {
2489                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2490                                     $1, $3); 
2491                 }
2492 |       conditional_and_expression BOOL_AND_TK error
2493                 {yyerror ("Missing term"); RECOVER;}
2494 ;
2495
2496 conditional_or_expression:
2497         conditional_and_expression
2498 |       conditional_or_expression BOOL_OR_TK conditional_and_expression
2499                 {
2500                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2501                                     $1, $3); 
2502                 }
2503 |       conditional_or_expression BOOL_OR_TK error
2504                 {yyerror ("Missing term"); RECOVER;}
2505 ;
2506
2507 conditional_expression:         /* Error handling here is weak */
2508         conditional_or_expression
2509 |       conditional_or_expression REL_QM_TK expression REL_CL_TK conditional_expression
2510                 {
2511                   $$ = build (CONDITIONAL_EXPR, NULL_TREE, $1, $3, $5);
2512                   EXPR_WFL_LINECOL ($$) = $2.location;
2513                 }
2514 |       conditional_or_expression REL_QM_TK REL_CL_TK error
2515                 {
2516                   YYERROR_NOW;
2517                   yyerror ("Missing term");
2518                   DRECOVER (1);
2519                 }
2520 |       conditional_or_expression REL_QM_TK error
2521                 {yyerror ("Missing term"); DRECOVER (2);}
2522 |       conditional_or_expression REL_QM_TK expression REL_CL_TK error
2523                 {yyerror ("Missing term"); DRECOVER (3);}
2524 ;
2525
2526 assignment_expression:
2527         conditional_expression
2528 |       assignment
2529 ;
2530
2531 assignment:
2532         left_hand_side assignment_operator assignment_expression
2533                 { $$ = build_assignment ($2.token, $2.location, $1, $3); }
2534 |       left_hand_side assignment_operator error
2535                 {
2536                   if (ctxp->prevent_ese != lineno)
2537                     yyerror ("Missing term");
2538                   DRECOVER (assign);
2539                 }
2540 ;
2541
2542 left_hand_side:
2543         name
2544 |       field_access
2545 |       array_access
2546 ;
2547
2548 assignment_operator:
2549         ASSIGN_ANY_TK
2550 |       ASSIGN_TK
2551 ;
2552
2553 expression:
2554         assignment_expression
2555 ;
2556
2557 constant_expression:
2558         expression
2559 ;
2560
2561 %%
2562 \f
2563
2564 /* This section of the code deal with save/restoring parser contexts.
2565    Add mode documentation here. FIXME */
2566
2567 /* Helper function. Create a new parser context. With
2568    COPY_FROM_PREVIOUS set to a non zero value, content of the previous
2569    context is copied, otherwise, the new context is zeroed. The newly
2570    created context becomes the current one.  */
2571
2572 static void
2573 create_new_parser_context (copy_from_previous)
2574     int copy_from_previous;
2575 {
2576   struct parser_ctxt *new;
2577
2578   new =  (struct parser_ctxt *)xmalloc(sizeof (struct parser_ctxt));
2579   if (copy_from_previous)
2580     {
2581       memcpy ((PTR)new, (PTR)ctxp, sizeof (struct parser_ctxt));
2582       new->saved_data_ctx = 1;
2583     }
2584   else
2585     bzero ((PTR) new, sizeof (struct parser_ctxt));
2586       
2587   new->next = ctxp;
2588   ctxp = new;
2589 }
2590
2591 /* Create a new parser context and make it the current one. */
2592
2593 void
2594 java_push_parser_context ()
2595 {
2596   create_new_parser_context (0);
2597   if (ctxp->next)
2598     {
2599       ctxp->incomplete_class = ctxp->next->incomplete_class;
2600       ctxp->gclass_list = ctxp->next->gclass_list;
2601     }
2602 }  
2603
2604 void 
2605 java_pop_parser_context (generate)
2606      int generate;
2607 {
2608   tree current;
2609   struct parser_ctxt *toFree, *next;
2610
2611   if (!ctxp)
2612     return;
2613
2614   toFree = ctxp;
2615   next = ctxp->next;
2616   if (next)
2617     {
2618       next->incomplete_class = ctxp->incomplete_class;
2619       next->gclass_list = ctxp->gclass_list;
2620       lineno = ctxp->lineno;
2621       finput = ctxp->finput;
2622       current_class = ctxp->current_class;
2623     }
2624
2625   /* Set the single import class file flag to 0 for the current list
2626      of imported things */
2627   for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
2628     IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_PURPOSE (current)) = 0;
2629
2630   /* And restore those of the previous context */
2631   if ((ctxp = next))            /* Assignment is really meant here */
2632     for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
2633       IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_PURPOSE (current)) = 1;
2634   
2635   /* If we pushed a context to parse a class intended to be generated,
2636      we keep it so we can remember the class. What we could actually
2637      do is to just update a list of class names.  */
2638   if (generate)
2639     {
2640       toFree->next = ctxp_for_generation;
2641       ctxp_for_generation = toFree;
2642     }
2643   else
2644     free (toFree);
2645 }
2646
2647 /* Create a parser context for the use of saving some global
2648    variables.  */
2649
2650 void
2651 java_parser_context_save_global ()
2652 {
2653   if (!ctxp)
2654     {
2655       java_push_parser_context ();
2656       ctxp->saved_data_ctx = 1;
2657     }
2658
2659   /* If this context already stores data, create a new one suitable
2660      for data storage. */
2661   else if (ctxp->saved_data)
2662     create_new_parser_context (1);
2663
2664   ctxp->finput = finput;
2665   ctxp->lineno = lineno;
2666   ctxp->current_class = current_class;
2667   ctxp->filename = input_filename;
2668   ctxp->current_function_decl = current_function_decl;
2669   ctxp->saved_data = 1;
2670 }
2671
2672 /* Restore some global variables from the previous context. Make the
2673    previous context the current one.  */
2674
2675 void
2676 java_parser_context_restore_global ()
2677 {
2678   finput = ctxp->finput;
2679   lineno = ctxp->lineno;
2680   current_class = ctxp->current_class;
2681   input_filename = ctxp->filename;
2682   current_function_decl = ctxp->current_function_decl;
2683   ctxp->saved_data = 0;
2684   if (ctxp->saved_data_ctx)
2685     java_pop_parser_context (0);
2686 }
2687
2688 /* Suspend vital data for the current class/function being parsed so
2689    that an other class can be parsed. Used to let local/anonymous
2690    classes be parsed.  */
2691
2692 static void
2693 java_parser_context_suspend ()
2694 {
2695   /* This makes debugging through java_debug_context easier */
2696   static const char *name = "<inner buffer context>";
2697
2698   /* Duplicate the previous context, use it to save the globals we're
2699      interested in */
2700   create_new_parser_context (1);
2701   ctxp->current_function_decl = current_function_decl;
2702   ctxp->current_class = current_class;
2703
2704   /* Then create a new context which inherits all data from the
2705      previous one. This will be the new current context  */
2706   create_new_parser_context (1);
2707
2708   /* Help debugging */
2709   ctxp->next->filename = name;
2710 }
2711
2712 /* Resume vital data for the current class/function being parsed so
2713    that an other class can be parsed. Used to let local/anonymous
2714    classes be parsed.  The trick is the data storing file position
2715    informations must be restored to their current value, so parsing
2716    can resume as if no context was ever saved. */
2717
2718 static void
2719 java_parser_context_resume ()
2720 {
2721   struct parser_ctxt *old = ctxp;             /* This one is to be discarded */
2722   struct parser_ctxt *saver = old->next;      /* This one contain saved info */
2723   struct parser_ctxt *restored = saver->next; /* This one is the old current */
2724
2725   /* We need to inherit the list of classes to complete/generate */
2726   restored->incomplete_class = old->incomplete_class;
2727   restored->gclass_list = old->gclass_list;
2728   restored->classd_list = old->classd_list;
2729   restored->class_list = old->class_list;
2730
2731   /* Restore the current class and function from the saver */
2732   current_class = saver->current_class;
2733   current_function_decl = saver->current_function_decl;
2734
2735   /* Retrive the restored context */
2736   ctxp = restored;
2737
2738   /* Re-installed the data for the parsing to carry on */
2739   bcopy (&old->marker_begining, &ctxp->marker_begining,
2740          (size_t)(&ctxp->marker_end - &ctxp->marker_begining));
2741
2742   /* Buffer context can now be discarded */
2743   free (saver);
2744   free (old);
2745 }
2746
2747 /* Add a new anchor node to which all statement(s) initializing static
2748    and non static initialized upon declaration field(s) will be
2749    linked.  */
2750
2751 static void
2752 java_parser_context_push_initialized_field ()
2753 {
2754   tree node;
2755
2756   node = build_tree_list (NULL_TREE, NULL_TREE);
2757   TREE_CHAIN (node) = CPC_STATIC_INITIALIZER_LIST (ctxp);
2758   CPC_STATIC_INITIALIZER_LIST (ctxp) = node;
2759
2760   node = build_tree_list (NULL_TREE, NULL_TREE);
2761   TREE_CHAIN (node) = CPC_INITIALIZER_LIST (ctxp);
2762   CPC_INITIALIZER_LIST (ctxp) = node;
2763
2764   node = build_tree_list (NULL_TREE, NULL_TREE);
2765   TREE_CHAIN (node) = CPC_INSTANCE_INITIALIZER_LIST (ctxp);
2766   CPC_INSTANCE_INITIALIZER_LIST (ctxp) = node;
2767 }
2768
2769 /* Pop the lists of initialized field. If this lists aren't empty,
2770    remember them so we can use it to create and populate the $finit$
2771    or <clinit> functions. */
2772
2773 static void
2774 java_parser_context_pop_initialized_field ()
2775 {
2776   tree stmts;
2777   tree class_type = TREE_TYPE (GET_CPC ());
2778
2779   if (CPC_INITIALIZER_LIST (ctxp))
2780     {
2781       stmts = CPC_INITIALIZER_STMT (ctxp);
2782       CPC_INITIALIZER_LIST (ctxp) = TREE_CHAIN (CPC_INITIALIZER_LIST (ctxp));
2783       if (stmts && !java_error_count)
2784         TYPE_FINIT_STMT_LIST (class_type) = reorder_static_initialized (stmts);
2785     }
2786
2787   if (CPC_STATIC_INITIALIZER_LIST (ctxp))
2788     {
2789       stmts = CPC_STATIC_INITIALIZER_STMT (ctxp);
2790       CPC_STATIC_INITIALIZER_LIST (ctxp) = 
2791         TREE_CHAIN (CPC_STATIC_INITIALIZER_LIST (ctxp));
2792       /* Keep initialization in order to enforce 8.5 */
2793       if (stmts && !java_error_count)
2794         TYPE_CLINIT_STMT_LIST (class_type) = nreverse (stmts);
2795     }
2796
2797   /* JDK 1.1 instance initializers */
2798   if (CPC_INSTANCE_INITIALIZER_LIST (ctxp))
2799     {
2800       stmts = CPC_INSTANCE_INITIALIZER_STMT (ctxp);
2801       CPC_INSTANCE_INITIALIZER_LIST (ctxp) = 
2802         TREE_CHAIN (CPC_INSTANCE_INITIALIZER_LIST (ctxp));
2803       if (stmts && !java_error_count)
2804         TYPE_II_STMT_LIST (class_type) = nreverse (stmts);
2805     }
2806 }
2807
2808 static tree
2809 reorder_static_initialized (list)
2810      tree list;
2811 {
2812   /* We have to keep things in order. The alias initializer have to
2813      come first, then the initialized regular field, in reverse to
2814      keep them in lexical order. */
2815   tree marker, previous = NULL_TREE;
2816   for (marker = list; marker; previous = marker, marker = TREE_CHAIN (marker))
2817     if (TREE_CODE (marker) == TREE_LIST 
2818         && !TREE_VALUE (marker) && !TREE_PURPOSE (marker))
2819       break;
2820   
2821   /* No static initialized, the list is fine as is */
2822   if (!previous)
2823     list = TREE_CHAIN (marker);
2824
2825   /* No marker? reverse the whole list */
2826   else if (!marker)
2827     list = nreverse (list);
2828
2829   /* Otherwise, reverse what's after the marker and the new reordered
2830      sublist will replace the marker. */
2831   else
2832     {
2833       TREE_CHAIN (previous) = NULL_TREE;
2834       list = nreverse (list);
2835       list = chainon (TREE_CHAIN (marker), list);
2836     }
2837   return list;
2838 }
2839
2840 /* Helper functions to dump the parser context stack.  */
2841
2842 #define TAB_CONTEXT(C) \
2843   {int i; for (i = 0; i < (C); i++) fputc (' ', stderr);}
2844
2845 static void
2846 java_debug_context_do (tab)
2847      int tab;
2848 {
2849   struct parser_ctxt *copy = ctxp;
2850   while (copy)
2851     {
2852       TAB_CONTEXT (tab);
2853       fprintf (stderr, "ctxt: 0x%0lX\n", (unsigned long)copy);
2854       TAB_CONTEXT (tab);
2855       fprintf (stderr, "filename: %s\n", copy->filename);
2856       TAB_CONTEXT (tab);
2857       fprintf (stderr, "lineno: %d\n", copy->lineno);
2858       TAB_CONTEXT (tab);
2859       fprintf (stderr, "package: %s\n",
2860                (copy->package ? 
2861                 IDENTIFIER_POINTER (copy->package) : "<none>"));
2862       TAB_CONTEXT (tab);
2863       fprintf (stderr, "context for saving: %d\n", copy->saved_data_ctx);
2864       TAB_CONTEXT (tab);
2865       fprintf (stderr, "saved data: %d\n", copy->saved_data);
2866       copy = copy->next;
2867       tab += 2;
2868     }
2869 }
2870
2871 /* Dump the stacked up parser contexts. Intended to be called from a
2872    debugger.  */
2873
2874 void
2875 java_debug_context ()
2876 {
2877   java_debug_context_do (0);
2878 }
2879
2880 \f
2881
2882 /* Flag for the error report routine to issue the error the first time
2883    it's called (overriding the default behavior which is to drop the
2884    first invocation and honor the second one, taking advantage of a
2885    richer context.  */
2886 static int force_error = 0;
2887
2888 /* Reporting an constructor invocation error.  */
2889 static void
2890 parse_ctor_invocation_error ()
2891 {
2892   if (DECL_CONSTRUCTOR_P (current_function_decl))
2893     yyerror ("Constructor invocation must be first thing in a constructor"); 
2894   else
2895     yyerror ("Only constructors can invoke constructors");
2896 }
2897
2898 /* Reporting JDK1.1 features not implemented.  */
2899
2900 static tree
2901 parse_jdk1_1_error (msg)
2902     const char *msg;
2903 {
2904   sorry (": `%s' JDK1.1(TM) feature", msg);
2905   java_error_count++;
2906   return empty_stmt_node;
2907 }
2908
2909 static int do_warning = 0;
2910
2911 void
2912 yyerror (msg)
2913      const char *msg;
2914 {
2915   static java_lc elc;
2916   static int  prev_lineno;
2917   static const char *prev_msg;
2918
2919   int save_lineno;
2920   char *remainder, *code_from_source;
2921   extern struct obstack temporary_obstack;
2922   
2923   if (!force_error && prev_lineno == lineno)
2924     return;
2925
2926   /* Save current error location but report latter, when the context is
2927      richer.  */
2928   if (ctxp->java_error_flag == 0)
2929     {
2930       ctxp->java_error_flag = 1;
2931       elc = ctxp->elc;
2932       /* Do something to use the previous line if we're reaching the
2933          end of the file... */
2934 #ifdef VERBOSE_SKELETON
2935       printf ("* Error detected (%s)\n", (msg ? msg : "(null)"));
2936 #endif
2937       return;
2938     }
2939
2940   /* Ignore duplicate message on the same line. BTW, this is dubious. FIXME */
2941   if (!force_error && msg == prev_msg && prev_lineno == elc.line)
2942     return;
2943
2944   ctxp->java_error_flag = 0;
2945   if (do_warning)
2946     java_warning_count++;
2947   else
2948     java_error_count++;
2949   
2950   if (elc.col == 0 && msg && msg[1] == ';')
2951     {
2952       elc.col  = ctxp->p_line->char_col-1;
2953       elc.line = ctxp->p_line->lineno;
2954     }
2955
2956   save_lineno = lineno;
2957   prev_lineno = lineno = elc.line;
2958   prev_msg = msg;
2959
2960   code_from_source = java_get_line_col (ctxp->filename, elc.line, elc.col);
2961   obstack_grow0 (&temporary_obstack, 
2962                  code_from_source, strlen (code_from_source));
2963   remainder = obstack_finish (&temporary_obstack);
2964   if (do_warning)
2965     warning ("%s.\n%s", msg, remainder);
2966   else
2967     error ("%s.\n%s", msg, remainder);
2968
2969   /* This allow us to cheaply avoid an extra 'Invalid expression
2970      statement' error report when errors have been already reported on
2971      the same line. This occurs when we report an error but don't have
2972      a synchronization point other than ';', which
2973      expression_statement is the only one to take care of.  */
2974   ctxp->prevent_ese = lineno = save_lineno;
2975 }
2976
2977 static void
2978 issue_warning_error_from_context (cl, msg, ap)
2979      tree cl;
2980      const char *msg;
2981      va_list ap;
2982 {
2983   const char *saved, *saved_input_filename;
2984   char buffer [4096];
2985   vsprintf (buffer, msg, ap);
2986   force_error = 1;
2987
2988   ctxp->elc.line = EXPR_WFL_LINENO (cl);
2989   ctxp->elc.col  = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 : 
2990                     (EXPR_WFL_COLNO (cl) == 0xffe ? -2 : EXPR_WFL_COLNO (cl)));
2991
2992   /* We have a CL, that's a good reason for using it if it contains data */
2993   saved = ctxp->filename;
2994   if (TREE_CODE (cl) == EXPR_WITH_FILE_LOCATION && EXPR_WFL_FILENAME_NODE (cl))
2995     ctxp->filename = EXPR_WFL_FILENAME (cl);
2996   saved_input_filename = input_filename;
2997   input_filename = ctxp->filename;
2998   java_error (NULL);
2999   java_error (buffer);
3000   ctxp->filename = saved;
3001   input_filename = saved_input_filename;
3002   force_error = 0;
3003 }
3004
3005 /* Issue an error message at a current source line CL */
3006
3007 void
3008 parse_error_context VPARAMS ((tree cl, const char *msg, ...))
3009 {
3010 #ifndef ANSI_PROTOTYPES
3011   tree cl;
3012   const char *msg;
3013 #endif
3014   va_list ap;
3015
3016   VA_START (ap, msg);
3017 #ifndef ANSI_PROTOTYPES
3018   cl = va_arg (ap, tree);
3019   msg = va_arg (ap, const char *);
3020 #endif
3021   issue_warning_error_from_context (cl, msg, ap);
3022   va_end (ap);
3023 }
3024
3025 /* Issue a warning at a current source line CL */
3026
3027 static void
3028 parse_warning_context VPARAMS ((tree cl, const char *msg, ...))
3029 {
3030 #ifndef ANSI_PROTOTYPES
3031   tree cl;
3032   const char *msg;
3033 #endif
3034   va_list ap;
3035
3036   VA_START (ap, msg);
3037 #ifndef ANSI_PROTOTYPES
3038   cl = va_arg (ap, tree);
3039   msg = va_arg (ap, const char *);
3040 #endif
3041
3042   force_error = do_warning = 1;
3043   issue_warning_error_from_context (cl, msg, ap);
3044   do_warning = force_error = 0;
3045   va_end (ap);
3046 }
3047
3048 static tree
3049 find_expr_with_wfl (node)
3050      tree node;
3051 {
3052   while (node)
3053     {
3054       char code;
3055       tree to_return;
3056
3057       switch (TREE_CODE (node))
3058         {
3059         case BLOCK:
3060           node = BLOCK_EXPR_BODY (node);
3061           continue;
3062
3063         case COMPOUND_EXPR:
3064           to_return = find_expr_with_wfl (TREE_OPERAND (node, 0));
3065           if (to_return)
3066             return to_return;
3067           node = TREE_OPERAND (node, 1);
3068           continue;
3069
3070         case LOOP_EXPR:
3071           node = TREE_OPERAND (node, 0);
3072           continue;
3073           
3074         case LABELED_BLOCK_EXPR:
3075           node = TREE_OPERAND (node, 1);
3076           continue;
3077
3078         default:
3079           code = TREE_CODE_CLASS (TREE_CODE (node));
3080           if (((code == '1') || (code == '2') || (code == 'e'))
3081               && EXPR_WFL_LINECOL (node))
3082             return node;
3083           return NULL_TREE;
3084         }
3085     }
3086   return NULL_TREE;
3087 }
3088
3089 /* Issue a missing return statement error. Uses METHOD to figure the
3090    last line of the method the error occurs in.  */
3091
3092 static void
3093 missing_return_error (method)
3094      tree method;
3095 {
3096   EXPR_WFL_SET_LINECOL (wfl_operator, DECL_SOURCE_LINE_LAST (method), -2);
3097   parse_error_context (wfl_operator, "Missing return statement");
3098 }
3099
3100 /* Issue an unreachable statement error. From NODE, find the next
3101    statement to report appropriately.  */
3102 static void
3103 unreachable_stmt_error (node)
3104      tree node;
3105 {
3106   /* Browse node to find the next expression node that has a WFL. Use
3107      the location to report the error */
3108   if (TREE_CODE (node) == COMPOUND_EXPR)
3109     node = find_expr_with_wfl (TREE_OPERAND (node, 1));
3110   else
3111     node = find_expr_with_wfl (node);
3112
3113   if (node)
3114     {
3115       EXPR_WFL_SET_LINECOL (wfl_operator, EXPR_WFL_LINENO (node), -2);
3116       parse_error_context (wfl_operator, "Unreachable statement");
3117     }
3118   else
3119     fatal ("Can't get valid statement - unreachable_stmt_error");
3120 }
3121
3122 int
3123 java_report_errors ()
3124 {
3125   if (java_error_count)
3126     fprintf (stderr, "%d error%s", 
3127              java_error_count, (java_error_count == 1 ? "" : "s"));
3128   if (java_warning_count)
3129     fprintf (stderr, "%s%d warning%s", (java_error_count ? ", " : ""),
3130              java_warning_count, (java_warning_count == 1 ? "" : "s"));
3131   if (java_error_count || java_warning_count)
3132     putc ('\n', stderr);
3133   return java_error_count;
3134 }
3135
3136 static char *
3137 java_accstring_lookup (flags)
3138      int flags;
3139 {
3140   static char buffer [80];
3141 #define COPY_RETURN(S) {strcpy (buffer, S); return buffer;}
3142
3143   /* Access modifier looked-up first for easier report on forbidden
3144      access. */
3145   if (flags & ACC_PUBLIC) COPY_RETURN ("public");
3146   if (flags & ACC_PRIVATE) COPY_RETURN ("private");
3147   if (flags & ACC_PROTECTED) COPY_RETURN ("protected");
3148   if (flags & ACC_STATIC) COPY_RETURN ("static");
3149   if (flags & ACC_FINAL) COPY_RETURN ("final");
3150   if (flags & ACC_SYNCHRONIZED) COPY_RETURN ("synchronized");
3151   if (flags & ACC_VOLATILE) COPY_RETURN ("volatile");
3152   if (flags & ACC_TRANSIENT) COPY_RETURN ("transient");
3153   if (flags & ACC_NATIVE) COPY_RETURN ("native");
3154   if (flags & ACC_INTERFACE) COPY_RETURN ("interface");
3155   if (flags & ACC_ABSTRACT) COPY_RETURN ("abstract");
3156
3157   buffer [0] = '\0';
3158   return buffer;
3159 #undef COPY_RETURN
3160 }
3161
3162 /* Issuing error messages upon redefinition of classes, interfaces or
3163    variables. */
3164
3165 static void
3166 classitf_redefinition_error (context, id, decl, cl)
3167      const char *context;
3168      tree id, decl, cl;
3169 {
3170   parse_error_context (cl, "%s `%s' already defined in %s:%d", 
3171                        context, IDENTIFIER_POINTER (id), 
3172                        DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
3173   /* Here we should point out where its redefined. It's a unicode. FIXME */
3174 }
3175
3176 static void
3177 variable_redefinition_error (context, name, type, line)
3178      tree context, name, type;
3179      int line;
3180 {
3181   const char *type_name;
3182
3183   /* Figure a proper name for type. We might haven't resolved it */
3184   if (TREE_CODE (type) == POINTER_TYPE && !TREE_TYPE (type))
3185     type_name = IDENTIFIER_POINTER (TYPE_NAME (type));
3186   else
3187     type_name = lang_printable_name (type, 0);
3188
3189   parse_error_context (context,
3190                        "Variable `%s' is already defined in this method and was declared `%s %s' at line %d", 
3191                        IDENTIFIER_POINTER (name),
3192                        type_name, IDENTIFIER_POINTER (name), line);
3193 }
3194
3195 static tree
3196 build_array_from_name (type, type_wfl, name, ret_name)
3197      tree type, type_wfl, name, *ret_name;
3198 {
3199   int more_dims = 0;
3200   const char *string;
3201
3202   /* Eventually get more dims */
3203   string = IDENTIFIER_POINTER (name);
3204   while (string [more_dims] == '[')
3205     more_dims++;
3206   
3207   /* If we have, then craft a new type for this variable */
3208   if (more_dims)
3209     {
3210       name = get_identifier (&string [more_dims]);
3211
3212       /* If we have a pointer, use its type */
3213       if (TREE_CODE (type) == POINTER_TYPE)
3214         type = TREE_TYPE (type);
3215
3216       /* Building the first dimension of a primitive type uses this
3217          function */
3218       if (JPRIMITIVE_TYPE_P (type))
3219         {
3220           type = build_java_array_type (type, -1);
3221           CLASS_LOADED_P (type) = 1;
3222           more_dims--;
3223         }
3224       /* Otherwise, if we have a WFL for this type, use it (the type
3225          is already an array on an unresolved type, and we just keep
3226          on adding dimensions) */
3227       else if (type_wfl)
3228         type = type_wfl;
3229
3230       /* Add all the dimensions */
3231       while (more_dims--)
3232         type = build_unresolved_array_type (type);
3233
3234       /* The type may have been incomplete in the first place */
3235       if (type_wfl)
3236         type = obtain_incomplete_type (type);
3237     }
3238
3239   if (ret_name)
3240     *ret_name = name;
3241   return type;
3242 }
3243
3244 /* Build something that the type identifier resolver will identify as
3245    being an array to an unresolved type. TYPE_WFL is a WFL on a
3246    identifier. */
3247
3248 static tree
3249 build_unresolved_array_type (type_or_wfl)
3250      tree type_or_wfl;
3251 {
3252   const char *ptr;
3253
3254   /* TYPE_OR_WFL might be an array on a resolved type. In this case,
3255      just create a array type */
3256   if (TREE_CODE (type_or_wfl) == RECORD_TYPE)
3257     {
3258       tree type = build_java_array_type (type_or_wfl, -1);
3259       CLASS_LOADED_P (type) = CLASS_LOADED_P (type_or_wfl);
3260       return type;
3261     }
3262
3263   obstack_1grow (&temporary_obstack, '[');
3264   obstack_grow0 (&temporary_obstack,
3265                  IDENTIFIER_POINTER (EXPR_WFL_NODE (type_or_wfl)),
3266                  IDENTIFIER_LENGTH (EXPR_WFL_NODE (type_or_wfl)));
3267   ptr = obstack_finish (&temporary_obstack);
3268   return build_expr_wfl (get_identifier (ptr),
3269                          EXPR_WFL_FILENAME (type_or_wfl),
3270                          EXPR_WFL_LINENO (type_or_wfl),
3271                          EXPR_WFL_COLNO (type_or_wfl));
3272 }
3273
3274 static void
3275 parser_add_interface (class_decl, interface_decl, wfl)
3276      tree class_decl, interface_decl, wfl;
3277 {
3278   if (maybe_add_interface (TREE_TYPE (class_decl), TREE_TYPE (interface_decl)))
3279     parse_error_context (wfl, "Interface `%s' repeated",
3280                          IDENTIFIER_POINTER (DECL_NAME (interface_decl)));
3281 }
3282
3283 /* Bulk of common class/interface checks. Return 1 if an error was
3284    encountered. TAG is 0 for a class, 1 for an interface.  */
3285
3286 static int
3287 check_class_interface_creation (is_interface, flags, raw_name, qualified_name, decl, cl)
3288      int is_interface, flags;
3289      tree raw_name, qualified_name, decl, cl;
3290 {
3291   tree node;
3292   int sca = 0;                  /* Static class allowed */
3293   int icaf = 0;                 /* Inner class allowed flags */
3294   int uaaf = CLASS_MODIFIERS;   /* Usually allowed access flags */
3295
3296   if (!quiet_flag)
3297     fprintf (stderr, " %s%s %s", 
3298              (CPC_INNER_P () ? "inner" : ""),
3299              (is_interface ? "interface" : "class"), 
3300              IDENTIFIER_POINTER (qualified_name));
3301
3302   /* Scope of an interface/class type name:
3303        - Can't be imported by a single type import
3304        - Can't already exists in the package */
3305   if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (raw_name)
3306       && (node = find_name_in_single_imports (raw_name)))
3307     {
3308       parse_error_context 
3309         (cl, "%s name `%s' clashes with imported type `%s'",
3310          (is_interface ? "Interface" : "Class"),
3311          IDENTIFIER_POINTER (raw_name), IDENTIFIER_POINTER (node));
3312       return 1;
3313     }
3314   if (decl && CLASS_COMPLETE_P (decl))
3315     {
3316       classitf_redefinition_error ((is_interface ? "Interface" : "Class"), 
3317                                    qualified_name, decl, cl);
3318       return 1;
3319     }
3320
3321   if (check_inner_class_redefinition (raw_name, cl))
3322     return 1;
3323
3324   /* If public, file name should match class/interface name, except
3325      when dealing with an inner class */
3326   if (!CPC_INNER_P () && (flags & ACC_PUBLIC ))
3327     {
3328       const char *f;
3329
3330       /* Contains OS dependent assumption on path separator. FIXME */
3331       for (f = &input_filename [strlen (input_filename)]; 
3332            f != input_filename && f[0] != '/' && f[0] != DIR_SEPARATOR;
3333            f--)
3334         ;
3335       if (f[0] == '/' || f[0] == DIR_SEPARATOR)
3336         f++;
3337       if (strncmp (IDENTIFIER_POINTER (raw_name), 
3338                    f , IDENTIFIER_LENGTH (raw_name)) ||
3339           f [IDENTIFIER_LENGTH (raw_name)] != '.')
3340         parse_error_context
3341           (cl, "Public %s `%s' must be defined in a file called `%s.java'", 
3342                              (is_interface ? "interface" : "class"),
3343                              IDENTIFIER_POINTER (qualified_name),
3344                              IDENTIFIER_POINTER (raw_name));
3345     }
3346
3347   /* Static classes can be declared only in top level classes. Note:
3348      once static, a inner class is a top level class. */
3349   if (flags & ACC_STATIC)
3350     {
3351       /* Catch the specific error of declaring an class inner class
3352          with no toplevel enclosing class. Prevent check_modifiers from
3353          complaining a second time */
3354       if (CPC_INNER_P () && !TOPLEVEL_CLASS_DECL_P (GET_CPC()))
3355         {
3356           parse_error_context (cl, "Inner class `%s' can't be static. Static classes can only occur in interfaces and top-level classes", 
3357                                IDENTIFIER_POINTER (qualified_name));
3358           sca = ACC_STATIC;
3359         }
3360       /* Else, in the context of a top-level class declaration, let
3361          `check_modifiers' do its job, otherwise, give it a go */
3362       else
3363         sca = (GET_CPC_LIST () ? ACC_STATIC : 0);
3364     }
3365
3366   /* Inner classes can be declared private or protected
3367      within their enclosing classes. */
3368   if (CPC_INNER_P ())
3369     {
3370       /* A class which is local to a block can't be public, private,
3371          protected or static. But it is created final, so allow this
3372          one. */
3373       if (current_function_decl)
3374         icaf = sca = uaaf = ACC_FINAL;
3375       else
3376         {
3377           check_modifiers_consistency (flags);
3378           icaf = ACC_PRIVATE|ACC_PROTECTED;
3379         }
3380     }
3381
3382   if (is_interface) 
3383     {
3384       if (CPC_INNER_P ())
3385         uaaf = INTERFACE_INNER_MODIFIERS;
3386       else
3387         uaaf = INTERFACE_MODIFIERS;
3388       
3389       check_modifiers ("Illegal modifier `%s' for interface declaration", 
3390                        flags, uaaf);
3391     }
3392   else
3393     check_modifiers ((current_function_decl ?
3394                       "Illegal modifier `%s' for local class declaration" :
3395                       "Illegal modifier `%s' for class declaration"),
3396                      flags, uaaf|sca|icaf);
3397   return 0;
3398 }
3399
3400 static void
3401 make_nested_class_name (cpc_list)
3402      tree cpc_list;
3403 {
3404   tree name;
3405
3406   if (!cpc_list)
3407     return;
3408   else
3409     make_nested_class_name (TREE_CHAIN (cpc_list));
3410
3411   /* Pick the qualified name when dealing with the first upmost
3412      enclosing class */
3413   name = (TREE_CHAIN (cpc_list) ? 
3414           TREE_PURPOSE (cpc_list) : DECL_NAME (TREE_VALUE (cpc_list)));
3415   obstack_grow (&temporary_obstack,
3416                 IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name));
3417   /* Why is NO_DOLLAR_IN_LABEL defined? */
3418 #if 0
3419 #ifdef NO_DOLLAR_IN_LABEL
3420   fatal ("make_nested_class_name: Can't use '$' as a separator "
3421          "for inner classes");
3422 #endif
3423 #endif
3424   obstack_1grow (&temporary_obstack, '$');
3425 }
3426
3427 /* Can't redefine a class already defined in an earlier scope. */
3428
3429 static int
3430 check_inner_class_redefinition (raw_name, cl)
3431      tree raw_name, cl;
3432 {
3433   tree scope_list;
3434
3435   for (scope_list = GET_CPC_LIST (); scope_list; 
3436        scope_list = GET_NEXT_ENCLOSING_CPC (scope_list))
3437     if (raw_name == GET_CPC_UN_NODE (scope_list))
3438       {
3439         parse_error_context 
3440           (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",
3441            IDENTIFIER_POINTER (raw_name));
3442         return 1;
3443       }
3444   return 0;
3445 }
3446
3447 static tree
3448 find_as_inner_class (enclosing, name, cl)
3449      tree enclosing, name, cl;
3450 {
3451   tree qual, to_return;
3452   if (!enclosing)
3453     return NULL_TREE;
3454
3455   name = TYPE_NAME (name);
3456
3457   /* First search: within the scope of `enclosing', search for name */
3458   if (QUALIFIED_P (name) && cl && EXPR_WFL_NODE (cl) == name)
3459     qual = EXPR_WFL_QUALIFICATION (cl);
3460   else if (cl)
3461     qual = build_tree_list (cl, NULL_TREE);
3462   else
3463     qual = build_tree_list (build_expr_wfl (name, NULL, 0, 0), NULL_TREE);
3464   
3465   if ((to_return = find_as_inner_class_do (qual, enclosing)))
3466     return to_return;
3467
3468   /* We're dealing with a qualified name. Try to resolve thing until
3469      we get something that is an enclosing class. */
3470   if (QUALIFIED_P (name) && cl && EXPR_WFL_NODE (cl) == name)
3471     {
3472       tree acc = NULL_TREE, decl = NULL_TREE, ptr;
3473
3474       for(qual = EXPR_WFL_QUALIFICATION (cl); qual && !decl; 
3475           qual = TREE_CHAIN (qual))
3476         {
3477           acc = merge_qualified_name (acc, 
3478                                       EXPR_WFL_NODE (TREE_PURPOSE (qual)));
3479           BUILD_PTR_FROM_NAME (ptr, acc);
3480           decl = do_resolve_class (NULL_TREE, ptr, NULL_TREE, cl);
3481         }
3482
3483       /* A NULL qual and a decl means that the search ended
3484          successfully?!? We have to do something then. FIXME */
3485       
3486       if (decl)
3487         enclosing = decl;
3488       else
3489         qual = EXPR_WFL_QUALIFICATION (cl);
3490     }
3491   /* Otherwise, create a qual for the other part of the resolution. */
3492   else
3493     qual = build_tree_list (build_expr_wfl (name, NULL, 0, 0), NULL_TREE);
3494
3495   return find_as_inner_class_do (qual, enclosing);
3496 }
3497
3498 /* We go inside the list of sub classes and try to find a way
3499    through. */
3500
3501 static tree
3502 find_as_inner_class_do (qual, enclosing)
3503      tree qual, enclosing;
3504 {
3505   if (!qual)
3506     return NULL_TREE;
3507
3508   for (; qual && enclosing; qual = TREE_CHAIN (qual))
3509     {
3510       tree name_to_match = EXPR_WFL_NODE (TREE_PURPOSE (qual));
3511       tree next_enclosing = NULL_TREE;
3512       tree inner_list;
3513
3514       for (inner_list = DECL_INNER_CLASS_LIST (enclosing);
3515            inner_list; inner_list = TREE_CHAIN (inner_list))
3516         {
3517           if (TREE_VALUE (inner_list) == name_to_match)
3518             {
3519               next_enclosing = TREE_PURPOSE (inner_list);
3520               break;
3521             }
3522         }
3523       enclosing = next_enclosing;
3524     }
3525
3526   return (!qual && enclosing ? enclosing : NULL_TREE);
3527 }
3528
3529 /* Reach all inner classes and tie their unqualified name to a
3530    DECL. */
3531
3532 static void
3533 set_nested_class_simple_name_value (outer, set)
3534      tree outer;
3535      int set;
3536 {
3537   tree l;
3538
3539   for (l = DECL_INNER_CLASS_LIST (outer); l; l = TREE_CHAIN (l))
3540     IDENTIFIER_GLOBAL_VALUE (TREE_VALUE (l)) = (set ? 
3541                                                 TREE_PURPOSE (l) : NULL_TREE);
3542 }
3543
3544 static void
3545 link_nested_class_to_enclosing ()
3546 {
3547   if (GET_ENCLOSING_CPC ())
3548     {
3549       tree enclosing = GET_ENCLOSING_CPC_CONTEXT ();
3550       DECL_INNER_CLASS_LIST (enclosing) = 
3551         tree_cons (GET_CPC (), GET_CPC_UN (),
3552                    DECL_INNER_CLASS_LIST (enclosing));
3553       enclosing = enclosing;
3554     }
3555 }
3556
3557 static tree
3558 maybe_make_nested_class_name (name)
3559      tree name;
3560 {
3561   tree id = NULL_TREE;
3562
3563   if (CPC_INNER_P ())
3564     {
3565       make_nested_class_name (GET_CPC_LIST ());
3566       obstack_grow0 (&temporary_obstack,
3567                      IDENTIFIER_POINTER (name), 
3568                      IDENTIFIER_LENGTH (name));
3569       id = get_identifier (obstack_finish (&temporary_obstack));
3570       if (ctxp->package)
3571         QUALIFIED_P (id) = 1;
3572     }
3573   return id;
3574 }
3575
3576 /* If DECL is NULL, create and push a new DECL, record the current
3577    line CL and do other maintenance things.  */
3578
3579 static tree
3580 maybe_create_class_interface_decl (decl, raw_name, qualified_name, cl)
3581      tree decl, raw_name, qualified_name, cl;
3582 {
3583   if (!decl)
3584     decl = push_class (make_class (), qualified_name);
3585
3586   /* Take care of the file and line business */
3587   DECL_SOURCE_FILE (decl) = EXPR_WFL_FILENAME (cl);
3588   /* If we're emiting xrefs, store the line/col number information */
3589   if (flag_emit_xref)
3590     DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (cl);
3591   else
3592     DECL_SOURCE_LINE (decl) = EXPR_WFL_LINENO (cl);
3593   CLASS_FROM_SOURCE_P (TREE_TYPE (decl)) = 1;
3594   CLASS_FROM_CURRENTLY_COMPILED_SOURCE_P (TREE_TYPE (decl)) =
3595     IS_A_COMMAND_LINE_FILENAME_P (EXPR_WFL_FILENAME_NODE (cl));
3596
3597   PUSH_CPC (decl, raw_name);
3598   DECL_CONTEXT (decl) = GET_ENCLOSING_CPC_CONTEXT ();
3599
3600   /* Link the declaration to the already seen ones */
3601   TREE_CHAIN (decl) = ctxp->class_list;
3602   ctxp->class_list = decl;
3603
3604   /* Create a new nodes in the global lists */
3605   ctxp->gclass_list = tree_cons (NULL_TREE, decl, ctxp->gclass_list);
3606   all_class_list = tree_cons (NULL_TREE, decl, all_class_list);
3607
3608   /* Install a new dependency list element */
3609   create_jdep_list (ctxp);
3610
3611   SOURCE_FRONTEND_DEBUG (("Defining class/interface %s", 
3612                           IDENTIFIER_POINTER (qualified_name)));
3613   return decl;
3614 }
3615
3616 static void
3617 add_superinterfaces (decl, interface_list)
3618      tree decl, interface_list;
3619 {
3620   tree node;
3621   /* Superinterface(s): if present and defined, parser_check_super_interface ()
3622      takes care of ensuring that:
3623        - This is an accessible interface type,
3624        - Circularity detection.
3625    parser_add_interface is then called. If present but not defined,
3626    the check operation is delayed until the super interface gets
3627    defined.  */
3628   for (node = interface_list; node; node = TREE_CHAIN (node))
3629     {
3630       tree current = TREE_PURPOSE (node);
3631       tree idecl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (current));
3632       if (idecl && CLASS_LOADED_P (TREE_TYPE (idecl)))
3633         {
3634           if (!parser_check_super_interface (idecl, decl, current))
3635             parser_add_interface (decl, idecl, current);
3636         }
3637       else
3638         register_incomplete_type (JDEP_INTERFACE,
3639                                   current, decl, NULL_TREE);
3640     }
3641 }
3642
3643 /* Create an interface in pass1 and return its decl. Return the
3644    interface's decl in pass 2.  */
3645
3646 static tree
3647 create_interface (flags, id, super)
3648      int flags;
3649      tree id, super;
3650 {
3651   tree raw_name = EXPR_WFL_NODE (id);
3652   tree q_name = parser_qualified_classname (flags & ACC_STATIC, raw_name);
3653   tree decl = IDENTIFIER_CLASS_VALUE (q_name);
3654
3655   EXPR_WFL_NODE (id) = q_name;  /* Keep source location, even if refined. */
3656
3657   /* Basic checks: scope, redefinition, modifiers */ 
3658   if (check_class_interface_creation (1, flags, raw_name, q_name, decl, id))
3659     {
3660       PUSH_ERROR ();
3661       return NULL_TREE;
3662     }
3663
3664   /* Suspend the current parsing context if we're parsing an inner
3665      interface */
3666   if (CPC_INNER_P ())
3667     java_parser_context_suspend ();
3668
3669   /* Push a new context for (static) initialized upon declaration fields */
3670   java_parser_context_push_initialized_field ();
3671
3672   /* Interface modifiers check
3673        - public/abstract allowed (already done at that point)
3674        - abstract is obsolete (comes first, it's a warning, or should be)
3675        - Can't use twice the same (checked in the modifier rule) */
3676   if ((flags & ACC_ABSTRACT) && flag_redundant)
3677     parse_warning_context 
3678       (MODIFIER_WFL (ABSTRACT_TK),
3679        "Redundant use of `abstract' modifier. Interface `%s' is implicitely abstract", IDENTIFIER_POINTER (raw_name));
3680
3681   /* Create a new decl if DECL is NULL, otherwise fix it */
3682   decl = maybe_create_class_interface_decl (decl, raw_name, q_name, id);
3683
3684   /* Set super info and mark the class a complete */
3685   set_super_info (ACC_INTERFACE | flags, TREE_TYPE (decl), 
3686                   object_type_node, ctxp->interface_number);
3687   ctxp->interface_number = 0;
3688   CLASS_COMPLETE_P (decl) = 1;
3689   add_superinterfaces (decl, super);
3690
3691   return decl;
3692 }
3693
3694 /* Anonymous class counter. Will be reset to 1 every time a non
3695    anonymous class gets created. */
3696 static int anonymous_class_counter = 1;
3697
3698 /* Patch anonymous class CLASS, by either extending or implementing
3699    DEP.  */
3700
3701 static void
3702 patch_anonymous_class (type_decl, class_decl, wfl)
3703     tree type_decl, class_decl, wfl;
3704 {
3705   tree class = TREE_TYPE (class_decl);
3706   tree type =  TREE_TYPE (type_decl);
3707   tree binfo = TYPE_BINFO (class);
3708
3709   /* If it's an interface, implement it */
3710   if (CLASS_INTERFACE (type_decl))
3711     {
3712       tree s_binfo;
3713       int length;
3714
3715       if (parser_check_super_interface (type_decl, class_decl, wfl))
3716         return;
3717
3718       s_binfo = TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (class)), 0);
3719       length = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (class))+1;
3720       TYPE_BINFO_BASETYPES (class) = make_tree_vec (length);
3721       TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (class)), 0) = s_binfo;
3722       /* And add the interface */
3723       parser_add_interface (class_decl, type_decl, wfl);
3724     }
3725   /* Otherwise, it's a type we want to extend */
3726   else
3727     {
3728       if (parser_check_super (type_decl, class_decl, wfl))
3729         return;
3730       BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo), 0)) = type;
3731     }
3732 }
3733
3734 static tree
3735 create_anonymous_class (location, type_name)
3736     int location;
3737     tree type_name;
3738 {
3739   char buffer [80];
3740   tree super = NULL_TREE, itf = NULL_TREE;
3741   tree id, type_decl, class;
3742
3743   /* The unqualified name of the anonymous class. It's just a number. */
3744   sprintf (buffer, "%d", anonymous_class_counter++);
3745   id = build_wfl_node (get_identifier (buffer));
3746   EXPR_WFL_LINECOL (id) = location;
3747
3748   /* We know about the type to extend/implement. We go ahead */
3749   if ((type_decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (type_name))))
3750     {
3751       /* Create a class which either implements on extends the designated
3752          class. The class bears an innacessible name. */
3753       if (CLASS_INTERFACE (type_decl))
3754         {
3755           /* It's OK to modify it here. It's been already used and
3756              shouldn't be reused */
3757           ctxp->interface_number = 1;
3758           /* Interfaces should presented as a list of WFLs */
3759           itf = build_tree_list (type_name, NULL_TREE);
3760         }
3761       else
3762         super = type_name;
3763     }
3764
3765   class = create_class (ACC_FINAL, id, super, itf);
3766
3767   /* We didn't know anything about the stuff. We register a dependence. */
3768   if (!type_decl)
3769     register_incomplete_type (JDEP_ANONYMOUS, type_name, class, NULL_TREE);
3770
3771   ANONYMOUS_CLASS_P (TREE_TYPE (class)) = 1;
3772   return class;
3773 }
3774
3775 /* Create a class in pass1 and return its decl. Return class
3776    interface's decl in pass 2.  */
3777
3778 static tree
3779 create_class (flags, id, super, interfaces)
3780      int flags;
3781      tree id, super, interfaces;
3782 {
3783   tree raw_name = EXPR_WFL_NODE (id);
3784   tree class_id, decl;
3785   tree super_decl_type;
3786
3787   class_id = parser_qualified_classname (0, raw_name);
3788   decl = IDENTIFIER_CLASS_VALUE (class_id);
3789   EXPR_WFL_NODE (id) = class_id;
3790
3791   /* Basic check: scope, redefinition, modifiers */
3792   if (check_class_interface_creation (0, flags, raw_name, class_id, decl, id))
3793     {
3794       PUSH_ERROR ();
3795       return NULL_TREE;
3796     }
3797   
3798   /* Suspend the current parsing context if we're parsing an inner
3799      class or an anonymous class. */
3800   if (CPC_INNER_P ())
3801     java_parser_context_suspend ();
3802   /* Push a new context for (static) initialized upon declaration fields */
3803   java_parser_context_push_initialized_field ();
3804
3805   /* Class modifier check: 
3806        - Allowed modifier (already done at that point)
3807        - abstract AND final forbidden 
3808        - Public classes defined in the correct file */
3809   if ((flags & ACC_ABSTRACT) && (flags & ACC_FINAL))
3810     parse_error_context
3811       (id, "Class `%s' can't be declared both abstract and final",
3812        IDENTIFIER_POINTER (raw_name));
3813
3814   /* Create a new decl if DECL is NULL, otherwise fix it */
3815   decl = maybe_create_class_interface_decl (decl, raw_name, class_id, id);
3816
3817   /* If SUPER exists, use it, otherwise use Object */
3818   if (super)
3819     {
3820       /* Can't extend java.lang.Object */
3821       if (TREE_TYPE (IDENTIFIER_CLASS_VALUE (class_id)) == object_type_node)
3822         {
3823           parse_error_context (id, "Can't extend `java.lang.Object'");
3824           return NULL_TREE;
3825         }
3826
3827       super_decl_type = 
3828         register_incomplete_type (JDEP_SUPER, super, decl, NULL_TREE);
3829     }
3830   else if (TREE_TYPE (decl) != object_type_node)
3831     super_decl_type = object_type_node;
3832   /* We're defining java.lang.Object */
3833   else
3834     super_decl_type = NULL_TREE;
3835
3836   /* Set super info and mark the class a complete */
3837   set_super_info (flags, TREE_TYPE (decl), super_decl_type, 
3838                   ctxp->interface_number);
3839   ctxp->interface_number = 0;
3840   CLASS_COMPLETE_P (decl) = 1;
3841   add_superinterfaces (decl, interfaces);
3842
3843   /* If the class is a top level inner class, install an alias. */
3844   if (INNER_CLASS_DECL_P (decl) && CLASS_STATIC (decl))
3845     {
3846       tree alias = parser_qualified_classname (1, raw_name);
3847       IDENTIFIER_GLOBAL_VALUE (alias) = decl;
3848     }
3849
3850   /* Add the private this$<n> field, Replicate final locals still in
3851      scope as private final fields mangled like val$<local_name>.
3852      This doesn't not occur for top level (static) inner classes. */
3853   if (PURE_INNER_CLASS_DECL_P (decl))
3854     add_inner_class_fields (decl, current_function_decl);
3855
3856   /* If doing xref, store the location at which the inherited class
3857      (if any) was seen. */
3858   if (flag_emit_xref && super)
3859     DECL_INHERITED_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (super);
3860
3861   /* Eventually sets the @deprecated tag flag */
3862   CHECK_DEPRECATED (decl);
3863
3864   /* Reset the anonymous class counter when declaring non inner classes */
3865   if (!INNER_CLASS_DECL_P (decl))
3866     anonymous_class_counter = 1;
3867
3868   return decl;
3869 }
3870
3871 /* End a class declaration: register the statements used to create
3872    $finit$ and <clinit>, pop the current class and resume the prior
3873    parser context if necessary.  */
3874
3875 static void
3876 end_class_declaration (resume)
3877      int resume;
3878 {
3879   /* If an error occured, context weren't pushed and won't need to be
3880      popped by a resume. */
3881   int no_error_occured = ctxp->next && GET_CPC () != error_mark_node;
3882
3883   java_parser_context_pop_initialized_field ();
3884   POP_CPC ();
3885   if (resume && no_error_occured)
3886     java_parser_context_resume ();
3887
3888   /* We're ending a class declaration, this is a good time to reset
3889      the interface cout. Note that might have been already done in
3890      create_interface, but if at that time an inner class was being
3891      dealt with, the interface count was reset in a context created
3892      for the sake of handling inner classes declaration. */
3893   ctxp->interface_number = 0;
3894 }
3895
3896 static void
3897 add_inner_class_fields (class_decl, fct_decl)
3898      tree class_decl;
3899      tree fct_decl;
3900 {
3901   tree block, marker, f;
3902
3903   f = add_field (TREE_TYPE (class_decl),
3904                  build_current_thisn (TREE_TYPE (class_decl)),
3905                  build_pointer_type (TREE_TYPE (DECL_CONTEXT (class_decl))), 
3906                  ACC_PRIVATE);
3907   FIELD_THISN (f) = 1;
3908
3909   if (!fct_decl)
3910     return;
3911     
3912   for (block = GET_CURRENT_BLOCK (fct_decl); 
3913        block && TREE_CODE (block) == BLOCK; block = BLOCK_SUPERCONTEXT (block))
3914     {
3915       tree decl;
3916       for (decl = BLOCK_EXPR_DECLS (block); decl; decl = TREE_CHAIN (decl))
3917         {
3918           char *name, *pname;
3919           tree wfl, init, list;
3920           
3921           /* Avoid non final arguments. */
3922           if (!LOCAL_FINAL (decl))
3923             continue;
3924           
3925           MANGLE_OUTER_LOCAL_VARIABLE_NAME (name, DECL_NAME (decl));
3926           MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_ID (pname, DECL_NAME (decl));
3927           wfl = build_wfl_node (get_identifier (name));
3928           init = build_wfl_node (get_identifier (pname));
3929           /* Build an initialization for the field: it will be
3930              initialized by a parameter added to $finit$, bearing a
3931              mangled name of the field itself (param$<n>.) The
3932              parameter is provided to $finit$ by the constructor
3933              invoking it (hence the constructor will also feature a
3934              hidden parameter, set to the value of the outer context
3935              local at the time the inner class is created.)
3936              
3937              Note: we take into account all possible locals that can
3938              be accessed by the inner class. It's actually not trivial
3939              to minimize these aliases down to the ones really
3940              used. One way to do that would be to expand all regular
3941              methods first, then $finit$ to get a picture of what's
3942              used.  It works with the exception that we would have to
3943              go back on all constructor invoked in regular methods to
3944              have their invokation reworked (to include the right amount
3945              of alias initializer parameters.)
3946
3947              The only real way around, I think, is a first pass to
3948              identify locals really used in the inner class. We leave
3949              the flag FIELD_LOCAL_ALIAS_USED around for that future
3950              use.
3951              
3952              On the other hand, it only affect local inner classes,
3953              whose constructors (and $finit$ call) will be featuring
3954              unecessary arguments. It's easy for a developper to keep
3955              this number of parameter down by using the `final'
3956              keyword only when necessary. For the time being, we can
3957              issue a warning on unecessary finals. FIXME */
3958           init = build_assignment (ASSIGN_TK, EXPR_WFL_LINECOL (wfl), 
3959                                    wfl, init);
3960
3961           /* Register the field. The TREE_LIST holding the part
3962              initialized/initializer will be marked ARG_FINAL_P so
3963              that the created field can be marked
3964              FIELD_LOCAL_ALIAS. */
3965           list = build_tree_list (wfl, init);
3966           ARG_FINAL_P (list) = 1;
3967           register_fields (ACC_PRIVATE | ACC_FINAL, TREE_TYPE (decl), list);
3968         }
3969     }
3970
3971   if (!CPC_INITIALIZER_STMT (ctxp))
3972     return;
3973
3974   /* If we ever registered an alias field, insert and marker to
3975      remeber where the list ends. The second part of the list (the one
3976      featuring initialized fields) so it can be later reversed to
3977      enforce 8.5. The marker will be removed during that operation. */
3978   marker = build_tree_list (NULL_TREE, NULL_TREE);
3979   TREE_CHAIN (marker) = CPC_INITIALIZER_STMT (ctxp);
3980   SET_CPC_INITIALIZER_STMT (ctxp, marker);
3981 }
3982
3983 /* Can't use lookup_field () since we don't want to load the class and
3984    can't set the CLASS_LOADED_P flag */
3985
3986 static tree
3987 find_field (class, name)
3988      tree class;
3989      tree name;
3990 {
3991   tree decl;
3992   for (decl = TYPE_FIELDS (class); decl; decl = TREE_CHAIN (decl))
3993     {
3994       if (DECL_NAME (decl) == name)
3995         return decl;
3996     }
3997   return NULL_TREE;
3998 }
3999
4000 /* Wrap around lookup_field that doesn't potentially upset the value
4001    of CLASS */
4002
4003 static tree
4004 lookup_field_wrapper (class, name)
4005      tree class, name;
4006 {
4007   tree type = class;
4008   tree decl = NULL_TREE;
4009   java_parser_context_save_global ();
4010
4011   /* Last chance: if we're within the context of an inner class, we
4012      might be trying to access a local variable defined in an outer
4013      context. We try to look for it now. */
4014   if (INNER_CLASS_TYPE_P (class))
4015     {
4016       char *alias_buffer;
4017       tree new_name;
4018       MANGLE_OUTER_LOCAL_VARIABLE_NAME (alias_buffer, name);
4019       new_name = get_identifier (alias_buffer);
4020       decl = lookup_field (&type, new_name);
4021       if (decl && decl != error_mark_node)
4022         FIELD_LOCAL_ALIAS_USED (decl) = 1;
4023     }
4024   if (!decl || decl == error_mark_node)
4025     {
4026       type = class;
4027       decl = lookup_field (&type, name);
4028     }
4029
4030   java_parser_context_restore_global ();
4031   return decl == error_mark_node ? NULL : decl;
4032 }
4033
4034 /* Find duplicate field within the same class declarations and report
4035    the error. Returns 1 if a duplicated field was found, 0
4036    otherwise.  */
4037
4038 static int
4039 duplicate_declaration_error_p (new_field_name, new_type, cl)
4040      tree new_field_name, new_type, cl;
4041 {
4042   /* This might be modified to work with method decl as well */
4043   tree decl = find_field (TREE_TYPE (GET_CPC ()), new_field_name);
4044   if (decl)
4045     {
4046       char *t1 = xstrdup (purify_type_name
4047                          ((TREE_CODE (new_type) == POINTER_TYPE 
4048                            && TREE_TYPE (new_type) == NULL_TREE) ?
4049                           IDENTIFIER_POINTER (TYPE_NAME (new_type)) :
4050                           lang_printable_name (new_type, 1)));
4051       /* The type may not have been completed by the time we report
4052          the error */
4053       char *t2 = xstrdup (purify_type_name
4054                          ((TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE 
4055                            && TREE_TYPE (TREE_TYPE (decl)) == NULL_TREE) ?
4056                           IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl))) :
4057                           lang_printable_name (TREE_TYPE (decl), 1)));
4058       parse_error_context 
4059         (cl , "Duplicate variable declaration: `%s %s' was `%s %s' (%s:%d)", 
4060          t1, IDENTIFIER_POINTER (new_field_name),
4061          t2, IDENTIFIER_POINTER (DECL_NAME (decl)),
4062          DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
4063       free (t1);
4064       free (t2);
4065       return 1;
4066     }
4067   return 0;
4068 }
4069
4070 /* Field registration routine. If TYPE doesn't exist, field
4071    declarations are linked to the undefined TYPE dependency list, to
4072    be later resolved in java_complete_class () */
4073
4074 static void
4075 register_fields (flags, type, variable_list)
4076      int flags;
4077      tree type, variable_list;
4078 {
4079   tree current, saved_type;
4080   tree class_type = NULL_TREE;
4081   int saved_lineno = lineno;
4082   int must_chain = 0;
4083   tree wfl = NULL_TREE;
4084
4085   if (GET_CPC ())
4086     class_type = TREE_TYPE (GET_CPC ());
4087
4088   if (!class_type || class_type == error_mark_node)
4089     return;
4090
4091   /* If we're adding fields to interfaces, those fields are public,
4092      static, final */
4093   if (CLASS_INTERFACE (TYPE_NAME (class_type)))
4094     {
4095       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (PUBLIC_TK),
4096                                  flags, ACC_PUBLIC, "interface field(s)");
4097       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (STATIC_TK),
4098                                  flags, ACC_STATIC, "interface field(s)");
4099       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (FINAL_TK),
4100                                  flags, ACC_FINAL, "interface field(s)");
4101       check_modifiers ("Illegal interface member modifier `%s'", flags,
4102                        INTERFACE_FIELD_MODIFIERS);
4103       flags |= (ACC_PUBLIC | ACC_STATIC | ACC_FINAL);
4104     }
4105
4106   /* Obtain a suitable type for resolution, if necessary */
4107   SET_TYPE_FOR_RESOLUTION (type, wfl, must_chain);
4108
4109   /* If TYPE is fully resolved and we don't have a reference, make one */
4110   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4111
4112   for (current = variable_list, saved_type = type; current; 
4113        current = TREE_CHAIN (current), type = saved_type)
4114     {
4115       tree real_type;
4116       tree field_decl;
4117       tree cl = TREE_PURPOSE (current);
4118       tree init = TREE_VALUE (current);
4119       tree current_name = EXPR_WFL_NODE (cl);
4120
4121       /* Can't declare non-final static fields in inner classes */
4122       if ((flags & ACC_STATIC) && !TOPLEVEL_CLASS_TYPE_P (class_type)
4123           && !(flags & ACC_FINAL))
4124         parse_error_context 
4125           (cl, "Field `%s' can't be static in inner class `%s' unless it is final",
4126            IDENTIFIER_POINTER (EXPR_WFL_NODE (cl)),
4127            lang_printable_name (class_type, 0));
4128
4129       /* Process NAME, as it may specify extra dimension(s) for it */
4130       type = build_array_from_name (type, wfl, current_name, &current_name);
4131
4132       /* Type adjustment. We may have just readjusted TYPE because
4133          the variable specified more dimensions. Make sure we have
4134          a reference if we can and don't have one already. Also
4135          change the name if we have an init. */
4136       if (type != saved_type)
4137         {
4138           PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4139           if (init)
4140             EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = current_name;
4141         }
4142
4143       real_type = GET_REAL_TYPE (type);
4144       /* Check for redeclarations */
4145       if (duplicate_declaration_error_p (current_name, real_type, cl))
4146         continue;
4147
4148       /* Set lineno to the line the field was found and create a
4149          declaration for it. Eventually sets the @deprecated tag flag. */
4150       if (flag_emit_xref)
4151         lineno = EXPR_WFL_LINECOL (cl);
4152       else
4153         lineno = EXPR_WFL_LINENO (cl);
4154       field_decl = add_field (class_type, current_name, real_type, flags);
4155       CHECK_DEPRECATED (field_decl);
4156
4157       /* If the couple initializer/initialized is marked ARG_FINAL_P, we
4158          mark the created field FIELD_LOCAL_ALIAS, so that we can 
4159          hide parameters to this inner class $finit$ and constructors. */
4160       if (ARG_FINAL_P (current))
4161         FIELD_LOCAL_ALIAS (field_decl) = 1;
4162       
4163       /* Check if we must chain. */
4164       if (must_chain)
4165         register_incomplete_type (JDEP_FIELD, wfl, field_decl, type);
4166           
4167       /* If we have an initialization value tied to the field */
4168       if (init)
4169         {
4170           /* The field is declared static */
4171           if (flags & ACC_STATIC)
4172             {
4173               /* We include the field and its initialization part into
4174                  a list used to generate <clinit>. After <clinit> is
4175                  walked, field initializations will be processed and
4176                  fields initialized with known constants will be taken
4177                  out of <clinit> and have their DECL_INITIAL set
4178                  appropriately. */
4179               TREE_CHAIN (init) = CPC_STATIC_INITIALIZER_STMT (ctxp);
4180               SET_CPC_STATIC_INITIALIZER_STMT (ctxp, init);
4181               if (TREE_OPERAND (init, 1) 
4182                   && TREE_CODE (TREE_OPERAND (init, 1)) == NEW_ARRAY_INIT)
4183                 TREE_STATIC (TREE_OPERAND (init, 1)) = 1;
4184             }
4185           /* A non-static field declared with an immediate initialization is
4186              to be initialized in <init>, if any.  This field is remembered
4187              to be processed at the time of the generation of <init>. */
4188           else
4189             {
4190               TREE_CHAIN (init) = CPC_INITIALIZER_STMT (ctxp);
4191               SET_CPC_INITIALIZER_STMT (ctxp, init);
4192             }
4193           MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
4194           DECL_INITIAL (field_decl) = TREE_OPERAND (init, 1);
4195         }
4196     }
4197   lineno = saved_lineno;
4198 }
4199
4200 /* Generate $finit$, using the list of initialized fields to populate
4201    its body. $finit$'s parameter(s) list is adjusted to include the
4202    one(s) used to initialized the field(s) caching outer context
4203    local(s). */
4204
4205 static tree
4206 generate_finit (class_type)
4207      tree class_type;
4208 {
4209   int count = 0;
4210   tree list = TYPE_FINIT_STMT_LIST (class_type);
4211   tree mdecl, current, parms;
4212
4213   parms = build_alias_initializer_parameter_list (AIPL_FUNCTION_CREATION, 
4214                                                   class_type, NULL_TREE, 
4215                                                   &count);
4216   CRAFTED_PARAM_LIST_FIXUP (parms);
4217   mdecl = create_artificial_method (class_type, ACC_PRIVATE, void_type_node,
4218                                     finit_identifier_node, parms);
4219   fix_method_argument_names (parms, mdecl);
4220   layout_class_method (class_type, CLASSTYPE_SUPER (class_type),
4221                        mdecl, NULL_TREE);
4222   DECL_FUNCTION_NAP (mdecl) = count;
4223   start_artificial_method_body (mdecl);
4224
4225   for (current = list; current; current = TREE_CHAIN (current))
4226     java_method_add_stmt (mdecl, 
4227                           build_debugable_stmt (EXPR_WFL_LINECOL (current), 
4228                                                 current));
4229   end_artificial_method_body (mdecl);
4230   return mdecl;
4231 }
4232
4233 static void
4234 add_instance_initializer (mdecl)
4235      tree mdecl;
4236 {
4237   tree current;
4238   tree stmt_list = TYPE_II_STMT_LIST (DECL_CONTEXT (mdecl));
4239   tree compound = NULL_TREE;
4240
4241   if (stmt_list)
4242     {
4243       for (current = stmt_list; current; current = TREE_CHAIN (current))
4244         compound = add_stmt_to_compound (compound, NULL_TREE, current);
4245
4246       java_method_add_stmt (mdecl, build1 (INSTANCE_INITIALIZERS_EXPR,
4247                                            NULL_TREE, compound));
4248     }
4249 }
4250
4251 /* Shared accros method_declarator and method_header to remember the
4252    patch stage that was reached during the declaration of the method.
4253    A method DECL is built differently is there is no patch
4254    (JDEP_NO_PATCH) or a patch (JDEP_METHOD or JDEP_METHOD_RETURN)
4255    pending on the currently defined method.  */
4256
4257 static int patch_stage;
4258
4259 /* Check the method declaration and add the method to its current
4260    class.  If the argument list is known to contain incomplete types,
4261    the method is partially added and the registration will be resume
4262    once the method arguments resolved. If TYPE is NULL, we're dealing
4263    with a constructor.  */
4264
4265 static tree
4266 method_header (flags, type, mdecl, throws)
4267      int flags;
4268      tree type, mdecl, throws;
4269 {
4270   tree meth = TREE_VALUE (mdecl);
4271   tree id = TREE_PURPOSE (mdecl);
4272   tree type_wfl = NULL_TREE;
4273   tree meth_name = NULL_TREE;
4274   tree current, orig_arg, this_class = NULL;
4275   int saved_lineno;
4276   int constructor_ok = 0, must_chain;
4277   int count;
4278   
4279   check_modifiers_consistency (flags);
4280
4281   if (GET_CPC ())
4282     this_class = TREE_TYPE (GET_CPC ());
4283
4284   if (!this_class || this_class == error_mark_node)
4285     return NULL_TREE;
4286   
4287   /* There are some forbidden modifiers for an abstract method and its
4288      class must be abstract as well.  */
4289   if (type && (flags & ACC_ABSTRACT))
4290     {
4291       ABSTRACT_CHECK (flags, ACC_PRIVATE, id, "Private");
4292       ABSTRACT_CHECK (flags, ACC_STATIC, id, "Static");
4293       ABSTRACT_CHECK (flags, ACC_FINAL, id, "Final");
4294       ABSTRACT_CHECK (flags, ACC_NATIVE, id, "Native");
4295       ABSTRACT_CHECK (flags, ACC_SYNCHRONIZED,id, "Synchronized");
4296       if (!CLASS_ABSTRACT (TYPE_NAME (this_class))
4297           && !CLASS_INTERFACE (TYPE_NAME (this_class)))
4298         parse_error_context 
4299           (id, "Class `%s' must be declared abstract to define abstract method `%s'", 
4300            IDENTIFIER_POINTER (DECL_NAME (ctxp->current_parsed_class)),
4301            IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
4302     }
4303
4304   /* Things to be checked when declaring a constructor */
4305   if (!type)
4306     {
4307       int ec = java_error_count;
4308       /* 8.6: Constructor declarations: we might be trying to define a
4309          method without specifying a return type. */
4310       if (EXPR_WFL_NODE (id) != GET_CPC_UN ())
4311         parse_error_context 
4312           (id, "Invalid method declaration, return type required");
4313       /* 8.6.3: Constructor modifiers */
4314       else
4315         {
4316           JCONSTRUCTOR_CHECK (flags, ACC_ABSTRACT, id, "abstract");
4317           JCONSTRUCTOR_CHECK (flags, ACC_STATIC, id, "static");
4318           JCONSTRUCTOR_CHECK (flags, ACC_FINAL, id, "final");
4319           JCONSTRUCTOR_CHECK (flags, ACC_NATIVE, id, "native");
4320           JCONSTRUCTOR_CHECK (flags, ACC_SYNCHRONIZED, id, "synchronized");
4321         }
4322       /* If we found error here, we don't consider it's OK to tread
4323          the method definition as a constructor, for the rest of this
4324          function */
4325       if (ec == java_error_count)
4326         constructor_ok = 1;
4327     }
4328
4329   /* Method declared within the scope of an interface are implicitly
4330      abstract and public. Conflicts with other erroneously provided
4331      modifiers are checked right after. */
4332
4333   if (CLASS_INTERFACE (TYPE_NAME (this_class)))
4334     {
4335       /* If FLAGS isn't set because of a modifier, turn the
4336          corresponding modifier WFL to NULL so we issue a warning on
4337          the obsolete use of the modifier */
4338       if (!(flags & ACC_PUBLIC))
4339         MODIFIER_WFL (PUBLIC_TK) = NULL;
4340       if (!(flags & ACC_ABSTRACT))
4341         MODIFIER_WFL (ABSTRACT_TK) = NULL;
4342       flags |= ACC_PUBLIC;
4343       flags |= ACC_ABSTRACT;
4344     }
4345
4346   /* Inner class can't declare static methods */
4347   if ((flags & ACC_STATIC) && !TOPLEVEL_CLASS_TYPE_P (this_class))
4348     {
4349       parse_error_context 
4350         (id, "Method `%s' can't be static in inner class `%s'. Only members of interfaces and top-level classes can be static",
4351          IDENTIFIER_POINTER (EXPR_WFL_NODE (id)),
4352          lang_printable_name (this_class, 0));
4353     }
4354
4355   /* Modifiers context reset moved up, so abstract method declaration
4356      modifiers can be later checked.  */
4357
4358   /* Set constructor returned type to void and method name to <init>,
4359      unless we found an error identifier the constructor (in which
4360      case we retain the original name) */
4361   if (!type)
4362     {
4363       type = void_type_node;
4364       if (constructor_ok)
4365         meth_name = init_identifier_node;
4366     }
4367   else
4368     meth_name = EXPR_WFL_NODE (id);
4369
4370   /* Do the returned type resolution and registration if necessary */
4371   SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
4372
4373   if (meth_name)
4374     type = build_array_from_name (type, type_wfl, meth_name, &meth_name);
4375   EXPR_WFL_NODE (id) = meth_name;
4376   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4377
4378   if (must_chain)
4379     {
4380       patch_stage = JDEP_METHOD_RETURN;
4381       register_incomplete_type (patch_stage, type_wfl, id, type);
4382       TREE_TYPE (meth) = GET_REAL_TYPE (type);
4383     }
4384   else
4385     TREE_TYPE (meth) = type;
4386
4387   saved_lineno = lineno;
4388   /* When defining an abstract or interface method, the curly
4389      bracket at level 1 doesn't exist because there is no function
4390      body */
4391   lineno = (ctxp->first_ccb_indent1 ? ctxp->first_ccb_indent1 : 
4392             EXPR_WFL_LINENO (id));
4393
4394   /* Remember the original argument list */
4395   orig_arg = TYPE_ARG_TYPES (meth);
4396
4397   if (patch_stage)              /* includes ret type and/or all args */
4398     {
4399       jdep *jdep;
4400       meth = add_method_1 (this_class, flags, meth_name, meth);
4401       /* Patch for the return type */
4402       if (patch_stage == JDEP_METHOD_RETURN)
4403         {
4404           jdep = CLASSD_LAST (ctxp->classd_list);
4405           JDEP_GET_PATCH (jdep) = &TREE_TYPE (TREE_TYPE (meth));
4406         }
4407       /* This is the stop JDEP. METH allows the function's signature
4408          to be computed. */
4409       register_incomplete_type (JDEP_METHOD_END, NULL_TREE, meth, NULL_TREE);
4410     }
4411   else
4412     meth = add_method (this_class, flags, meth_name, 
4413                        build_java_signature (meth));
4414
4415   /* Remember final parameters */
4416   MARK_FINAL_PARMS (meth, orig_arg);
4417
4418   /* Fix the method argument list so we have the argument name
4419      information */
4420   fix_method_argument_names (orig_arg, meth);
4421
4422   /* Register the parameter number and re-install the current line
4423      number */
4424   DECL_MAX_LOCALS (meth) = ctxp->formal_parameter_number+1;
4425   lineno = saved_lineno;
4426
4427   /* Register exception specified by the `throws' keyword for
4428      resolution and set the method decl appropriate field to the list.
4429      Note: the grammar ensures that what we get here are class
4430      types. */
4431   if (throws)
4432     {
4433       throws = nreverse (throws);
4434       for (current = throws; current; current = TREE_CHAIN (current))
4435         {
4436           register_incomplete_type (JDEP_EXCEPTION, TREE_VALUE (current),
4437                                     NULL_TREE, NULL_TREE);
4438           JDEP_GET_PATCH (CLASSD_LAST (ctxp->classd_list)) = 
4439             &TREE_VALUE (current);
4440         }
4441       DECL_FUNCTION_THROWS (meth) = throws;
4442     }
4443
4444   /* We set the DECL_NAME to ID so we can track the location where
4445      the function was declared. This allow us to report
4446      redefinition error accurately. When method are verified,
4447      DECL_NAME is reinstalled properly (using the content of the
4448      WFL node ID) (see check_method_redefinition). We don't do that
4449      when Object is being defined. Constructor <init> names will be
4450      reinstalled the same way. */
4451   if (TREE_TYPE (GET_CPC ()) != object_type_node)
4452     DECL_NAME (meth) = id;
4453
4454   /* Set the flag if we correctly processed a constructor */
4455   if (constructor_ok)
4456     {
4457       DECL_CONSTRUCTOR_P (meth) = 1;
4458       /* Compute and store the number of artificial parameters declared
4459          for this constructor */
4460       for (count = 0, current = TYPE_FIELDS (this_class); current; 
4461            current = TREE_CHAIN (current))
4462         if (FIELD_LOCAL_ALIAS (current))
4463           count++;
4464       DECL_FUNCTION_NAP (meth) = count;
4465     }
4466
4467   /* Eventually set the @deprecated tag flag */
4468   CHECK_DEPRECATED (meth);
4469
4470   /* If doing xref, store column and line number information instead
4471      of the line number only. */
4472   if (flag_emit_xref)
4473     DECL_SOURCE_LINE (meth) = EXPR_WFL_LINECOL (id);
4474
4475   return meth;
4476 }
4477
4478 static void
4479 fix_method_argument_names (orig_arg, meth)
4480     tree orig_arg, meth;
4481 {
4482   tree arg = TYPE_ARG_TYPES (TREE_TYPE (meth));
4483   if (TREE_CODE (TREE_TYPE (meth)) == METHOD_TYPE)
4484     {
4485       TREE_PURPOSE (arg) = this_identifier_node;
4486       arg = TREE_CHAIN (arg);
4487     }
4488   while (orig_arg != end_params_node)
4489     {
4490       TREE_PURPOSE (arg) = TREE_PURPOSE (orig_arg);
4491       orig_arg = TREE_CHAIN (orig_arg);
4492       arg = TREE_CHAIN (arg);
4493     }
4494 }
4495
4496 /* Complete the method declaration with METHOD_BODY.  */
4497
4498 static void
4499 finish_method_declaration (method_body)
4500      tree method_body;
4501 {
4502   int flags;
4503
4504   if (!current_function_decl)
4505     return;
4506
4507   flags = get_access_flags_from_decl (current_function_decl);
4508
4509   /* 8.4.5 Method Body */
4510   if ((flags & ACC_ABSTRACT || flags & ACC_NATIVE) && method_body)
4511     {
4512       tree wfl = DECL_NAME (current_function_decl);
4513       parse_error_context (wfl, 
4514                            "%s method `%s' can't have a body defined",
4515                            (METHOD_NATIVE (current_function_decl) ?
4516                             "Native" : "Abstract"),
4517                            IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
4518       method_body = NULL_TREE;
4519     }
4520   else if (!(flags & ACC_ABSTRACT) && !(flags & ACC_NATIVE) && !method_body)
4521     {
4522       tree wfl = DECL_NAME (current_function_decl);
4523       parse_error_context
4524         (wfl, 
4525          "Non native and non abstract method `%s' must have a body defined",
4526          IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
4527       method_body = NULL_TREE;
4528     }
4529
4530   if (flag_emit_class_files && method_body 
4531       && TREE_CODE (method_body) == NOP_EXPR 
4532       && TREE_TYPE (current_function_decl) 
4533       && TREE_TYPE (TREE_TYPE (current_function_decl)) == void_type_node)
4534     method_body = build1 (RETURN_EXPR, void_type_node, NULL);
4535
4536   BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (current_function_decl)) = method_body;
4537   maybe_absorb_scoping_blocks ();
4538   /* Exit function's body */
4539   exit_block ();
4540   /* Merge last line of the function with first line, directly in the
4541      function decl. It will be used to emit correct debug info. */
4542   if (!flag_emit_xref)
4543     DECL_SOURCE_LINE_MERGE (current_function_decl, ctxp->last_ccb_indent1);
4544
4545   /* Since function's argument's list are shared, reset the
4546      ARG_FINAL_P parameter that might have been set on some of this
4547      function parameters. */
4548   UNMARK_FINAL_PARMS (current_function_decl);
4549   
4550   /* So we don't have an irrelevant function declaration context for
4551      the next static block we'll see. */
4552   current_function_decl = NULL_TREE;
4553 }
4554
4555 /* Build a an error message for constructor circularity errors.  */
4556
4557 static char *
4558 constructor_circularity_msg (from, to)
4559      tree from, to;
4560 {
4561   static char string [4096];
4562   char *t = xstrdup (lang_printable_name (from, 0));
4563   sprintf (string, "`%s' invokes `%s'", t, lang_printable_name (to, 0));
4564   free (t);
4565   return string;
4566 }
4567
4568 /* Verify a circular call to METH. Return 1 if an error is found, 0
4569    otherwise.  */
4570
4571 static int
4572 verify_constructor_circularity (meth, current)
4573      tree meth, current;
4574 {
4575   static tree list = NULL_TREE;
4576   tree c;
4577   for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
4578     {
4579       if (TREE_VALUE (c) == meth)
4580         {
4581           char *t;
4582           if (list)
4583             {
4584               tree liste;
4585               list = nreverse (list);
4586               for (liste = list; liste; liste = TREE_CHAIN (liste))
4587                 {
4588                   parse_error_context 
4589                     (TREE_PURPOSE (TREE_PURPOSE (liste)), "%s",
4590                      constructor_circularity_msg
4591                       (TREE_VALUE (liste), TREE_VALUE (TREE_PURPOSE (liste)))); 
4592                   java_error_count--;
4593                 }
4594             }
4595           t = xstrdup (lang_printable_name (meth, 0));
4596           parse_error_context (TREE_PURPOSE (c), 
4597                                "%s: recursive invocation of constructor `%s'",
4598                                constructor_circularity_msg (current, meth), t);
4599           free (t);
4600           list = NULL_TREE;
4601           return 1;
4602         }
4603     }
4604   for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
4605     {
4606       list = tree_cons (c, current, list);
4607       if (verify_constructor_circularity (meth, TREE_VALUE (c)))
4608         return 1;
4609       list = TREE_CHAIN (list);
4610     }
4611   return 0;
4612 }
4613
4614 /* Check modifiers that can be declared but exclusively */
4615
4616 static void
4617 check_modifiers_consistency (flags)
4618      int flags;
4619 {
4620   int acc_count = 0;
4621   tree cl = NULL_TREE;
4622
4623   THIS_MODIFIER_ONLY (flags, ACC_PUBLIC, PUBLIC_TK, acc_count, cl);
4624   THIS_MODIFIER_ONLY (flags, ACC_PRIVATE, PRIVATE_TK, acc_count, cl);
4625   THIS_MODIFIER_ONLY (flags, ACC_PROTECTED, PROTECTED_TK, acc_count, cl);
4626   if (acc_count > 1)
4627     parse_error_context
4628       (cl, "Inconsistent member declaration.  At most one of `public', `private', or `protected' may be specified");
4629
4630   acc_count = 0;
4631   cl = NULL_TREE;
4632   THIS_MODIFIER_ONLY (flags, ACC_FINAL, FINAL_TK, acc_count, cl);
4633   THIS_MODIFIER_ONLY (flags, ACC_VOLATILE, VOLATILE_TK, acc_count, cl);
4634   if (acc_count > 1)
4635     parse_error_context (cl,
4636                          "Inconsistent member declaration.  At most one of `final' or `volatile' may be specified");
4637 }
4638
4639 /* Check the methode header METH for abstract specifics features */
4640
4641 static void
4642 check_abstract_method_header (meth)
4643      tree meth;
4644 {
4645   int flags = get_access_flags_from_decl (meth);
4646   /* DECL_NAME might still be a WFL node */
4647   tree name = GET_METHOD_NAME (meth);
4648
4649   OBSOLETE_MODIFIER_WARNING2 (MODIFIER_WFL (ABSTRACT_TK), flags,
4650                               ACC_ABSTRACT, "abstract method",
4651                               IDENTIFIER_POINTER (name));
4652   OBSOLETE_MODIFIER_WARNING2 (MODIFIER_WFL (PUBLIC_TK), flags, 
4653                               ACC_PUBLIC, "abstract method",
4654                               IDENTIFIER_POINTER (name));
4655
4656   check_modifiers ("Illegal modifier `%s' for interface method",
4657                   flags, INTERFACE_METHOD_MODIFIERS);
4658 }
4659
4660 /* Create a FUNCTION_TYPE node and start augmenting it with the
4661    declared function arguments. Arguments type that can't be resolved
4662    are left as they are, but the returned node is marked as containing
4663    incomplete types.  */
4664
4665 static tree
4666 method_declarator (id, list)
4667      tree id, list;
4668 {
4669   tree arg_types = NULL_TREE, current, node;
4670   tree meth = make_node (FUNCTION_TYPE);
4671   jdep *jdep;
4672
4673   patch_stage = JDEP_NO_PATCH;
4674
4675   /* If we're dealing with an inner class constructor, we hide the
4676      this$<n> decl in the name field of its parameter declaration.  We
4677      also might have to hide the outer context local alias
4678      initializers. Not done when the class is a toplevel class. */
4679   if (PURE_INNER_CLASS_DECL_P (GET_CPC ()) 
4680       && EXPR_WFL_NODE (id) == GET_CPC_UN ())
4681     {
4682       tree aliases_list, type, thisn;
4683       /* First the aliases, linked to the regular parameters */
4684       aliases_list =
4685         build_alias_initializer_parameter_list (AIPL_FUNCTION_DECLARATION, 
4686                                                 TREE_TYPE (GET_CPC ()),
4687                                                 NULL_TREE, NULL);
4688       list = chainon (nreverse (aliases_list), list);
4689
4690       /* Then this$<n> */
4691       type = TREE_TYPE (DECL_CONTEXT (GET_CPC ()));
4692       thisn = build_current_thisn (TREE_TYPE (GET_CPC ()));
4693       list = tree_cons (build_wfl_node (thisn), build_pointer_type (type),
4694                         list);
4695     }
4696   
4697   for (current = list; current; current = TREE_CHAIN (current))
4698     {
4699       int must_chain = 0;
4700       tree wfl_name = TREE_PURPOSE (current);
4701       tree type = TREE_VALUE (current);
4702       tree name = EXPR_WFL_NODE (wfl_name);
4703       tree already, arg_node;
4704       tree type_wfl = NULL_TREE;
4705       tree real_type;
4706
4707       /* Obtain a suitable type for resolution, if necessary */
4708       SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
4709
4710       /* Process NAME, as it may specify extra dimension(s) for it */
4711       type = build_array_from_name (type, type_wfl, name, &name);
4712       EXPR_WFL_NODE (wfl_name) = name;
4713
4714       real_type = GET_REAL_TYPE (type);
4715       if (TREE_CODE (real_type) == RECORD_TYPE)
4716         {
4717           real_type = promote_type (real_type);
4718           if (TREE_CODE (type) == TREE_LIST)
4719             TREE_PURPOSE (type) = real_type;
4720         }
4721
4722       /* Check redefinition */
4723       for (already = arg_types; already; already = TREE_CHAIN (already))
4724         if (TREE_PURPOSE (already) == name)
4725           {
4726             parse_error_context
4727               (wfl_name, "Variable `%s' is used more than once in the argument list of method `%s'",
4728                IDENTIFIER_POINTER (name),
4729                IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
4730             break;
4731           }
4732
4733       /* If we've an incomplete argument type, we know there is a location
4734          to patch when the type get resolved, later.  */
4735       jdep = NULL;
4736       if (must_chain)
4737         {
4738           patch_stage = JDEP_METHOD;
4739           type = register_incomplete_type (patch_stage, 
4740                                            type_wfl, wfl_name, type);
4741           jdep = CLASSD_LAST (ctxp->classd_list);
4742           JDEP_MISC (jdep) = id;
4743         }
4744
4745       /* The argument node: a name and a (possibly) incomplete type.  */
4746       arg_node = build_tree_list (name, real_type);
4747       /* Remeber arguments declared final. */
4748       ARG_FINAL_P (arg_node) = ARG_FINAL_P (current);
4749       
4750       if (jdep)
4751         JDEP_GET_PATCH (jdep) = &TREE_VALUE (arg_node);
4752       TREE_CHAIN (arg_node) = arg_types;
4753       arg_types = arg_node;
4754     }
4755   TYPE_ARG_TYPES (meth) = chainon (nreverse (arg_types), end_params_node);
4756   node = build_tree_list (id, meth);
4757   return node;
4758 }
4759
4760 static int
4761 unresolved_type_p (wfl, returned)
4762      tree wfl;
4763      tree *returned;
4764      
4765 {
4766   if (TREE_CODE (wfl) == EXPR_WITH_FILE_LOCATION)
4767     {
4768       if (returned)
4769         {
4770           tree decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (wfl));
4771           if (decl && current_class && (decl == TYPE_NAME (current_class)))
4772             *returned = TREE_TYPE (decl);
4773           else if (GET_CPC_UN () == EXPR_WFL_NODE (wfl))
4774             *returned = TREE_TYPE (GET_CPC ());
4775           else
4776             *returned = NULL_TREE;
4777         }
4778       return 1;
4779     }
4780   if (returned)
4781     *returned = wfl;
4782   return 0;
4783 }
4784
4785 /* From NAME, build a qualified identifier node using the
4786    qualification from the current package definition. */
4787
4788 static tree
4789 parser_qualified_classname (is_static, name)
4790      int is_static;
4791      tree name;
4792 {
4793   tree nested_class_name;
4794
4795   if (!is_static 
4796       && (nested_class_name = maybe_make_nested_class_name (name)))
4797     return nested_class_name;
4798
4799   if (ctxp->package)
4800     return merge_qualified_name (ctxp->package, name);
4801   else 
4802     return name;
4803 }
4804
4805 /* Called once the type a interface extends is resolved. Returns 0 if
4806    everything is OK.  */
4807
4808 static int
4809 parser_check_super_interface (super_decl, this_decl, this_wfl)
4810      tree super_decl, this_decl, this_wfl;
4811 {
4812   tree super_type = TREE_TYPE (super_decl);
4813
4814   /* Has to be an interface */
4815   if (!CLASS_INTERFACE (super_decl))
4816     {
4817       parse_error_context 
4818         (this_wfl, "Can't use %s `%s' to implement/extend %s `%s'",
4819          (TYPE_ARRAY_P (super_type) ? "array" : "class"),
4820          IDENTIFIER_POINTER (DECL_NAME (super_decl)),
4821          (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (this_decl))) ? 
4822           "interface" : "class"),
4823          IDENTIFIER_POINTER (DECL_NAME (this_decl)));
4824       return 1;
4825     }
4826
4827   /* Check scope: same package OK, other package: OK if public */
4828   if (check_pkg_class_access (DECL_NAME (super_decl), lookup_cl (this_decl)))
4829     return 1;
4830
4831   SOURCE_FRONTEND_DEBUG (("Completing interface %s with %s",
4832                           IDENTIFIER_POINTER (DECL_NAME (this_decl)),
4833                           IDENTIFIER_POINTER (DECL_NAME (super_decl))));
4834   return 0;
4835 }
4836
4837 /* Makes sure that SUPER_DECL is suitable to extend THIS_DECL. Returns
4838    0 if everthing is OK.  */
4839
4840 static int
4841 parser_check_super (super_decl, this_decl, wfl)
4842      tree super_decl, this_decl, wfl;
4843 {
4844   tree super_type = TREE_TYPE (super_decl);
4845
4846   /* SUPER should be a CLASS (neither an array nor an interface) */
4847   if (TYPE_ARRAY_P (super_type) || CLASS_INTERFACE (TYPE_NAME (super_type)))
4848     {
4849       parse_error_context 
4850         (wfl, "Class `%s' can't subclass %s `%s'",
4851          IDENTIFIER_POINTER (DECL_NAME (this_decl)),
4852          (CLASS_INTERFACE (TYPE_NAME (super_type)) ? "interface" : "array"),
4853          IDENTIFIER_POINTER (DECL_NAME (super_decl)));
4854       return 1;
4855     }
4856
4857   if (CLASS_FINAL (TYPE_NAME (super_type)))
4858     {
4859       parse_error_context (wfl, "Can't subclass final classes: %s",
4860                            IDENTIFIER_POINTER (DECL_NAME (super_decl)));
4861       return 1;
4862     }
4863
4864   /* Check scope: same package OK, other package: OK if public */
4865   if (check_pkg_class_access (DECL_NAME (super_decl), wfl))
4866     return 1;
4867   
4868   SOURCE_FRONTEND_DEBUG (("Completing class %s with %s",
4869                           IDENTIFIER_POINTER (DECL_NAME (this_decl)),
4870                           IDENTIFIER_POINTER (DECL_NAME (super_decl))));
4871   return 0;
4872 }
4873
4874 /* Create a new dependency list and link it (in a LIFO manner) to the
4875    CTXP list of type dependency list.  */
4876
4877 static void
4878 create_jdep_list (ctxp)
4879      struct parser_ctxt *ctxp;
4880 {
4881   jdeplist *new = (jdeplist *)xmalloc (sizeof (jdeplist));      
4882   new->first = new->last = NULL;
4883   new->next = ctxp->classd_list;
4884   ctxp->classd_list = new;
4885 }
4886
4887 static jdeplist *
4888 reverse_jdep_list (ctxp)
4889      struct parser_ctxt *ctxp;
4890 {
4891   register jdeplist *prev = NULL, *current, *next;
4892   for (current = ctxp->classd_list; current; current = next)
4893     {
4894       next = current->next;
4895       current->next = prev;
4896       prev = current;
4897     }
4898   return prev;
4899 }
4900
4901 /* Create a fake pointer based on the ID stored in
4902    TYPE_NAME. TYPE_NAME can be a WFL or a incomplete type asking to be
4903    registered again. */
4904
4905 static tree
4906 obtain_incomplete_type (type_name)
4907      tree type_name;
4908 {
4909   tree ptr, name;
4910
4911   if (TREE_CODE (type_name) == EXPR_WITH_FILE_LOCATION)
4912     name = EXPR_WFL_NODE (type_name);
4913   else if (INCOMPLETE_TYPE_P (type_name))
4914     name = TYPE_NAME (type_name);
4915   else
4916     fatal ("invalid type name - obtain_incomplete_type");
4917
4918   for (ptr = ctxp->incomplete_class; ptr; ptr = TREE_CHAIN (ptr))
4919     if (TYPE_NAME (ptr) == name)
4920       break;
4921
4922   if (!ptr)
4923     {
4924       push_obstacks (&permanent_obstack, &permanent_obstack);
4925       BUILD_PTR_FROM_NAME (ptr, name);
4926       layout_type (ptr);
4927       pop_obstacks ();
4928       TREE_CHAIN (ptr) = ctxp->incomplete_class;
4929       ctxp->incomplete_class = ptr;
4930     }
4931
4932   return ptr;
4933 }
4934
4935 /* Register a incomplete type whose name is WFL. Reuse PTR if PTR is
4936    non NULL instead of computing a new fake type based on WFL. The new
4937    dependency is inserted in the current type dependency list, in FIFO
4938    manner.  */
4939
4940 static tree
4941 register_incomplete_type (kind, wfl, decl, ptr)
4942      int kind;
4943      tree wfl, decl, ptr;
4944 {
4945   jdep *new = (jdep *)xmalloc (sizeof (jdep));
4946
4947   if (!ptr && kind != JDEP_METHOD_END) /* JDEP_METHOD_END is a mere marker */
4948     ptr = obtain_incomplete_type (wfl);
4949
4950   JDEP_KIND (new) = kind;
4951   JDEP_DECL (new) = decl;
4952   JDEP_SOLV (new) = ptr;
4953   JDEP_WFL (new) = wfl;
4954   JDEP_CHAIN (new) = NULL;
4955   JDEP_MISC (new) = NULL_TREE;
4956   /* For some dependencies, set the enclosing class of the current
4957      class to be the enclosing context */
4958   if ((kind == JDEP_SUPER || kind == JDEP_INTERFACE || kind == JDEP_ANONYMOUS)
4959       && GET_ENCLOSING_CPC ())
4960     JDEP_ENCLOSING (new) = TREE_VALUE (GET_ENCLOSING_CPC ());
4961   else
4962     JDEP_ENCLOSING (new) = GET_CPC ();
4963   JDEP_GET_PATCH (new) = (tree *)NULL;
4964
4965   JDEP_INSERT (ctxp->classd_list, new);
4966
4967   return ptr;
4968 }
4969
4970 void
4971 java_check_circular_reference ()
4972 {
4973   tree current;
4974   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
4975     {
4976       tree type = TREE_TYPE (current);
4977       if (CLASS_INTERFACE (current))
4978         {
4979           /* Check all interfaces this class extends */
4980           tree basetype_vec = TYPE_BINFO_BASETYPES (type);
4981           int n, i;
4982
4983           if (!basetype_vec)
4984             return;
4985           n = TREE_VEC_LENGTH (basetype_vec);
4986           for (i = 0; i < n; i++)
4987             {
4988               tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
4989               if (vec_elt && BINFO_TYPE (vec_elt) != object_type_node 
4990                   && interface_of_p (type, BINFO_TYPE (vec_elt)))
4991                 parse_error_context (lookup_cl (current),
4992                                      "Cyclic interface inheritance");
4993             }
4994         }
4995       else
4996         if (inherits_from_p (CLASSTYPE_SUPER (type), type))
4997           parse_error_context (lookup_cl (current), 
4998                                "Cyclic class inheritance%s",
4999                                (cyclic_inheritance_report ?
5000                                 cyclic_inheritance_report : ""));
5001     }
5002 }
5003
5004 /* Augment the parameter list PARM with parameters crafted to
5005    initialize outer context locals aliases. Through ARTIFICIAL, a
5006    count is kept of the number of crafted parameters. MODE governs
5007    what eventually gets created: something suitable for a function
5008    creation or a function invocation, either the constructor or
5009    $finit$.  */
5010
5011 static tree
5012 build_alias_initializer_parameter_list (mode, class_type, parm, artificial)
5013     int mode;
5014     tree class_type, parm;
5015     int *artificial;
5016 {
5017   tree field;
5018   for (field = TYPE_FIELDS (class_type); field; field = TREE_CHAIN (field))
5019     if (FIELD_LOCAL_ALIAS (field))
5020       {
5021         char *buffer = IDENTIFIER_POINTER (DECL_NAME (field));
5022         tree purpose = NULL_TREE, value = NULL_TREE, name = NULL_TREE;
5023
5024         switch (mode)
5025           {
5026           case AIPL_FUNCTION_DECLARATION:
5027             MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (buffer, &buffer [4]);
5028             purpose = build_wfl_node (get_identifier (buffer));
5029             if (TREE_CODE (TREE_TYPE (field)) == POINTER_TYPE)
5030               value = build_wfl_node (TYPE_NAME (TREE_TYPE (field)));
5031             else
5032               value = TREE_TYPE (field);
5033             break;
5034
5035           case AIPL_FUNCTION_CREATION:
5036             MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (buffer, &buffer [4]);
5037             purpose = get_identifier (buffer);
5038             value = TREE_TYPE (field);
5039             break;
5040
5041           case AIPL_FUNCTION_FINIT_INVOCATION:
5042             MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (buffer, &buffer [4]);
5043             /* Now, this is wrong. purpose should always be the NAME
5044                of something and value its matching value (decl, type,
5045                etc...) FIXME -- but there is a lot to fix. */
5046
5047             /* When invoked for this kind of operation, we already
5048                know whether a field is used or not. */
5049             purpose = TREE_TYPE (field);
5050             value = build_wfl_node (get_identifier (buffer));
5051             break;
5052
5053           case AIPL_FUNCTION_CTOR_INVOCATION:
5054             /* There are two case: the constructor invokation happends
5055                outside the local inner, in which case, locales from the outer
5056                context are directly used.
5057
5058                Otherwise, we fold to using the alias directly. */
5059             if (class_type == current_class)
5060               value = field;
5061             else
5062               {
5063                 name = get_identifier (&buffer[4]);
5064                 value = IDENTIFIER_LOCAL_VALUE (name);
5065               }
5066             break;
5067           }
5068         parm = tree_cons (purpose, value, parm);
5069         if (artificial)
5070           *artificial +=1;
5071       }
5072   return parm;
5073 }
5074
5075 /* Craft a constructor for CLASS_DECL -- what we should do when none
5076    where found. ARGS is non NULL when a special signature must be
5077    enforced. This is the case for anonymous classes.  */
5078
5079 static void
5080 craft_constructor (class_decl, args)
5081      tree class_decl, args;
5082 {
5083   tree class_type = TREE_TYPE (class_decl);
5084   tree parm = NULL_TREE;
5085   int flags = (get_access_flags_from_decl (class_decl) & ACC_PUBLIC ?
5086                ACC_PUBLIC : 0);
5087   int i = 0, artificial = 0;
5088   tree decl, ctor_name;
5089   char buffer [80];
5090   
5091   push_obstacks (&permanent_obstack, &permanent_obstack);
5092
5093   /* The constructor name is <init> unless we're dealing with an
5094      anonymous class, in which case the name will be fixed after having
5095      be expanded. */
5096   if (ANONYMOUS_CLASS_P (class_type))
5097     ctor_name = DECL_NAME (class_decl);
5098   else
5099     ctor_name = init_identifier_node;
5100
5101   /* If we're dealing with an inner class constructor, we hide the
5102      this$<n> decl in the name field of its parameter declaration. */
5103   if (PURE_INNER_CLASS_TYPE_P (class_type))
5104     {
5105       tree type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class_type)));
5106       parm = tree_cons (build_current_thisn (class_type),
5107                         build_pointer_type (type), parm);
5108
5109       /* Some more arguments to be hidden here. The values of the local
5110          variables of the outer context that the inner class needs to see. */
5111       parm = build_alias_initializer_parameter_list (AIPL_FUNCTION_CREATION,
5112                                                      class_type, parm, 
5113                                                      &artificial);
5114     }
5115
5116   /* Then if there are any args to be enforced, enforce them now */
5117   for (; args && args != end_params_node; args = TREE_CHAIN (args))
5118     {
5119       sprintf (buffer, "parm%d", i++);
5120       parm = tree_cons (get_identifier (buffer), TREE_VALUE (args), parm);
5121     }
5122
5123   CRAFTED_PARAM_LIST_FIXUP (parm);
5124   decl = create_artificial_method (class_type, flags, void_type_node, 
5125                                    ctor_name, parm);
5126   fix_method_argument_names (parm, decl);
5127   /* Now, mark the artificial parameters. */
5128   DECL_FUNCTION_NAP (decl) = artificial;
5129
5130   pop_obstacks ();
5131   DECL_CONSTRUCTOR_P (decl) = 1;
5132 }
5133
5134
5135 /* Fix the constructors. This will be called right after circular
5136    references have been checked. It is necessary to fix constructors
5137    early even if no code generation will take place for that class:
5138    some generated constructor might be required by the class whose
5139    compilation triggered this one to be simply loaded.  */
5140
5141 void
5142 java_fix_constructors ()
5143 {
5144   tree current;
5145
5146   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
5147     {
5148       tree class_type = TREE_TYPE (current);
5149       int saw_ctor = 0;
5150       tree decl;
5151
5152       if (CLASS_INTERFACE (TYPE_NAME (class_type)))
5153         continue;
5154
5155       for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
5156         {
5157           if (DECL_CONSTRUCTOR_P (decl))
5158             {
5159               fix_constructors (decl);
5160               saw_ctor = 1;
5161             }
5162         }
5163
5164       /* Anonymous class constructor can't be generated that early. */
5165       if (!saw_ctor && !ANONYMOUS_CLASS_P (class_type))
5166         craft_constructor (current, NULL_TREE);
5167     }
5168 }
5169
5170 /* safe_layout_class just makes sure that we can load a class without
5171    disrupting the current_class, input_file, lineno, etc, information
5172    about the class processed currently.  */
5173
5174 void
5175 safe_layout_class (class)
5176      tree class;
5177 {
5178   tree save_current_class = current_class;
5179   const char *save_input_filename = input_filename;
5180   int save_lineno = lineno;
5181
5182   push_obstacks (&permanent_obstack, &permanent_obstack);
5183
5184   layout_class (class);
5185   pop_obstacks ();
5186
5187   current_class = save_current_class;
5188   input_filename = save_input_filename;
5189   lineno = save_lineno;
5190   CLASS_LOADED_P (class) = 1;
5191 }
5192
5193 static tree
5194 jdep_resolve_class (dep)
5195      jdep *dep;
5196 {
5197   tree decl;
5198
5199   if (JDEP_RESOLVED_P (dep))
5200     decl = JDEP_RESOLVED_DECL (dep);
5201   else
5202     {
5203       decl = resolve_class (JDEP_ENCLOSING (dep), JDEP_TO_RESOLVE (dep),
5204                             JDEP_DECL (dep), JDEP_WFL (dep));
5205       JDEP_RESOLVED (dep, decl);
5206     }
5207     
5208   if (!decl)
5209     complete_class_report_errors (dep);
5210
5211   check_inner_class_access (decl, JDEP_ENCLOSING (dep), JDEP_WFL (dep));
5212   return decl;
5213 }
5214
5215 /* Complete unsatisfied class declaration and their dependencies */
5216
5217 void
5218 java_complete_class ()
5219 {
5220   tree cclass;
5221   jdeplist *cclassd;
5222   int error_found;
5223   tree type;
5224
5225   push_obstacks (&permanent_obstack, &permanent_obstack);
5226
5227   /* Process imports */
5228   process_imports ();
5229
5230   /* Rever things so we have the right order */
5231   ctxp->class_list = nreverse (ctxp->class_list);
5232   ctxp->classd_list = reverse_jdep_list (ctxp);
5233
5234   for (cclassd = ctxp->classd_list, cclass = ctxp->class_list; 
5235        cclass && cclassd; 
5236        cclass = TREE_CHAIN (cclass), cclassd = CLASSD_CHAIN (cclassd))
5237     {
5238       jdep *dep;
5239       for (dep = CLASSD_FIRST (cclassd); dep; dep = JDEP_CHAIN (dep))
5240         {
5241           tree decl;
5242           if (!(decl = jdep_resolve_class (dep)))
5243             continue;
5244
5245           /* Now it's time to patch */
5246           switch (JDEP_KIND (dep))
5247             {
5248             case JDEP_SUPER:
5249               /* Simply patch super */
5250               if (parser_check_super (decl, JDEP_DECL (dep), JDEP_WFL (dep)))
5251                 continue;
5252               BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO 
5253                 (TREE_TYPE (JDEP_DECL (dep)))), 0)) = TREE_TYPE (decl);
5254               break;
5255
5256             case JDEP_FIELD:
5257               {
5258                 /* We do part of the job done in add_field */
5259                 tree field_decl = JDEP_DECL (dep);
5260                 tree field_type = TREE_TYPE (decl);
5261                 push_obstacks (&permanent_obstack, &permanent_obstack);
5262                 if (TREE_CODE (field_type) == RECORD_TYPE)
5263                   field_type = promote_type (field_type);
5264                 pop_obstacks ();
5265                 TREE_TYPE (field_decl) = field_type;
5266                 DECL_ALIGN (field_decl) = 0;
5267                 DECL_USER_ALIGN (field_decl) = 0;
5268                 layout_decl (field_decl, 0);
5269                 SOURCE_FRONTEND_DEBUG 
5270                   (("Completed field/var decl `%s' with `%s'",
5271                     IDENTIFIER_POINTER (DECL_NAME (field_decl)),
5272                     IDENTIFIER_POINTER (DECL_NAME (decl))));
5273                 break;
5274               }
5275             case JDEP_METHOD:   /* We start patching a method */
5276             case JDEP_METHOD_RETURN:
5277               error_found = 0;
5278               while (1)
5279                 {
5280                   if (decl)
5281                     {
5282                       type = TREE_TYPE(decl);
5283                       if (TREE_CODE (type) == RECORD_TYPE)
5284                         type = promote_type (type);
5285                       JDEP_APPLY_PATCH (dep, type);
5286                       SOURCE_FRONTEND_DEBUG 
5287                         (((JDEP_KIND (dep) == JDEP_METHOD_RETURN ?
5288                            "Completing fct `%s' with ret type `%s'":
5289                            "Completing arg `%s' with type `%s'"),
5290                           IDENTIFIER_POINTER (EXPR_WFL_NODE 
5291                                               (JDEP_DECL_WFL (dep))),
5292                           IDENTIFIER_POINTER (DECL_NAME (decl))));
5293                     }
5294                   else
5295                     error_found = 1;
5296                   dep = JDEP_CHAIN (dep);
5297                   if (JDEP_KIND (dep) == JDEP_METHOD_END)
5298                     break;
5299                   else
5300                     decl = jdep_resolve_class (dep);
5301                 }
5302               if (!error_found)
5303                 {
5304                   tree mdecl = JDEP_DECL (dep), signature;
5305                   push_obstacks (&permanent_obstack, &permanent_obstack);
5306                   /* Recompute and reset the signature, check first that
5307                      all types are now defined. If they're not,
5308                      dont build the signature. */
5309                   if (check_method_types_complete (mdecl))
5310                     {
5311                       signature = build_java_signature (TREE_TYPE (mdecl));
5312                       set_java_signature (TREE_TYPE (mdecl), signature);
5313                     }
5314                   pop_obstacks ();
5315                 }
5316               else
5317                 continue;
5318               break;
5319
5320             case JDEP_INTERFACE:
5321               if (parser_check_super_interface (decl, JDEP_DECL (dep),
5322                                                 JDEP_WFL (dep)))
5323                 continue;
5324               parser_add_interface (JDEP_DECL (dep), decl, JDEP_WFL (dep));
5325               break;
5326
5327             case JDEP_PARM:
5328             case JDEP_VARIABLE:
5329               type = TREE_TYPE(decl);
5330               if (TREE_CODE (type) == RECORD_TYPE)
5331                 type = promote_type (type);
5332               JDEP_APPLY_PATCH (dep, type);
5333               break;
5334
5335             case JDEP_TYPE:
5336               JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
5337               SOURCE_FRONTEND_DEBUG 
5338                 (("Completing a random type dependency on a '%s' node",
5339                   tree_code_name [TREE_CODE (JDEP_DECL (dep))]));
5340               break;
5341
5342             case JDEP_EXCEPTION:
5343               JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
5344               SOURCE_FRONTEND_DEBUG 
5345                 (("Completing `%s' `throws' argument node",
5346                   IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)))));
5347               break;
5348
5349             case JDEP_ANONYMOUS:
5350               patch_anonymous_class (decl, JDEP_DECL (dep), JDEP_WFL (dep));
5351               break;
5352
5353             default:
5354               fatal ("Can't handle patch code %d - java_complete_class",
5355                      JDEP_KIND (dep));
5356             }
5357         }
5358     }
5359   pop_obstacks ();
5360   return;
5361 }
5362
5363 /* Resolve class CLASS_TYPE. Handle the case of trying to resolve an
5364    array.  */
5365
5366 static tree
5367 resolve_class (enclosing, class_type, decl, cl)
5368      tree enclosing, class_type, decl, cl;
5369 {
5370   const char *name = IDENTIFIER_POINTER (TYPE_NAME (class_type));
5371   const char *base = name;
5372   tree resolved_type = TREE_TYPE (class_type);
5373   tree resolved_type_decl;
5374   
5375   if (resolved_type != NULL_TREE)
5376     {
5377       tree resolved_type_decl = TYPE_NAME (resolved_type);
5378       if (resolved_type_decl == NULL_TREE
5379           || TREE_CODE (resolved_type_decl) == IDENTIFIER_NODE)
5380         {
5381           resolved_type_decl = build_decl (TYPE_DECL,
5382                                            TYPE_NAME (class_type),
5383                                            resolved_type);
5384         }
5385       return resolved_type_decl;
5386     }
5387
5388   /* 1- Check to see if we have an array. If true, find what we really
5389      want to resolve  */
5390   while (name[0] == '[')
5391     name++;
5392   if (base != name)
5393     TYPE_NAME (class_type) = get_identifier (name);
5394
5395   /* 2- Resolve the bare type */
5396   if (!(resolved_type_decl = do_resolve_class (enclosing, class_type, 
5397                                                decl, cl)))
5398     return NULL_TREE;
5399   resolved_type = TREE_TYPE (resolved_type_decl);
5400
5401   /* 3- If we have and array, reconstruct the array down to its nesting */
5402   if (base != name)
5403     {
5404       while (base != name)
5405         {
5406           if (TREE_CODE (resolved_type) == RECORD_TYPE)
5407             resolved_type  = promote_type (resolved_type);
5408           resolved_type = build_java_array_type (resolved_type, -1);
5409           CLASS_LOADED_P (resolved_type) = 1;
5410           name--;
5411         }
5412       /* Build a fake decl for this, since this is what is expected to
5413          be returned.  */
5414       resolved_type_decl =
5415         build_decl (TYPE_DECL, TYPE_NAME (resolved_type), resolved_type);
5416       /* Figure how those two things are important for error report. FIXME */
5417       DECL_SOURCE_LINE (resolved_type_decl) = 0;
5418       DECL_SOURCE_FILE (resolved_type_decl) = input_filename;
5419       TYPE_NAME (class_type) = TYPE_NAME (resolved_type);
5420     }
5421   TREE_TYPE (class_type) = resolved_type;
5422   return resolved_type_decl;
5423 }
5424
5425 /* Effectively perform the resolution of class CLASS_TYPE. DECL or CL
5426    are used to report error messages.  */
5427
5428 tree
5429 do_resolve_class (enclosing, class_type, decl, cl)
5430      tree enclosing, class_type, decl, cl;
5431 {
5432   tree new_class_decl;
5433
5434   /* Do not try to replace TYPE_NAME (class_type) by a variable, since
5435      it is changed by find_in_imports{_on_demand} and (but it doesn't
5436      really matter) qualify_and_find */
5437
5438   /* 0- Search in the current class as an inner class */
5439
5440   /* Maybe some code here should be added to load the class or
5441      something, at least if the class isn't an inner class and ended
5442      being loaded from class file. FIXME. */
5443   while (enclosing)
5444     {
5445       tree name;
5446
5447       if ((new_class_decl = find_as_inner_class (enclosing, class_type, cl)))
5448         return new_class_decl;
5449
5450       /* Now go to the upper classes, bail out if necessary. */
5451       enclosing = CLASSTYPE_SUPER (TREE_TYPE (enclosing));
5452       if (!enclosing || enclosing == object_type_node)
5453         break;
5454       
5455       if (TREE_CODE (enclosing) == RECORD_TYPE)
5456         {
5457           enclosing = TYPE_NAME (enclosing);
5458           continue;
5459         }
5460
5461       if (TREE_CODE (enclosing) == IDENTIFIER_NODE)
5462         {
5463           BUILD_PTR_FROM_NAME (name, enclosing);
5464         }
5465       else
5466         name = enclosing;
5467       enclosing = do_resolve_class (NULL, name, NULL, NULL);
5468     }
5469
5470   /* 1- Check for the type in single imports. This will change
5471      TYPE_NAME() if something relevant is found */
5472   find_in_imports (class_type);
5473
5474   /* 2- And check for the type in the current compilation unit */
5475   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
5476     {
5477       if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
5478           !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
5479         load_class (TYPE_NAME (class_type), 0);
5480       return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5481     }
5482
5483   /* 3- Search according to the current package definition */
5484   if (!QUALIFIED_P (TYPE_NAME (class_type)))
5485     {
5486       if ((new_class_decl = qualify_and_find (class_type, ctxp->package,
5487                                              TYPE_NAME (class_type))))
5488         return new_class_decl;
5489     }
5490
5491   /* 4- Check the import on demands. Don't allow bar.baz to be
5492      imported from foo.* */
5493   if (!QUALIFIED_P (TYPE_NAME (class_type)))
5494     if (find_in_imports_on_demand (class_type))
5495       return NULL_TREE;
5496
5497   /* If found in find_in_imports_on_demant, the type has already been
5498      loaded. */
5499   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
5500     return new_class_decl;
5501
5502   /* 5- Try with a name qualified with the package name we've seen so far */
5503   if (!QUALIFIED_P (TYPE_NAME (class_type)))
5504     {
5505       tree package;
5506
5507       /* If there is a current package (ctxp->package), it's the first
5508          element of package_list and we can skip it. */
5509       for (package = (ctxp->package ? 
5510                       TREE_CHAIN (package_list) : package_list);
5511            package; package = TREE_CHAIN (package))
5512         if ((new_class_decl = qualify_and_find (class_type,
5513                                                TREE_PURPOSE (package), 
5514                                                TYPE_NAME (class_type))))
5515           return new_class_decl;
5516     }
5517
5518   /* 5- Check an other compilation unit that bears the name of type */
5519   load_class (TYPE_NAME (class_type), 0);
5520   if (check_pkg_class_access (TYPE_NAME (class_type), 
5521                               (cl ? cl : lookup_cl (decl))))
5522     return NULL_TREE;
5523
5524   /* 6- Last call for a resolution */
5525   return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5526 }
5527
5528 static tree
5529 qualify_and_find (class_type, package, name)
5530      tree class_type, package, name;
5531 {
5532   tree new_qualified = merge_qualified_name (package, name);
5533   tree new_class_decl;
5534
5535   if (!IDENTIFIER_CLASS_VALUE (new_qualified))
5536     load_class (new_qualified, 0);
5537   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (new_qualified)))
5538     {
5539       if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
5540           !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
5541         load_class (new_qualified, 0);
5542       TYPE_NAME (class_type) = new_qualified;
5543       return IDENTIFIER_CLASS_VALUE (new_qualified);
5544     }
5545   return NULL_TREE;
5546 }
5547
5548 /* Resolve NAME and lay it out (if not done and if not the current
5549    parsed class). Return a decl node. This function is meant to be
5550    called when type resolution is necessary during the walk pass.  */
5551
5552 static tree
5553 resolve_and_layout (something, cl)
5554      tree something;
5555      tree cl;
5556 {
5557   tree decl;
5558
5559   /* Don't do that on the current class */
5560   if (something == current_class)
5561     return TYPE_NAME (current_class);
5562
5563   /* Don't do anything for void and other primitive types */
5564   if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
5565     return NULL_TREE;
5566
5567   /* Pointer types can be reall pointer types or fake pointers. When
5568      finding a real pointer, recheck for primitive types */
5569   if (TREE_CODE (something) == POINTER_TYPE)
5570     {
5571       if (TREE_TYPE (something))
5572         {
5573           something = TREE_TYPE (something);
5574           if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
5575             return NULL_TREE;
5576         }
5577       else
5578         something = TYPE_NAME (something);
5579     }
5580
5581   /* Don't do anything for arrays of primitive types */
5582   if (TREE_CODE (something) == RECORD_TYPE && TYPE_ARRAY_P (something)
5583       && JPRIMITIVE_TYPE_P (TYPE_ARRAY_ELEMENT (something)))
5584     return NULL_TREE;
5585
5586   /* Something might be a WFL */
5587   if (TREE_CODE (something) == EXPR_WITH_FILE_LOCATION)
5588     something = EXPR_WFL_NODE (something);
5589
5590   /* Otherwise, if something is not and IDENTIFIER_NODE, it can be a a
5591      TYPE_DECL or a real TYPE */
5592   else if (TREE_CODE (something) != IDENTIFIER_NODE)
5593     something = (TREE_CODE (TYPE_NAME (something)) == TYPE_DECL ?
5594             DECL_NAME (TYPE_NAME (something)) : TYPE_NAME (something));
5595
5596   if (!(decl = resolve_no_layout (something, cl)))
5597     return NULL_TREE;
5598
5599   /* Resolve and layout if necessary */
5600   layout_class_methods (TREE_TYPE (decl));
5601   /* Check methods, but only once */
5602   if (CLASS_FROM_SOURCE_P (TREE_TYPE (decl)) 
5603       && !CLASS_LOADED_P (TREE_TYPE (decl)))
5604     CHECK_METHODS (decl);
5605   if (TREE_TYPE (decl) != current_class && !CLASS_LOADED_P (TREE_TYPE (decl)))
5606     safe_layout_class (TREE_TYPE (decl));
5607
5608   return decl;
5609 }
5610
5611 /* Resolve a class, returns its decl but doesn't perform any
5612    layout. The current parsing context is saved and restored */
5613
5614 static tree
5615 resolve_no_layout (name, cl)
5616      tree name, cl;
5617 {
5618   tree ptr, decl;
5619   BUILD_PTR_FROM_NAME (ptr, name);
5620   java_parser_context_save_global ();
5621   decl = resolve_class (TYPE_NAME (current_class), ptr, NULL_TREE, cl);
5622   java_parser_context_restore_global ();
5623   
5624   return decl;
5625 }
5626
5627 /* Called when reporting errors. Skip leader '[' in a complex array
5628    type description that failed to be resolved.  */
5629
5630 static const char *
5631 purify_type_name (name)
5632      const char *name;
5633 {
5634   while (*name && *name == '[')
5635     name++;
5636   return name;
5637 }
5638
5639 /* The type CURRENT refers to can't be found. We print error messages.  */
5640
5641 static void
5642 complete_class_report_errors (dep)
5643      jdep *dep;
5644 {
5645   const char *name;
5646
5647   if (!JDEP_WFL (dep))
5648     return;
5649
5650   name = IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)));
5651   switch (JDEP_KIND (dep))
5652     {
5653     case JDEP_SUPER:
5654       parse_error_context  
5655         (JDEP_WFL (dep), "Superclass `%s' of class `%s' not found",
5656          purify_type_name (name),
5657          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5658       break;
5659     case JDEP_FIELD:
5660       parse_error_context
5661         (JDEP_WFL (dep), "Type `%s' not found in declaration of field `%s'",
5662          purify_type_name (name),
5663          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5664       break;
5665     case JDEP_METHOD:           /* Covers arguments */
5666       parse_error_context
5667         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the argument `%s' of method `%s'",
5668          purify_type_name (name),
5669          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))),
5670          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_MISC (dep))));
5671       break;
5672     case JDEP_METHOD_RETURN:    /* Covers return type */
5673       parse_error_context
5674         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the return type of method `%s'", 
5675          purify_type_name (name),
5676          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))));
5677       break;
5678     case JDEP_INTERFACE:
5679       parse_error_context
5680         (JDEP_WFL (dep), "Superinterface `%s' of %s `%s' not found",
5681          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))),
5682          (CLASS_OR_INTERFACE (JDEP_DECL (dep), "class", "interface")),
5683          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5684       break;
5685     case JDEP_VARIABLE:
5686       parse_error_context
5687         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the local variable `%s'", 
5688          purify_type_name (IDENTIFIER_POINTER 
5689                            (EXPR_WFL_NODE (JDEP_WFL (dep)))),
5690          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5691       break;
5692     case JDEP_EXCEPTION:        /* As specified by `throws' */
5693       parse_error_context 
5694           (JDEP_WFL (dep), "Class `%s' not found in `throws'",
5695          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))));
5696       break;
5697     default:
5698       /* Fix for -Wall. Just break doing nothing. The error will be
5699          caught later */
5700       break;
5701     }
5702 }
5703
5704 /* Return a static string containing the DECL prototype string. If
5705    DECL is a constructor, use the class name instead of the form
5706    <init> */
5707
5708 static const char *
5709 get_printable_method_name (decl)
5710      tree decl;
5711 {
5712   const char *to_return;
5713   tree name = NULL_TREE;
5714
5715   if (DECL_CONSTRUCTOR_P (decl))
5716     {
5717       name = DECL_NAME (decl);
5718       DECL_NAME (decl) = DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)));
5719     }
5720       
5721   to_return = lang_printable_name (decl, 0);
5722   if (DECL_CONSTRUCTOR_P (decl))
5723     DECL_NAME (decl) = name;
5724   
5725   return to_return;
5726 }
5727
5728 /* Reinstall the proper DECL_NAME on METHOD. Return 0 if the method
5729    nevertheless needs to be verfied, 1 otherwise.  */
5730
5731 static int
5732 reset_method_name (method)
5733      tree method;
5734 {
5735   if (!DECL_CLINIT_P (method) && !DECL_FINIT_P (method))
5736     {
5737       /* NAME is just the plain name when Object is being defined */
5738       if (DECL_CONTEXT (method) != object_type_node)
5739         DECL_NAME (method) = (DECL_CONSTRUCTOR_P (method) ? 
5740                               init_identifier_node : GET_METHOD_NAME (method));
5741       return 0;
5742     }
5743   else 
5744     return 1;
5745 }
5746
5747 /* Return the name of METHOD_DECL, when DECL_NAME is a WFL */
5748
5749 tree
5750 java_get_real_method_name (method_decl)
5751      tree method_decl;
5752 {
5753   tree method_name = DECL_NAME (method_decl);
5754   if (DECL_CONSTRUCTOR_P (method_decl))
5755     return init_identifier_node;
5756
5757   /* Explain here why METHOD_DECL doesn't have the DECL_CONSTRUCTUR_P
5758      and still can be a constructor. FIXME */
5759
5760   /* Don't confuse method only bearing the name of their class as
5761      constructors */
5762   else if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (method_decl))
5763            && ctxp
5764            && GET_CPC_UN () == EXPR_WFL_NODE (method_name)
5765            && get_access_flags_from_decl (method_decl) <= ACC_PROTECTED
5766            && TREE_TYPE (TREE_TYPE (method_decl)) == void_type_node)
5767     return init_identifier_node;
5768   else
5769     return EXPR_WFL_NODE (method_name);
5770 }
5771
5772 /* Track method being redefined inside the same class. As a side
5773    effect, set DECL_NAME to an IDENTIFIER (prior entering this
5774    function it's a FWL, so we can track errors more accurately.)  */
5775
5776 static int
5777 check_method_redefinition (class, method)
5778      tree class, method;
5779 {
5780   tree redef, name;
5781   tree cl = DECL_NAME (method);
5782   tree sig = TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (method));
5783   /* decl name of artificial <clinit> and $finit$ doesn't need to be
5784      fixed and checked */
5785
5786   /* Reset the method name before running the check. If it returns 1,
5787      the method doesn't need to be verified with respect to method
5788      redeclaration and we return 0 */
5789   if (reset_method_name (method))
5790     return 0;
5791
5792   name = DECL_NAME (method);
5793   for (redef = TYPE_METHODS (class); redef; redef = TREE_CHAIN (redef))
5794     {
5795       if (redef == method)
5796         break;
5797       if (DECL_NAME (redef) == name 
5798           && sig == TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (redef)))
5799         {
5800           parse_error_context 
5801             (cl, "Duplicate %s declaration `%s'",
5802              (DECL_CONSTRUCTOR_P (redef) ? "constructor" : "method"),
5803              get_printable_method_name (redef));
5804           return 1;
5805         }
5806     }
5807   return 0;
5808 }
5809
5810 static void
5811 check_abstract_method_definitions (do_interface, class_decl, type)
5812      int do_interface;
5813      tree class_decl, type;
5814 {
5815   tree class = TREE_TYPE (class_decl);
5816   tree method, end_type;
5817
5818   end_type = (do_interface ? object_type_node : type);
5819   for (method = TYPE_METHODS (type); method; method = TREE_CHAIN (method))
5820     {
5821       tree other_super, other_method, method_sig, method_name;
5822       int found = 0;
5823       int end_type_reached = 0;
5824       
5825       if (!METHOD_ABSTRACT (method) || METHOD_FINAL (method))
5826         continue;
5827       
5828       /* Now verify that somewhere in between TYPE and CLASS,
5829          abstract method METHOD gets a non abstract definition
5830          that is inherited by CLASS.  */
5831       
5832       method_sig = build_java_signature (TREE_TYPE (method));
5833       method_name = DECL_NAME (method);
5834       if (TREE_CODE (method_name) == EXPR_WITH_FILE_LOCATION)
5835         method_name = EXPR_WFL_NODE (method_name);
5836
5837       other_super = class;
5838       do {
5839         if (other_super == end_type)
5840           end_type_reached = 1;
5841         
5842         /* Method search */
5843         for (other_method = TYPE_METHODS (other_super); other_method;
5844             other_method = TREE_CHAIN (other_method))
5845           {
5846             tree s = build_java_signature (TREE_TYPE (other_method));
5847             tree other_name = DECL_NAME (other_method);
5848             
5849             if (TREE_CODE (other_name) == EXPR_WITH_FILE_LOCATION)
5850               other_name = EXPR_WFL_NODE (other_name);
5851             if (!DECL_CLINIT_P (other_method)
5852                 && !DECL_CONSTRUCTOR_P (other_method)
5853                 && method_name == other_name
5854                 && method_sig == s
5855                 && !METHOD_ABSTRACT (other_method))
5856              {
5857                found = 1;
5858                break;
5859              }
5860           }
5861         other_super = CLASSTYPE_SUPER (other_super);
5862       } while (!end_type_reached);
5863  
5864       /* Report that abstract METHOD didn't find an implementation
5865          that CLASS can use. */
5866       if (!found)
5867         {
5868           char *t = xstrdup (lang_printable_name 
5869                             (TREE_TYPE (TREE_TYPE (method)), 0));
5870           tree ccn = DECL_NAME (TYPE_NAME (DECL_CONTEXT (method)));
5871           tree saved_wfl = NULL_TREE;
5872           
5873           if (TREE_CODE (DECL_NAME (method)) == EXPR_WITH_FILE_LOCATION)
5874             {
5875               saved_wfl = DECL_NAME (method);
5876               DECL_NAME (method) = EXPR_WFL_NODE (DECL_NAME (method));
5877             }
5878           
5879           parse_error_context 
5880             (lookup_cl (class_decl),
5881              "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",
5882              IDENTIFIER_POINTER (DECL_NAME (class_decl)),
5883              t, lang_printable_name (method, 0), 
5884              (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))) ? 
5885               "interface" : "class"),
5886              IDENTIFIER_POINTER (ccn),
5887              (CLASS_INTERFACE (class_decl) ? "interface" : "class"),
5888              IDENTIFIER_POINTER (DECL_NAME (class_decl)));
5889           
5890           free (t);
5891           
5892           if (saved_wfl)
5893             DECL_NAME (method) = saved_wfl;
5894         }
5895     }
5896 }
5897
5898 /* Check that CLASS_DECL somehow implements all inherited abstract
5899    methods.  */
5900
5901 static void
5902 java_check_abstract_method_definitions (class_decl)
5903      tree class_decl;
5904 {
5905   tree class = TREE_TYPE (class_decl);
5906   tree super, vector;
5907   int i;
5908
5909   if (CLASS_ABSTRACT (class_decl))
5910     return;
5911
5912   /* Check for inherited types */
5913   super = class;
5914   do {
5915     super = CLASSTYPE_SUPER (super);
5916     check_abstract_method_definitions (0, class_decl, super);
5917   } while (super != object_type_node);
5918
5919   /* Check for implemented interfaces. */
5920   vector = TYPE_BINFO_BASETYPES (class);
5921   for (i = 1; i < TREE_VEC_LENGTH (vector); i++)
5922     {
5923       super = BINFO_TYPE (TREE_VEC_ELT (vector, i));
5924       check_abstract_method_definitions (1, class_decl, super);
5925     }
5926 }
5927
5928 /* Check all the types method DECL uses and return 1 if all of them
5929    are now complete, 0 otherwise. This is used to check whether its
5930    safe to build a method signature or not.  */
5931
5932 static int
5933 check_method_types_complete (decl)
5934      tree decl;
5935 {
5936   tree type = TREE_TYPE (decl);
5937   tree args;
5938
5939   if (!INCOMPLETE_TYPE_P (TREE_TYPE (type)))
5940     return 0;
5941   
5942   args = TYPE_ARG_TYPES (type);
5943   if (TREE_CODE (type) == METHOD_TYPE)
5944     args = TREE_CHAIN (args);
5945   for (; args != end_params_node; args = TREE_CHAIN (args))
5946     if (INCOMPLETE_TYPE_P (TREE_VALUE (args)))
5947       return 0;
5948
5949   return 1;
5950 }
5951
5952 /* Check all the methods of CLASS_DECL. Methods are first completed
5953    then checked according to regular method existance rules.  If no
5954    constructor for CLASS_DECL were encountered, then build its
5955    declaration.  */
5956
5957 static void
5958 java_check_regular_methods (class_decl)
5959      tree class_decl;
5960 {
5961   int saw_constructor = ANONYMOUS_CLASS_P (TREE_TYPE (class_decl));
5962   tree method;
5963   tree class = CLASS_TO_HANDLE_TYPE (TREE_TYPE (class_decl));
5964   tree saved_found_wfl = NULL_TREE, found = NULL_TREE;
5965   tree mthrows;
5966
5967   /* It is not necessary to check methods defined in java.lang.Object */
5968   if (class == object_type_node)
5969     return;
5970
5971   if (!TYPE_NVIRTUALS (class))
5972     TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
5973
5974   /* Should take interfaces into account. FIXME */
5975   for (method = TYPE_METHODS (class); method; method = TREE_CHAIN (method))
5976     {
5977       tree sig;
5978       tree method_wfl = DECL_NAME (method);
5979       int aflags;
5980
5981       /* If we previously found something and its name was saved,
5982          reinstall it now */
5983       if (found && saved_found_wfl)
5984         {
5985           DECL_NAME (found) = saved_found_wfl;
5986           saved_found_wfl = NULL_TREE;
5987         }
5988
5989       /* Check for redefinitions */
5990       if (check_method_redefinition (class, method))
5991         continue;
5992
5993       /* If we see one constructor a mark so we don't generate the
5994          default one. Also skip other verifications: constructors
5995          can't be inherited hence hiden or overriden */
5996      if (DECL_CONSTRUCTOR_P (method))
5997        {
5998          saw_constructor = 1;
5999          continue;
6000        }
6001
6002       /* We verify things thrown by the method. They must inherits from
6003          java.lang.Throwable */
6004       for (mthrows = DECL_FUNCTION_THROWS (method);
6005            mthrows; mthrows = TREE_CHAIN (mthrows))
6006         {
6007           if (!inherits_from_p (TREE_VALUE (mthrows), throwable_type_node))
6008             parse_error_context 
6009               (TREE_PURPOSE (mthrows), "Class `%s' in `throws' clause must be a subclass of class `java.lang.Throwable'",
6010                IDENTIFIER_POINTER 
6011                  (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))));
6012         }
6013
6014       sig = build_java_argument_signature (TREE_TYPE (method));
6015       found = lookup_argument_method2 (class, DECL_NAME (method), sig);
6016
6017       /* Inner class can't declare static methods */
6018       if (METHOD_STATIC (method) && !TOPLEVEL_CLASS_DECL_P (class_decl))
6019         {
6020           char *t = xstrdup (lang_printable_name (class, 0));
6021           parse_error_context 
6022             (method_wfl, "Method `%s' can't be static in inner class `%s'. Only members of interfaces and top-level classes can be static",
6023              lang_printable_name (method, 0), t);
6024           free (t);
6025         }
6026
6027       /* Nothing overrides or it's a private method. */
6028       if (!found)
6029         continue;
6030       if (METHOD_PRIVATE (found))
6031         {
6032           found = NULL_TREE;
6033           continue;
6034         }
6035
6036       /* If found wasn't verified, it's DECL_NAME won't be set properly. 
6037          We set it temporarily for the sake of the error report. */
6038       saved_found_wfl = DECL_NAME (found);
6039       reset_method_name (found);
6040
6041       /* If `found' is declared in an interface, make sure the
6042          modifier matches. */
6043       if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (found))) 
6044           && clinit_identifier_node != DECL_NAME (found)
6045           && !METHOD_PUBLIC (method))
6046         {
6047           tree found_decl = TYPE_NAME (DECL_CONTEXT (found));
6048           parse_error_context (method_wfl, "Class `%s' must override `%s' with a public method in order to implement interface `%s'",
6049                                IDENTIFIER_POINTER (DECL_NAME (class_decl)),
6050                                lang_printable_name (method, 0),
6051                                IDENTIFIER_POINTER (DECL_NAME (found_decl)));
6052         }
6053
6054       /* Can't override a method with the same name and different return
6055          types. */
6056       if (TREE_TYPE (TREE_TYPE (found)) != TREE_TYPE (TREE_TYPE (method)))
6057         {
6058           char *t = xstrdup 
6059             (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
6060           parse_error_context 
6061             (method_wfl,
6062              "Method `%s' was defined with return type `%s' in class `%s'", 
6063              lang_printable_name (found, 0), t,
6064              IDENTIFIER_POINTER 
6065                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6066           free (t);
6067         }
6068
6069       aflags = get_access_flags_from_decl (found);
6070       /* If the method has default, access in an other package, then
6071          issue a warning that the current method doesn't override the
6072          one that was found elsewhere. Do not issue this warning when
6073          the match was found in java.lang.Object.  */
6074       if (DECL_CONTEXT (found) != object_type_node
6075           && ((aflags & ACC_VISIBILITY) == 0)
6076           && !class_in_current_package (DECL_CONTEXT (found))
6077           && !DECL_CLINIT_P (found)
6078           && flag_not_overriding)
6079         {
6080           parse_warning_context 
6081             (method_wfl, "Method `%s' in class `%s' does not override the corresponding method in class `%s', which is private to a different package",
6082              lang_printable_name (found, 0),
6083              IDENTIFIER_POINTER (DECL_NAME (class_decl)),
6084              IDENTIFIER_POINTER (DECL_NAME 
6085                                  (TYPE_NAME (DECL_CONTEXT (found)))));
6086           continue;
6087         }
6088
6089       /* Can't override final. Can't override static. */
6090       if (METHOD_FINAL (found) || METHOD_STATIC (found))
6091         {
6092           /* Static *can* override static */
6093           if (METHOD_STATIC (found) && METHOD_STATIC (method))
6094             continue;
6095           parse_error_context 
6096             (method_wfl,
6097              "%s methods can't be overriden. Method `%s' is %s in class `%s'",
6098              (METHOD_FINAL (found) ? "Final" : "Static"),
6099              lang_printable_name (found, 0),
6100              (METHOD_FINAL (found) ? "final" : "static"),
6101              IDENTIFIER_POINTER
6102                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6103           continue;
6104         }
6105
6106       /* Static method can't override instance method. */
6107       if (METHOD_STATIC (method))
6108         {
6109           parse_error_context 
6110             (method_wfl,
6111              "Instance methods can't be overriden by a static method. Method `%s' is an instance method in class `%s'",
6112              lang_printable_name (found, 0),
6113              IDENTIFIER_POINTER
6114                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6115           continue;
6116         }
6117
6118       /* - Overriding/hiding public must be public
6119          - Overriding/hiding protected must be protected or public
6120          - If the overriden or hidden method has default (package)
6121            access, then the overriding or hiding method must not be
6122            private; otherwise, a compile-time error occurs.  If
6123            `found' belongs to an interface, things have been already
6124            taken care of.  */
6125       if (!CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (found)))
6126           && ((METHOD_PUBLIC (found) && !METHOD_PUBLIC (method))
6127               || (METHOD_PROTECTED (found) 
6128                   && !(METHOD_PUBLIC (method) || METHOD_PROTECTED (method)))
6129               || (!(aflags & (ACC_PUBLIC | ACC_PRIVATE | ACC_STATIC))
6130                   && METHOD_PRIVATE (method))))
6131         {
6132           parse_error_context 
6133             (method_wfl,
6134              "Methods can't be overridden to be more private. Method `%s' is not %s in class `%s'", lang_printable_name (method, 0),
6135              (METHOD_PUBLIC (method) ? "public" : 
6136               (METHOD_PRIVATE (method) ? "private" : "protected")),
6137              IDENTIFIER_POINTER (DECL_NAME 
6138                                  (TYPE_NAME (DECL_CONTEXT (found)))));
6139           continue;
6140         }
6141
6142       /* Overriding methods must have compatible `throws' clauses on checked
6143          exceptions, if any */
6144       check_throws_clauses (method, method_wfl, found);
6145
6146       /* Inheriting multiple methods with the same signature. FIXME */
6147     }
6148   
6149   /* Don't forget eventual pending found and saved_found_wfl. Take
6150      into account that we might have exited because we saw an
6151      artificial method as the last entry. */
6152
6153   if (found && !DECL_ARTIFICIAL (found) && saved_found_wfl)
6154     DECL_NAME (found) = saved_found_wfl;
6155
6156   if (!TYPE_NVIRTUALS (class))
6157     TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
6158
6159   /* Search for inherited abstract method not yet implemented in this
6160      class.  */
6161   java_check_abstract_method_definitions (class_decl);
6162
6163   if (!saw_constructor)
6164     fatal ("No constructor found");
6165 }
6166
6167 /* Return a non zero value if the `throws' clause of METHOD (if any)
6168    is incompatible with the `throws' clause of FOUND (if any).  */
6169
6170 static void
6171 check_throws_clauses (method, method_wfl, found)
6172      tree method, method_wfl, found;
6173 {
6174   tree mthrows, fthrows;
6175
6176   /* Can't check these things with class loaded from bytecode. FIXME */
6177   if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (found)))
6178     return;
6179
6180   for (mthrows = DECL_FUNCTION_THROWS (method);
6181        mthrows; mthrows = TREE_CHAIN (mthrows))
6182     {
6183       /* We don't verify unchecked expressions */
6184       if (IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (mthrows)))
6185         continue;
6186       /* Checked expression must be compatible */
6187       for (fthrows = DECL_FUNCTION_THROWS (found); 
6188            fthrows; fthrows = TREE_CHAIN (fthrows))
6189         if (inherits_from_p (TREE_VALUE (mthrows), TREE_VALUE (fthrows)))
6190           break;
6191       if (!fthrows)
6192         {
6193           parse_error_context 
6194             (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'",
6195              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))),
6196              lang_printable_name (found, 0),
6197              IDENTIFIER_POINTER 
6198                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6199         }
6200     }
6201 }
6202
6203 /* Check abstract method of interface INTERFACE */
6204
6205 static void
6206 java_check_abstract_methods (interface_decl)
6207      tree interface_decl;
6208 {
6209   int i, n;
6210   tree method, basetype_vec, found;
6211   tree interface = TREE_TYPE (interface_decl);
6212
6213   for (method = TYPE_METHODS (interface); method; method = TREE_CHAIN (method))
6214     {
6215       tree method_wfl = DECL_NAME (method);
6216
6217       /* 2- Check for double definition inside the defining interface */
6218       if (check_method_redefinition (interface, method))
6219         continue;
6220
6221       /* 3- Overriding is OK as far as we preserve the return type and
6222          the thrown exceptions (FIXME) */
6223       found = lookup_java_interface_method2 (interface, method);
6224       if (found)
6225         {
6226           char *t;
6227           tree saved_found_wfl = DECL_NAME (found);
6228           reset_method_name (found);
6229           t = xstrdup (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
6230           parse_error_context 
6231             (method_wfl,
6232              "Method `%s' was defined with return type `%s' in class `%s'",
6233              lang_printable_name (found, 0), t,
6234              IDENTIFIER_POINTER 
6235                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6236           free (t);
6237           DECL_NAME (found) = saved_found_wfl;
6238           continue;
6239         }
6240     }
6241
6242   /* 4- Inherited methods can't differ by their returned types */
6243   if (!(basetype_vec = TYPE_BINFO_BASETYPES (interface)))
6244     return;
6245   n = TREE_VEC_LENGTH (basetype_vec);
6246   for (i = 0; i < n; i++)
6247     {
6248       tree sub_interface_method, sub_interface;
6249       tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
6250       if (!vec_elt)
6251         continue;
6252       sub_interface = BINFO_TYPE (vec_elt);
6253       for (sub_interface_method = TYPE_METHODS (sub_interface); 
6254            sub_interface_method;
6255            sub_interface_method = TREE_CHAIN (sub_interface_method))
6256         {
6257           found = lookup_java_interface_method2 (interface, 
6258                                                  sub_interface_method);
6259           if (found && (found != sub_interface_method))
6260             {
6261               tree saved_found_wfl = DECL_NAME (found);
6262               reset_method_name (found);
6263               parse_error_context 
6264                 (lookup_cl (sub_interface_method),
6265                  "Interface `%s' inherits method `%s' from interface `%s'. This method is redefined with a different return type in interface `%s'",
6266                  IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (interface))),
6267                  lang_printable_name (found, 0),
6268                  IDENTIFIER_POINTER 
6269                    (DECL_NAME (TYPE_NAME 
6270                                (DECL_CONTEXT (sub_interface_method)))),
6271                  IDENTIFIER_POINTER 
6272                    (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6273               DECL_NAME (found) = saved_found_wfl;
6274             }
6275         }
6276     }
6277 }
6278
6279 /* Lookup methods in interfaces using their name and partial
6280    signature. Return a matching method only if their types differ.  */
6281
6282 static tree
6283 lookup_java_interface_method2 (class, method_decl)
6284      tree class, method_decl;
6285 {
6286   int i, n;
6287   tree basetype_vec = TYPE_BINFO_BASETYPES (class), to_return;
6288
6289   if (!basetype_vec)
6290     return NULL_TREE;
6291
6292   n = TREE_VEC_LENGTH (basetype_vec);
6293   for (i = 0; i < n; i++)
6294     {
6295       tree vec_elt = TREE_VEC_ELT (basetype_vec, i), to_return;
6296       if ((BINFO_TYPE (vec_elt) != object_type_node)
6297           && (to_return = 
6298               lookup_java_method2 (BINFO_TYPE (vec_elt), method_decl, 1)))
6299         return to_return;
6300     }
6301   for (i = 0; i < n; i++)
6302     {
6303       to_return = lookup_java_interface_method2 
6304         (BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i)), method_decl);
6305       if (to_return)
6306         return to_return;
6307     }
6308
6309   return NULL_TREE;
6310 }
6311
6312 /* Lookup method using their name and partial signature. Return a
6313    matching method only if their types differ.  */
6314
6315 static tree
6316 lookup_java_method2 (clas, method_decl, do_interface)
6317      tree clas, method_decl;
6318      int do_interface;
6319 {
6320   tree method, method_signature, method_name, method_type, name;
6321
6322   method_signature = build_java_argument_signature (TREE_TYPE (method_decl));
6323   name = DECL_NAME (method_decl);
6324   method_name = (TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ? 
6325                  EXPR_WFL_NODE (name) : name);
6326   method_type = TREE_TYPE (TREE_TYPE (method_decl));
6327
6328   while (clas != NULL_TREE)
6329     {
6330       for (method = TYPE_METHODS (clas);
6331            method != NULL_TREE;  method = TREE_CHAIN (method))
6332         {
6333           tree method_sig = build_java_argument_signature (TREE_TYPE (method));
6334           tree name = DECL_NAME (method);
6335           if ((TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
6336                EXPR_WFL_NODE (name) : name) == method_name
6337               && method_sig == method_signature 
6338               && TREE_TYPE (TREE_TYPE (method)) != method_type)
6339             return method;
6340         }
6341       clas = (do_interface ? NULL_TREE : CLASSTYPE_SUPER (clas));
6342     }
6343   return NULL_TREE;
6344 }
6345
6346 /* Return the line that matches DECL line number, and try its best to
6347    position the column number. Used during error reports.  */
6348
6349 static tree
6350 lookup_cl (decl)
6351      tree decl;
6352 {
6353   static tree cl = NULL_TREE;
6354   char *line, *found;
6355   
6356   if (!decl)
6357     return NULL_TREE;
6358
6359   if (cl == NULL_TREE)
6360     cl = build_expr_wfl (NULL_TREE, NULL, 0, 0);
6361
6362   EXPR_WFL_FILENAME_NODE (cl) = get_identifier (DECL_SOURCE_FILE (decl));
6363   EXPR_WFL_SET_LINECOL (cl, DECL_SOURCE_LINE_FIRST (decl), -1);
6364
6365   line = java_get_line_col (IDENTIFIER_POINTER (EXPR_WFL_FILENAME_NODE (cl)),
6366                             EXPR_WFL_LINENO (cl), EXPR_WFL_COLNO (cl));
6367
6368   found = strstr ((const char *)line, 
6369                   (const char *)IDENTIFIER_POINTER (DECL_NAME (decl)));
6370   if (found)
6371     EXPR_WFL_SET_LINECOL (cl, EXPR_WFL_LINENO (cl), found - line);
6372
6373   return cl;
6374 }
6375
6376 /* Look for a simple name in the single-type import list */
6377
6378 static tree
6379 find_name_in_single_imports (name)
6380      tree name;
6381 {
6382   tree node;
6383
6384   for (node = ctxp->import_list; node; node = TREE_CHAIN (node))
6385     if (TREE_VALUE (node) == name)
6386       return (EXPR_WFL_NODE (TREE_PURPOSE (node)));
6387
6388   return NULL_TREE;
6389 }
6390
6391 /* Process all single-type import. */
6392
6393 static int
6394 process_imports ()
6395 {
6396   tree import;
6397   int error_found;
6398
6399   for (import = ctxp->import_list; import; import = TREE_CHAIN (import))
6400     {
6401       tree to_be_found = EXPR_WFL_NODE (TREE_PURPOSE (import));
6402
6403       /* Don't load twice something already defined. */
6404       if (IDENTIFIER_CLASS_VALUE (to_be_found))
6405         continue;
6406       QUALIFIED_P (to_be_found) = 1;
6407       load_class (to_be_found, 0);
6408       error_found =
6409         check_pkg_class_access (to_be_found, TREE_PURPOSE (import));
6410       if (!IDENTIFIER_CLASS_VALUE (to_be_found))
6411         {
6412           parse_error_context (TREE_PURPOSE (import),
6413                                "Class or interface `%s' not found in import",
6414                                IDENTIFIER_POINTER (to_be_found));
6415           return 1;
6416         }
6417       if (error_found)
6418         return 1;
6419     }
6420   return 0;
6421 }
6422
6423 /* Possibly find and mark a class imported by a single-type import
6424    statement.  */
6425
6426 static void
6427 find_in_imports (class_type)
6428      tree class_type;
6429 {
6430   tree import;
6431
6432   for (import = ctxp->import_list; import; import = TREE_CHAIN (import))
6433     if (TREE_VALUE (import) == TYPE_NAME (class_type))
6434       {
6435         TYPE_NAME (class_type) = EXPR_WFL_NODE (TREE_PURPOSE (import));
6436         QUALIFIED_P (TYPE_NAME (class_type)) = 1;
6437       }
6438 }
6439
6440 static int
6441 note_possible_classname (name, len)
6442      const char *name;
6443      int len;
6444 {
6445   tree node;
6446   if (len > 5 && strncmp (&name [len-5], ".java", 5) == 0)
6447     len = len - 5;
6448   else if (len > 6 && strncmp (&name [len-6], ".class", 6) == 0)
6449     len = len - 6;
6450   else
6451     return 0;
6452   node = ident_subst (name, len, "", '/', '.', "");
6453   IS_A_CLASSFILE_NAME (node) = 1; /* Or soon to be */
6454   QUALIFIED_P (node) = strchr (name, '/') ? 1 : 0;
6455   return 1;
6456 }
6457
6458 /* Read a import directory, gathering potential match for further type
6459    references. Indifferently reads a filesystem or a ZIP archive
6460    directory.  */
6461
6462 static void
6463 read_import_dir (wfl)
6464      tree wfl;
6465 {
6466   tree package_id = EXPR_WFL_NODE (wfl);
6467   const char *package_name = IDENTIFIER_POINTER (package_id);
6468   int package_length = IDENTIFIER_LENGTH (package_id);
6469   DIR *dirp = NULL;
6470   JCF *saved_jcf = current_jcf;
6471
6472   int found = 0;
6473   int k;
6474   void *entry;
6475   struct buffer filename[1];
6476
6477
6478   if (IS_AN_IMPORT_ON_DEMAND_P (package_id))
6479     return;
6480   IS_AN_IMPORT_ON_DEMAND_P (package_id) = 1;
6481
6482   BUFFER_INIT (filename);
6483   buffer_grow (filename, package_length + 100);
6484
6485   for (entry = jcf_path_start (); entry != NULL; entry = jcf_path_next (entry))
6486     {
6487       const char *entry_name = jcf_path_name (entry);
6488       int entry_length = strlen (entry_name);
6489       if (jcf_path_is_zipfile (entry))
6490         {
6491           ZipFile *zipf;
6492           buffer_grow (filename, entry_length);
6493           memcpy (filename->data, entry_name, entry_length - 1);
6494           filename->data[entry_length-1] = '\0';
6495           zipf = opendir_in_zip (filename->data, jcf_path_is_system (entry));
6496           if (zipf == NULL)
6497             error ("malformed .zip archive in CLASSPATH: %s", entry_name);
6498           else
6499             {
6500               ZipDirectory *zipd = (ZipDirectory *) zipf->central_directory;
6501               BUFFER_RESET (filename);
6502               for (k = 0; k < package_length; k++)
6503                 {
6504                   char ch = package_name[k];
6505                   *filename->ptr++ = ch == '.' ? '/' : ch;
6506                 }
6507               *filename->ptr++ = '/';
6508
6509               for (k = 0; k < zipf->count;  k++, zipd = ZIPDIR_NEXT (zipd))
6510                 {
6511                   const char *current_entry = ZIPDIR_FILENAME (zipd);
6512                   int current_entry_len = zipd->filename_length;
6513
6514                   if (current_entry_len >= BUFFER_LENGTH (filename)
6515                       && strncmp (filename->data, current_entry, 
6516                                   BUFFER_LENGTH (filename)) != 0)
6517                     continue;
6518                   found |= note_possible_classname (current_entry,
6519                                                     current_entry_len);
6520                 }
6521             }
6522         }
6523       else
6524         {
6525           BUFFER_RESET (filename);
6526           buffer_grow (filename, entry_length + package_length + 4);
6527           strcpy (filename->data, entry_name);
6528           filename->ptr = filename->data + entry_length;
6529           for (k = 0; k < package_length; k++)
6530             {
6531               char ch = package_name[k];
6532               *filename->ptr++ = ch == '.' ? '/' : ch;
6533             }
6534           *filename->ptr = '\0';
6535
6536           dirp = opendir (filename->data);
6537           if (dirp == NULL)
6538             continue;
6539           *filename->ptr++ = '/';
6540           for (;;)
6541             {
6542               int len; 
6543               const char *d_name;
6544               struct dirent *direntp = readdir (dirp);
6545               if (!direntp)
6546                 break;
6547               d_name = direntp->d_name;
6548               len = strlen (direntp->d_name);
6549               buffer_grow (filename, len+1);
6550               strcpy (filename->ptr, d_name);
6551               found |= note_possible_classname (filename->data + entry_length,
6552                                                 package_length+len+1);
6553             }
6554           if (dirp)
6555             closedir (dirp);
6556         }
6557     }
6558
6559   free (filename->data);
6560
6561   /* Here we should have a unified way of retrieving an entry, to be
6562      indexed. */
6563   if (!found)
6564     {
6565       static int first = 1;
6566       if (first)
6567         {
6568           error ("Can't find default package `%s'. Check the CLASSPATH environment variable and the access to the archives.", package_name);
6569           java_error_count++;
6570           first = 0;
6571         }
6572       else
6573         parse_error_context (wfl, "Package `%s' not found in import",
6574                              package_name);
6575       current_jcf = saved_jcf;
6576       return;
6577     }
6578   current_jcf = saved_jcf;
6579 }
6580
6581 /* Possibly find a type in the import on demands specified
6582    types. Returns 1 if an error occured, 0 otherwise. Run throught the
6583    entire list, to detected potential double definitions.  */
6584                  
6585 static int
6586 find_in_imports_on_demand (class_type)
6587      tree class_type;
6588 {
6589   tree node, import, node_to_use = NULL_TREE;
6590   int seen_once = -1;
6591   tree cl = NULL_TREE;
6592
6593   for (import = ctxp->import_demand_list; import; import = TREE_CHAIN (import))
6594     {
6595       const char *id_name;
6596       obstack_grow (&temporary_obstack, 
6597                     IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))),
6598                     IDENTIFIER_LENGTH (EXPR_WFL_NODE (TREE_PURPOSE (import))));
6599       obstack_1grow (&temporary_obstack, '.');
6600       obstack_grow0 (&temporary_obstack, 
6601                      IDENTIFIER_POINTER (TYPE_NAME (class_type)),
6602                      IDENTIFIER_LENGTH (TYPE_NAME (class_type)));
6603       id_name = obstack_finish (&temporary_obstack);
6604               
6605       node = maybe_get_identifier (id_name);
6606       if (node && IS_A_CLASSFILE_NAME (node))
6607         {
6608           if (seen_once < 0)
6609             {
6610               cl = TREE_PURPOSE (import);
6611               seen_once = 1;
6612               node_to_use = node;
6613             }
6614           else
6615             {
6616               seen_once++;
6617               parse_error_context 
6618                 (import, "Type `%s' also potentially defined in package `%s'",
6619                  IDENTIFIER_POINTER (TYPE_NAME (class_type)),
6620                  IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))));
6621             }
6622         }
6623     }
6624
6625   if (seen_once == 1)
6626     {
6627       /* Setup lineno so that it refers to the line of the import (in
6628          case we parse a class file and encounter errors */
6629       tree decl;
6630       int saved_lineno = lineno;
6631       lineno = EXPR_WFL_LINENO (cl);
6632       TYPE_NAME (class_type) = node_to_use;
6633       QUALIFIED_P (TYPE_NAME (class_type)) = 1;
6634       decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
6635       /* If there is no DECL set for the class or if the class isn't
6636          loaded and not seen in source yet, the load */
6637       if (!decl || (!CLASS_LOADED_P (TREE_TYPE (decl))
6638                     && !CLASS_FROM_SOURCE_P (TREE_TYPE (decl))))
6639         load_class (node_to_use, 0);
6640       lineno = saved_lineno;
6641       return check_pkg_class_access (TYPE_NAME (class_type), cl);
6642     }
6643   else
6644     return (seen_once < 0 ? 0 : seen_once); /* It's ok not to have found */
6645 }
6646
6647 /* Add package NAME to the list of package encountered so far. To
6648    speed up class lookup in do_resolve_class, we make sure a
6649    particular package is added only once.  */
6650
6651 static void
6652 register_package (name)
6653      tree name;
6654 {
6655   static struct hash_table _pht, *pht = NULL;
6656
6657   if (!pht)
6658     {
6659       hash_table_init (&_pht, hash_newfunc, 
6660                        java_hash_hash_tree_node, java_hash_compare_tree_node);
6661       pht = &_pht;
6662     }
6663   
6664   if (!hash_lookup (pht, (const hash_table_key) name, FALSE, NULL))
6665     {
6666       package_list = chainon (package_list, build_tree_list (name, NULL));
6667       hash_lookup (pht, (const hash_table_key) name, TRUE, NULL);
6668     }
6669 }
6670
6671 static tree
6672 resolve_package (pkg, next)
6673      tree pkg, *next;
6674 {
6675   tree current, acc;
6676   tree type_name = NULL_TREE;
6677   const char *name = IDENTIFIER_POINTER (EXPR_WFL_NODE (pkg));
6678
6679   /* The trick is to determine when the package name stops and were
6680      the name of something contained in the package starts. Then we
6681      return a fully qualified name of what we want to get. */
6682
6683   /* Do a quick search on well known package names */
6684   if (!strncmp (name, "java.lang.reflect", 17))
6685     {
6686       *next = 
6687         TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg))));
6688       type_name = lookup_package_type (name, 17);
6689     }
6690   else if (!strncmp (name, "java.lang", 9))
6691     {
6692       *next = TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg)));
6693       type_name = lookup_package_type (name, 9);
6694     }
6695
6696   /* If we found something here, return */
6697   if (type_name)
6698     return type_name; 
6699
6700   *next = EXPR_WFL_QUALIFICATION (pkg);
6701
6702   /* Try the current package. */
6703   if (ctxp->package && !strncmp (name, IDENTIFIER_POINTER (ctxp->package),  
6704                                  IDENTIFIER_LENGTH (ctxp->package)))
6705     {
6706       type_name = 
6707         lookup_package_type_and_set_next (name, 
6708                                           IDENTIFIER_LENGTH (ctxp->package), 
6709                                           next );
6710       if (type_name)
6711         return type_name;
6712     }
6713
6714   /* Search in imported package */
6715   for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
6716     {
6717       tree current_pkg_name = EXPR_WFL_NODE (TREE_PURPOSE (current));
6718       int len = IDENTIFIER_LENGTH (current_pkg_name);
6719       if (!strncmp (name, IDENTIFIER_POINTER (current_pkg_name), len))
6720         {
6721           tree left, dummy;
6722           
6723           breakdown_qualified (&left, &dummy, current_pkg_name);
6724           len = IDENTIFIER_LENGTH (left);
6725           type_name = lookup_package_type_and_set_next (name, len, next);
6726           if (type_name)
6727             break;
6728         }
6729     }
6730
6731   /* Try to progressively construct a type name */
6732   if (TREE_CODE (pkg) == EXPR_WITH_FILE_LOCATION)
6733     for (acc = NULL_TREE, current = EXPR_WFL_QUALIFICATION (pkg); 
6734          current; current = TREE_CHAIN (current))
6735       {
6736         acc = merge_qualified_name (acc, EXPR_WFL_NODE (QUAL_WFL (current)));
6737         if ((type_name = resolve_no_layout (acc, NULL_TREE)))
6738           {
6739             type_name = acc;
6740             /* resolve_package should be used in a loop, hence we
6741                point at this one to naturally process the next one at
6742                the next iteration. */
6743             *next = current;
6744             break;
6745           }
6746       }
6747   return type_name;
6748 }
6749
6750 static tree
6751 lookup_package_type_and_set_next (name, len, next)
6752      const char *name;
6753      int len;
6754      tree *next;
6755 {
6756   const char *ptr;
6757   tree type_name = lookup_package_type (name, len);
6758
6759   if (!type_name)
6760     return NULL;
6761   
6762   ptr = IDENTIFIER_POINTER (type_name);
6763   while (ptr && (ptr = strchr (ptr, '.'))) 
6764     {
6765       *next = TREE_CHAIN (*next);
6766       ptr++;
6767     }
6768   return type_name;
6769 }
6770
6771 static tree
6772 lookup_package_type (name, from)
6773      const char *name;
6774      int from;
6775 {
6776   char subname [128];
6777   const char *sub = &name[from+1];
6778   while (*sub != '.' && *sub)
6779     sub++;
6780   strncpy (subname, name, sub-name);
6781   subname [sub-name] = '\0';
6782   return get_identifier (subname);
6783 }
6784
6785 static void
6786 check_inner_class_access (decl, enclosing_type, cl)
6787      tree decl, enclosing_type, cl;
6788 {
6789   /* We don't issue an error message when CL is null. CL can be null
6790      as a result of processing a JDEP crafted by
6791      source_start_java_method for the purpose of patching its parm
6792      decl. But the error would have been already trapped when fixing
6793      the method's signature. */
6794   if (!(cl && PURE_INNER_CLASS_DECL_P (decl) && CLASS_PRIVATE (decl))
6795       || (PURE_INNER_CLASS_DECL_P (enclosing_type)
6796           && common_enclosing_context_p (TREE_TYPE (enclosing_type), 
6797                                           TREE_TYPE (decl)))
6798       || enclosing_context_p (TREE_TYPE (enclosing_type), TREE_TYPE (decl)))
6799     return;
6800
6801   parse_error_context (cl, "Can't access nested %s %s. Only public classes and interfaces in other packages can be accessed",
6802                        (CLASS_INTERFACE (decl) ? "interface" : "class"),
6803                        lang_printable_name (decl, 0));
6804 }
6805
6806 /* Check that CLASS_NAME refers to a PUBLIC class. Return 0 if no
6807    access violations were found, 1 otherwise.  */
6808
6809 static int
6810 check_pkg_class_access (class_name, cl)
6811      tree class_name;
6812      tree cl;
6813 {
6814   tree type;
6815
6816   if (!QUALIFIED_P (class_name) || !IDENTIFIER_CLASS_VALUE (class_name))
6817     return 0;
6818
6819   if (!(type = TREE_TYPE (IDENTIFIER_CLASS_VALUE (class_name))))
6820     return 0;
6821
6822   if (!CLASS_PUBLIC (TYPE_NAME (type)))
6823     {
6824       /* Access to a private class within the same package is
6825          allowed. */
6826       tree l, r;
6827       breakdown_qualified (&l, &r, class_name);
6828       if (l == ctxp->package)
6829         return 0;
6830
6831       parse_error_context 
6832         (cl, "Can't access %s `%s'. Only public classes and interfaces in other packages can be accessed",
6833          (CLASS_INTERFACE (TYPE_NAME (type)) ? "interface" : "class"),
6834          IDENTIFIER_POINTER (class_name));
6835       return 1;
6836     }
6837   return 0;
6838 }
6839
6840 /* Local variable declaration. */
6841
6842 static void
6843 declare_local_variables (modifier, type, vlist)
6844      int modifier;
6845      tree type;
6846      tree vlist;
6847 {
6848   tree decl, current, saved_type;
6849   tree type_wfl = NULL_TREE;
6850   int must_chain = 0;
6851   int final_p = 0;
6852
6853   /* Push a new block if statements were seen between the last time we
6854      pushed a block and now. Keep a cound of block to close */
6855   if (BLOCK_EXPR_BODY (GET_CURRENT_BLOCK (current_function_decl)))
6856     {
6857       tree body = GET_CURRENT_BLOCK (current_function_decl);
6858       tree b = enter_block ();
6859       BLOCK_EXPR_ORIGIN (b) = body;
6860     }
6861
6862   if (modifier)
6863     {
6864       int i;
6865       for (i = 0; i <= 10; i++) if (1 << i & modifier) break;
6866       if (modifier == ACC_FINAL)
6867         final_p = 1;
6868       else 
6869         {
6870           parse_error_context 
6871             (ctxp->modifier_ctx [i], 
6872              "Only `final' is allowed as a local variables modifier");
6873           return;
6874         }
6875     }
6876
6877   /* Obtain an incomplete type if TYPE is not complete. TYPE_WFL will
6878      hold the TYPE value if a new incomplete has to be created (as
6879      opposed to being found already existing and reused). */
6880   SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
6881
6882   /* If TYPE is fully resolved and we don't have a reference, make one */
6883   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
6884
6885   /* Go through all the declared variables */
6886   for (current = vlist, saved_type = type; current;
6887        current = TREE_CHAIN (current), type = saved_type)
6888     {
6889       tree other, real_type;
6890       tree wfl  = TREE_PURPOSE (current);
6891       tree name = EXPR_WFL_NODE (wfl);
6892       tree init = TREE_VALUE (current);
6893
6894       /* Process NAME, as it may specify extra dimension(s) for it */
6895       type = build_array_from_name (type, type_wfl, name, &name);
6896
6897       /* Variable redefinition check */
6898       if ((other = lookup_name_in_blocks (name)))
6899         {
6900           variable_redefinition_error (wfl, name, TREE_TYPE (other),
6901                                        DECL_SOURCE_LINE (other));
6902           continue;
6903         }
6904
6905       /* Type adjustment. We may have just readjusted TYPE because
6906          the variable specified more dimensions. Make sure we have
6907          a reference if we can and don't have one already. */
6908       PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
6909
6910       real_type = GET_REAL_TYPE (type);
6911       /* Never layout this decl. This will be done when its scope
6912          will be entered */
6913       decl = build_decl (VAR_DECL, name, real_type);
6914       LOCAL_FINAL (decl) = final_p;
6915       BLOCK_CHAIN_DECL (decl);
6916       
6917       /* If doing xreferencing, replace the line number with the WFL
6918          compound value */
6919       if (flag_emit_xref)
6920         DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (wfl);
6921       
6922       /* Don't try to use an INIT statement when an error was found */
6923       if (init && java_error_count)
6924         init = NULL_TREE;
6925       
6926       /* Add the initialization function to the current function's code */
6927       if (init)
6928         {
6929           /* Name might have been readjusted */
6930           EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = name;
6931           MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
6932           java_method_add_stmt (current_function_decl,
6933                                 build_debugable_stmt (EXPR_WFL_LINECOL (init),
6934                                                       init));
6935         }
6936     
6937       /* Setup dependency the type of the decl */
6938       if (must_chain)
6939         {
6940           jdep *dep;
6941           register_incomplete_type (JDEP_VARIABLE, type_wfl, decl, type);
6942           dep = CLASSD_LAST (ctxp->classd_list);
6943           JDEP_GET_PATCH (dep) = &TREE_TYPE (decl);
6944         }
6945     }
6946   SOURCE_FRONTEND_DEBUG (("Defined locals"));
6947 }
6948
6949 /* Called during parsing. Build decls from argument list.  */
6950
6951 static void
6952 source_start_java_method (fndecl)
6953      tree fndecl;
6954 {
6955   tree tem;
6956   tree parm_decl;
6957   int i;
6958
6959   if (!fndecl)
6960     return;
6961
6962   current_function_decl = fndecl;
6963
6964   /* New scope for the function */
6965   enter_block ();
6966   for (tem = TYPE_ARG_TYPES (TREE_TYPE (fndecl)), i = 0;
6967        tem != end_params_node; tem = TREE_CHAIN (tem), i++)
6968     {
6969       tree type = TREE_VALUE (tem);
6970       tree name = TREE_PURPOSE (tem);
6971       
6972       /* If type is incomplete. Create an incomplete decl and ask for
6973          the decl to be patched later */
6974       if (INCOMPLETE_TYPE_P (type))
6975         {
6976           jdep *jdep;
6977           tree real_type = GET_REAL_TYPE (type);
6978           parm_decl = build_decl (PARM_DECL, name, real_type);
6979           type = obtain_incomplete_type (type);
6980           register_incomplete_type (JDEP_PARM, NULL_TREE, NULL_TREE, type);
6981           jdep = CLASSD_LAST (ctxp->classd_list);
6982           JDEP_MISC (jdep) = name;
6983           JDEP_GET_PATCH (jdep) = &TREE_TYPE (parm_decl);
6984         }
6985       else
6986         parm_decl = build_decl (PARM_DECL, name, type);
6987
6988       /* Remember if a local variable was declared final (via its
6989          TREE_LIST of type/name.) Set LOCAL_FINAL accordingly. */
6990       if (ARG_FINAL_P (tem))
6991         LOCAL_FINAL (parm_decl) = 1;
6992
6993       BLOCK_CHAIN_DECL (parm_decl);
6994     }
6995   tem = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
6996   BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl)) =
6997     nreverse (tem);
6998   DECL_ARG_SLOT_COUNT (current_function_decl) = i;
6999   DECL_MAX_LOCALS (current_function_decl) = i;
7000 }
7001
7002 /* Called during parsing. Creates an artificial method declaration.  */
7003
7004 static tree
7005 create_artificial_method (class, flags, type, name, args)
7006      tree class;
7007      int flags;
7008      tree type, name, args;
7009 {
7010   tree mdecl;
7011
7012   java_parser_context_save_global ();
7013   lineno = 0;                                                               
7014   mdecl = make_node (FUNCTION_TYPE);                                
7015   TREE_TYPE (mdecl) = type;
7016   TYPE_ARG_TYPES (mdecl) = args;
7017   mdecl = add_method (class, flags, name, build_java_signature (mdecl)); 
7018   java_parser_context_restore_global ();
7019   DECL_ARTIFICIAL (mdecl) = 1;                                      
7020   return mdecl;
7021 }
7022
7023 /* Starts the body if an artifical method.  */
7024
7025 static void
7026 start_artificial_method_body (mdecl)
7027      tree mdecl;
7028 {
7029   DECL_SOURCE_LINE (mdecl) = 1;
7030   DECL_SOURCE_LINE_MERGE (mdecl, 1);
7031   source_start_java_method (mdecl);
7032   enter_block ();
7033 }
7034
7035 static void
7036 end_artificial_method_body (mdecl)
7037      tree mdecl;
7038 {
7039   BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)) = exit_block ();
7040   exit_block ();
7041 }
7042
7043 /* Called during expansion. Push decls formerly built from argument
7044    list so they're usable during expansion. */
7045
7046 static void
7047 expand_start_java_method (fndecl)
7048      tree fndecl;
7049 {
7050   tree tem, *ptr;
7051
7052   current_function_decl = fndecl;
7053
7054   if (! quiet_flag)
7055     fprintf (stderr, " [%s.", lang_printable_name (DECL_CONTEXT (fndecl), 0));
7056   announce_function (fndecl);
7057   if (! quiet_flag)
7058     fprintf (stderr, "]");
7059
7060   pushlevel (1);                /* Prepare for a parameter push */
7061   ptr = &DECL_ARGUMENTS (fndecl);
7062   tem  = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
7063   while (tem)
7064     {
7065       tree next = TREE_CHAIN (tem);
7066       tree type = TREE_TYPE (tem);
7067       if (PROMOTE_PROTOTYPES
7068           && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
7069           && INTEGRAL_TYPE_P (type))
7070         type = integer_type_node;
7071       DECL_ARG_TYPE (tem) = type;
7072       layout_decl (tem, 0);
7073       pushdecl (tem);
7074       *ptr = tem;
7075       ptr = &TREE_CHAIN (tem);
7076       tem = next;
7077     }
7078   *ptr = NULL_TREE;
7079   pushdecl_force_head (DECL_ARGUMENTS (fndecl));
7080   lineno = DECL_SOURCE_LINE_FIRST (fndecl);
7081 }
7082
7083 /* Terminate a function and expand its body.  */
7084
7085 static void
7086 source_end_java_method ()
7087 {
7088   tree fndecl = current_function_decl;
7089   int flag_asynchronous_exceptions = asynchronous_exceptions;
7090
7091   if (!fndecl)
7092     return;
7093
7094   java_parser_context_save_global ();
7095   lineno = ctxp->last_ccb_indent1;
7096
7097   /* Set EH language codes */
7098   java_set_exception_lang_code ();
7099
7100   /* Turn function bodies with only a NOP expr null, so they don't get
7101      generated at all and we won't get warnings when using the -W
7102      -Wall flags. */
7103   if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) == empty_stmt_node)
7104     BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) = NULL_TREE;
7105
7106   /* Generate function's code */
7107   if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl))
7108       && ! flag_emit_class_files
7109       && ! flag_emit_xref)
7110     expand_expr_stmt (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)));
7111
7112   /* pop out of its parameters */
7113   pushdecl_force_head (DECL_ARGUMENTS (fndecl));
7114   poplevel (1, 0, 1);
7115   BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
7116
7117   /* Generate rtl for function exit.  */
7118   if (! flag_emit_class_files && ! flag_emit_xref)
7119     {
7120       lineno = DECL_SOURCE_LINE_LAST (fndecl);
7121       /* Emit catch-finally clauses */
7122       emit_handlers ();
7123       expand_function_end (input_filename, lineno, 0);
7124
7125       /* FIXME: If the current method contains any exception handlers,
7126          force asynchronous_exceptions: this is necessary because signal
7127          handlers in libjava may throw exceptions.  This is far from being
7128          a perfect solution, but it's better than doing nothing at all.*/
7129       if (catch_clauses)
7130         asynchronous_exceptions = 1;
7131
7132       /* Run the optimizers and output assembler code for this function. */
7133       rest_of_compilation (fndecl);
7134     }
7135
7136   current_function_decl = NULL_TREE;
7137   permanent_allocation (1);
7138   java_parser_context_restore_global ();
7139   asynchronous_exceptions = flag_asynchronous_exceptions;
7140 }
7141
7142 /* Record EXPR in the current function block. Complements compound
7143    expression second operand if necessary.  */
7144
7145 tree
7146 java_method_add_stmt (fndecl, expr)
7147      tree fndecl, expr;
7148 {
7149   if (!GET_CURRENT_BLOCK (fndecl))
7150     return NULL_TREE;
7151   return add_stmt_to_block (GET_CURRENT_BLOCK (fndecl), NULL_TREE, expr);
7152 }
7153
7154 static tree
7155 add_stmt_to_block (b, type, stmt)
7156      tree b, type, stmt;
7157 {
7158   tree body = BLOCK_EXPR_BODY (b), c;
7159   
7160   if (java_error_count)
7161     return body;
7162     
7163   if ((c = add_stmt_to_compound (body, type, stmt)) == body)
7164     return body;
7165
7166   BLOCK_EXPR_BODY (b) = c;
7167   TREE_SIDE_EFFECTS (c) = 1;
7168   return c;
7169 }
7170
7171 /* Add STMT to EXISTING if possible, otherwise create a new
7172    COMPOUND_EXPR and add STMT to it. */
7173
7174 static tree
7175 add_stmt_to_compound (existing, type, stmt)
7176      tree existing, type, stmt;
7177 {
7178   if (existing)
7179     return build (COMPOUND_EXPR, type, existing, stmt);
7180   else
7181     return stmt;
7182 }
7183
7184 /* Hold THIS for the scope of the current public method decl.  */
7185 static tree current_this;
7186
7187 void java_layout_seen_class_methods ()
7188 {
7189   tree previous_list = all_class_list;
7190   tree end = NULL_TREE;
7191   tree current;
7192
7193   while (1)
7194     {
7195       for (current = previous_list; 
7196            current != end; current = TREE_CHAIN (current))
7197         layout_class_methods (TREE_TYPE (TREE_VALUE (current)));
7198       
7199       if (previous_list != all_class_list)
7200         {
7201           end = previous_list;
7202           previous_list = all_class_list;
7203         }
7204       else
7205         break;
7206     }
7207 }
7208
7209 void
7210 java_reorder_fields ()
7211 {
7212   static tree stop_reordering = NULL_TREE;
7213
7214   tree current;
7215   for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
7216     {
7217       current_class = TREE_TYPE (TREE_VALUE (current));
7218
7219       if (current_class == stop_reordering)
7220         break;
7221
7222       /* Reverse the fields, but leave the dummy field in front.
7223          Fields are already ordered for Object and Class */
7224       if (TYPE_FIELDS (current_class) && current_class != object_type_node
7225           && current_class != class_type_node)
7226       {
7227         /* If the dummy field is there, reverse the right fields and
7228            just layout the type for proper fields offset */
7229         if (!DECL_NAME (TYPE_FIELDS (current_class)))
7230           {
7231             tree fields = TYPE_FIELDS (current_class);
7232             TREE_CHAIN (fields) = nreverse (TREE_CHAIN (fields));
7233             TYPE_SIZE (current_class) = NULL_TREE;
7234           }
7235         /* We don't have a dummy field, we need to layout the class,
7236            after having reversed the fields */
7237         else
7238           {
7239             TYPE_FIELDS (current_class) = 
7240               nreverse (TYPE_FIELDS (current_class));
7241             TYPE_SIZE (current_class) = NULL_TREE;
7242           }
7243       }
7244     }
7245   stop_reordering = TREE_TYPE (TREE_VALUE (ctxp->gclass_list));
7246 }
7247
7248 /* Layout the methods of all classes loaded in one way on an
7249    other. Check methods of source parsed classes. Then reorder the
7250    fields and layout the classes or the type of all source parsed
7251    classes */
7252
7253 void
7254 java_layout_classes ()
7255 {
7256   tree current;
7257   int save_error_count = java_error_count;
7258
7259   /* Layout the methods of all classes seen so far */
7260   java_layout_seen_class_methods ();
7261   java_parse_abort_on_error ();
7262   all_class_list = NULL_TREE;
7263
7264   /* Then check the methods of all parsed classes */
7265   for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
7266     if (CLASS_FROM_SOURCE_P (TREE_TYPE (TREE_VALUE (current))))
7267       CHECK_METHODS (TREE_VALUE (current));
7268   java_parse_abort_on_error ();
7269
7270   for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
7271     {
7272       current_class = TREE_TYPE (TREE_VALUE (current));
7273       layout_class (current_class);
7274
7275       /* From now on, the class is considered completely loaded */
7276       CLASS_LOADED_P (current_class) = 1;
7277
7278       /* Error reported by the caller */
7279       if (java_error_count)
7280         return;
7281     }
7282
7283   /* We might have reloaded classes durign the process of laying out
7284      classes for code generation. We must layout the methods of those
7285      late additions, as constructor checks might use them */
7286   java_layout_seen_class_methods ();
7287   java_parse_abort_on_error ();
7288 }
7289
7290 /* Expand methods in the current set of classes rememebered for
7291    generation.  */
7292
7293 static void
7294 java_complete_expand_classes ()
7295 {
7296   tree current;
7297
7298   do_not_fold = flag_emit_xref;
7299
7300   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
7301     if (!INNER_CLASS_DECL_P (current))
7302       java_complete_expand_class (current);
7303 }
7304
7305 /* Expand the methods found in OUTER, starting first by OUTER's inner
7306    classes, if any.  */
7307
7308 static void
7309 java_complete_expand_class (outer)
7310      tree outer;
7311 {
7312   tree inner_list;
7313
7314   set_nested_class_simple_name_value (outer, 1); /* Set */
7315
7316   /* We need to go after all inner classes and start expanding them,
7317      starting with most nested ones. We have to do that because nested
7318      classes might add functions to outer classes */
7319
7320   for (inner_list = DECL_INNER_CLASS_LIST (outer);
7321        inner_list; inner_list = TREE_CHAIN (inner_list))
7322     java_complete_expand_class (TREE_PURPOSE (inner_list));
7323
7324   java_complete_expand_methods (outer);
7325   set_nested_class_simple_name_value (outer, 0); /* Reset */
7326 }
7327
7328 /* Expand methods registered in CLASS_DECL. The general idea is that
7329    we expand regular methods first. This allows us get an estimate on
7330    how outer context local alias fields are really used so we can add
7331    to the constructor just enough code to initialize them properly (it
7332    also lets us generate $finit$ correctly.) Then we expand the
7333    constructors and then <clinit>.  */
7334
7335 static void
7336 java_complete_expand_methods (class_decl)
7337      tree class_decl;
7338 {
7339   tree clinit, finit, decl, first_decl;
7340
7341   current_class = TREE_TYPE (class_decl);
7342
7343   /* Initialize a new constant pool */
7344   init_outgoing_cpool ();
7345
7346   /* Pre-expand <clinit> to figure whether we really need it or
7347      not. If we do need it, we pre-expand the static fields so they're
7348      ready to be used somewhere else. <clinit> will be fully expanded
7349      after we processed the constructors. */
7350   first_decl = TYPE_METHODS (current_class);
7351   clinit = maybe_generate_pre_expand_clinit (current_class);
7352
7353   /* Then generate $finit$ (if we need to) because constructor will
7354    try to use it.*/
7355   if (TYPE_FINIT_STMT_LIST (current_class))
7356     {
7357       finit = generate_finit (current_class);
7358       java_complete_expand_method (finit);
7359     }
7360
7361   /* Now do the constructors */
7362   for (decl = first_decl ; !java_error_count && decl; decl = TREE_CHAIN (decl))
7363     {
7364       int no_body;
7365
7366       if (!DECL_CONSTRUCTOR_P (decl))
7367         continue;
7368       
7369       no_body = !DECL_FUNCTION_BODY (decl);
7370       /* Don't generate debug info on line zero when expanding a
7371          generated constructor. */
7372       if (no_body)
7373         restore_line_number_status (1);
7374
7375       java_complete_expand_method (decl);
7376       
7377       if (no_body)
7378         restore_line_number_status (0);
7379     }
7380
7381   /* First, do the ordinary methods. */
7382   for (decl = first_decl; decl; decl = TREE_CHAIN (decl))
7383     {
7384       /* Skip abstract or native methods -- but do handle native
7385          methods when generating JNI stubs.  */
7386       if (METHOD_ABSTRACT (decl)
7387           || (! flag_jni && METHOD_NATIVE (decl))
7388           || DECL_CONSTRUCTOR_P (decl) || DECL_CLINIT_P (decl))
7389         continue;
7390
7391       if (METHOD_NATIVE (decl))
7392         {
7393           tree body = build_jni_stub (decl);
7394           BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (decl)) = body;
7395         }
7396
7397       java_complete_expand_method (decl);
7398     }
7399
7400   /* If there is indeed a <clinit>, fully expand it now */
7401   if (clinit)
7402     {
7403       /* Prevent the use of `this' inside <clinit> */
7404       ctxp->explicit_constructor_p = 1;
7405       java_complete_expand_method (clinit);
7406       ctxp->explicit_constructor_p = 0;
7407     }
7408   
7409   /* We might have generated a class$ that we now want to expand */
7410   if (TYPE_DOT_CLASS (current_class))
7411     java_complete_expand_method (TYPE_DOT_CLASS (current_class));
7412
7413   /* Now verify constructor circularity (stop after the first one we
7414      prove wrong.) */
7415   if (!CLASS_INTERFACE (class_decl))
7416     for (decl = TYPE_METHODS (current_class); decl; decl = TREE_CHAIN (decl))
7417       if (DECL_CONSTRUCTOR_P (decl) 
7418           && verify_constructor_circularity (decl, decl))
7419         break;
7420
7421   /* Save the constant pool. We'll need to restore it later. */
7422   TYPE_CPOOL (current_class) = outgoing_cpool;
7423 }
7424
7425 /* Hold a list of catch clauses list. The first element of this list is
7426    the list of the catch clauses of the currently analysed try block. */
7427 static tree currently_caught_type_list;
7428
7429 /* Attempt to create <clinit>. Pre-expand static fields so they can be
7430    safely used in some other methods/constructors.  */
7431
7432 static tree
7433 maybe_generate_pre_expand_clinit (class_type)
7434      tree class_type;
7435 {
7436   tree current, mdecl;
7437
7438   if (!TYPE_CLINIT_STMT_LIST (class_type))
7439     return NULL_TREE;
7440
7441   /* Go through all static fields and pre expand them */
7442   for (current = TYPE_FIELDS (class_type); current; 
7443        current = TREE_CHAIN (current))
7444     if (FIELD_STATIC (current))
7445       build_field_ref (NULL_TREE, class_type, DECL_NAME (current));
7446
7447   /* Then build the <clinit> method */
7448   mdecl = create_artificial_method (class_type, ACC_STATIC, void_type_node,
7449                                     clinit_identifier_node, end_params_node);
7450   layout_class_method (class_type, CLASSTYPE_SUPER (class_type),
7451                        mdecl, NULL_TREE);
7452   start_artificial_method_body (mdecl);
7453
7454   /* We process the list of assignment we produced as the result of
7455      the declaration of initialized static field and add them as
7456      statement to the <clinit> method. */
7457   for (current = TYPE_CLINIT_STMT_LIST (class_type); current;
7458        current = TREE_CHAIN (current))
7459     {
7460       tree stmt = current;
7461       /* We build the assignment expression that will initialize the
7462          field to its value. There are strict rules on static
7463          initializers (8.5). FIXME */
7464       if (TREE_CODE (stmt) != BLOCK)
7465         stmt = build_debugable_stmt (EXPR_WFL_LINECOL (stmt), stmt);
7466       java_method_add_stmt (mdecl, stmt);
7467     }
7468
7469   end_artificial_method_body (mdecl);
7470
7471   /* Now we want to place <clinit> as the last method (because we need
7472      it at least for interface so that it doesn't interfere with the
7473      dispatch table based lookup. */
7474   if (TREE_CHAIN (TYPE_METHODS (class_type)))
7475     {
7476       current = TREE_CHAIN (TYPE_METHODS (class_type));
7477       TYPE_METHODS (class_type) = current;
7478
7479       while (TREE_CHAIN (current))
7480         current = TREE_CHAIN (current);
7481
7482       TREE_CHAIN (current) = mdecl;
7483       TREE_CHAIN (mdecl) = NULL_TREE;
7484     }
7485
7486   return mdecl;
7487 }
7488
7489 /* See whether we could get rid of <clinit>. Criteria are: all static
7490    final fields have constant initial values and the body of <clinit>
7491    is empty. Return 1 if <clinit> was discarded, 0 otherwise. */
7492
7493 static int
7494 maybe_yank_clinit (mdecl)
7495      tree mdecl;
7496 {
7497   tree type, current;
7498   tree fbody, bbody;
7499   
7500   if (!DECL_CLINIT_P (mdecl))
7501     return 0;
7502   
7503   /* If the body isn't empty, then we keep <clinit> */
7504   fbody = DECL_FUNCTION_BODY (mdecl);
7505   if ((bbody = BLOCK_EXPR_BODY (fbody)))
7506     bbody = BLOCK_EXPR_BODY (bbody);
7507   if (bbody && bbody != empty_stmt_node)
7508     return 0;
7509   
7510   type = DECL_CONTEXT (mdecl);
7511   current = TYPE_FIELDS (type);
7512
7513   for (current = (current ? TREE_CHAIN (current) : current); 
7514        current; current = TREE_CHAIN (current))
7515     if (!(FIELD_STATIC (current) && FIELD_FINAL (current)
7516           && DECL_INITIAL (current) && TREE_CONSTANT (DECL_INITIAL (current))))
7517       break;
7518
7519   if (current)
7520     return 0;
7521
7522   /* Get rid of <clinit> in the class' list of methods */
7523   if (TYPE_METHODS (type) == mdecl)
7524     TYPE_METHODS (type) = TREE_CHAIN (mdecl);
7525   else
7526     for (current = TYPE_METHODS (type); current; 
7527          current = TREE_CHAIN (current))
7528       if (TREE_CHAIN (current) == mdecl)
7529         {
7530           TREE_CHAIN (current) = TREE_CHAIN (mdecl);
7531           break;
7532         }
7533
7534   return 1;
7535 }
7536
7537
7538 /* Complete and expand a method.  */
7539
7540 static void
7541 java_complete_expand_method (mdecl)
7542      tree mdecl;
7543 {
7544   int yank_clinit = 0;
7545
7546   current_function_decl = mdecl;
7547   /* Fix constructors before expanding them */
7548   if (DECL_CONSTRUCTOR_P (mdecl))
7549     fix_constructors (mdecl);
7550   
7551   /* Expand functions that have a body */
7552   if (DECL_FUNCTION_BODY (mdecl))
7553     {
7554       tree fbody = DECL_FUNCTION_BODY (mdecl);
7555       tree block_body = BLOCK_EXPR_BODY (fbody);
7556       tree exception_copy = NULL_TREE;
7557       expand_start_java_method (mdecl);
7558       build_result_decl (mdecl);
7559
7560       current_this 
7561         = (!METHOD_STATIC (mdecl) ? 
7562            BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl)) : NULL_TREE);
7563
7564       /* Purge the `throws' list of unchecked exceptions. If we're
7565          doing xref, save a copy of the list and re-install it
7566          later. */
7567       if (flag_emit_xref)
7568         exception_copy = copy_list (DECL_FUNCTION_THROWS (mdecl));
7569
7570       purge_unchecked_exceptions (mdecl);
7571
7572       /* Install exceptions thrown with `throws' */
7573       PUSH_EXCEPTIONS (DECL_FUNCTION_THROWS (mdecl));
7574
7575       if (block_body != NULL_TREE)
7576         {
7577           block_body = java_complete_tree (block_body);
7578
7579           if (! flag_emit_xref && ! METHOD_NATIVE (mdecl))
7580             check_for_initialization (block_body);
7581           ctxp->explicit_constructor_p = 0;
7582         }
7583
7584       BLOCK_EXPR_BODY (fbody) = block_body;
7585
7586       /* If we saw a return but couldn't evaluate it properly, we'll
7587          have an error_mark_node here. */
7588       if (block_body != error_mark_node
7589           && (block_body == NULL_TREE || CAN_COMPLETE_NORMALLY (block_body))
7590           && TREE_CODE (TREE_TYPE (TREE_TYPE (mdecl))) != VOID_TYPE
7591           && !flag_emit_xref)
7592         missing_return_error (current_function_decl);
7593
7594       /* Check wether we could just get rid of clinit, now the picture
7595          is complete. */
7596       if (!(yank_clinit = maybe_yank_clinit (mdecl)))
7597         complete_start_java_method (mdecl); 
7598       
7599       /* Don't go any further if we've found error(s) during the
7600          expansion */
7601       if (!java_error_count && !yank_clinit)
7602         source_end_java_method ();
7603       else
7604         {
7605           if (java_error_count)
7606             pushdecl_force_head (DECL_ARGUMENTS (mdecl));
7607           poplevel (1, 0, 1);
7608         }
7609
7610       /* Pop the exceptions and sanity check */
7611       POP_EXCEPTIONS();
7612       if (currently_caught_type_list)
7613         fatal ("Exception list non empty - java_complete_expand_method");
7614
7615       if (flag_emit_xref)
7616         DECL_FUNCTION_THROWS (mdecl) = exception_copy;
7617     }
7618 }
7619
7620 \f
7621
7622 /* This section of the code deals with accessing enclosing context
7623    fields either directly by using the relevant access to this$<n> or
7624    by invoking an access method crafted for that purpose.  */
7625
7626 /* Build the necessary access from an inner class to an outer
7627    class. This routine could be optimized to cache previous result
7628    (decl, current_class and returned access).  When an access method
7629    needs to be generated, it always takes the form of a read. It might
7630    be later turned into a write by calling outer_field_access_fix.  */
7631
7632 static tree
7633 build_outer_field_access (id, decl)
7634      tree id, decl;
7635 {
7636   tree access = NULL_TREE;
7637   tree ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class)));
7638
7639   /* If decl's class is the direct outer class of the current_class,
7640      build the access as `this$<n>.<field>'. Not that we will break
7641      the `private' barrier if we're not emitting bytecodes. */
7642   if (ctx == DECL_CONTEXT (decl) 
7643       && (!FIELD_PRIVATE (decl) || !flag_emit_class_files ))
7644     {
7645       tree thisn = build_current_thisn (current_class);
7646       access = make_qualified_primary (build_wfl_node (thisn), 
7647                                        id, EXPR_WFL_LINECOL (id));
7648     }
7649   /* Otherwise, generate access methods to outer this and access the
7650      field (either using an access method or by direct access.) */
7651   else
7652     {
7653       int lc = EXPR_WFL_LINECOL (id);
7654
7655       /* Now we chain the required number of calls to the access$0 to
7656          get a hold to the enclosing instance we need, and the we
7657          build the field access. */
7658       access = build_access_to_thisn (ctx, DECL_CONTEXT (decl), lc);
7659
7660       /* If the field is private and we're generating bytecode, then
7661          we generate an access method */
7662       if (FIELD_PRIVATE (decl) && flag_emit_class_files )
7663         {
7664           tree name = build_outer_field_access_methods (decl);
7665           access = build_outer_field_access_expr (lc, DECL_CONTEXT (decl),
7666                                                   name, access, NULL_TREE);
7667         }
7668       /* Otherwise we use `access$(this$<j>). ... access$(this$<i>).<field>'.
7669          Once again we break the `private' access rule from a foreign
7670          class. */
7671       else
7672         access = make_qualified_primary (access, id, lc);
7673     }
7674   return resolve_expression_name (access, NULL);
7675 }
7676
7677 /* Return a non zero value if NODE describes an outer field inner
7678    access.  */
7679
7680 static int
7681 outer_field_access_p (type, decl)
7682     tree type, decl;
7683 {
7684   if (!INNER_CLASS_TYPE_P (type) 
7685       || TREE_CODE (decl) != FIELD_DECL
7686       || DECL_CONTEXT (decl) == type)
7687     return 0;
7688
7689   for (type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))); ;
7690        type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))))
7691     {
7692       if (type == DECL_CONTEXT (decl))
7693         return 1;
7694       if (!DECL_CONTEXT (TYPE_NAME (type)))
7695         break;
7696     }
7697
7698   return 0;
7699 }
7700
7701 /* Return a non zero value if NODE represents an outer field inner
7702    access that was been already expanded. As a side effect, it returns
7703    the name of the field being accessed and the argument passed to the
7704    access function, suitable for a regeneration of the access method
7705    call if necessary. */
7706
7707 static int
7708 outer_field_expanded_access_p (node, name, arg_type, arg)
7709     tree node, *name, *arg_type, *arg;
7710 {
7711   int identified = 0;
7712
7713   if (TREE_CODE (node) != CALL_EXPR)
7714     return 0;
7715
7716   /* Well, gcj generates slightly different tree nodes when compiling
7717      to native or bytecodes. It's the case for function calls. */
7718
7719   if (flag_emit_class_files 
7720       && TREE_CODE (node) == CALL_EXPR
7721       && OUTER_FIELD_ACCESS_IDENTIFIER_P (DECL_NAME (TREE_OPERAND (node, 0))))
7722     identified = 1;
7723   else if (!flag_emit_class_files)
7724     {
7725       node = TREE_OPERAND (node, 0);
7726       
7727       if (node && TREE_OPERAND (node, 0)
7728           && TREE_CODE (TREE_OPERAND (node, 0)) == ADDR_EXPR)
7729         {
7730           node = TREE_OPERAND (node, 0);
7731           if (TREE_OPERAND (node, 0)
7732               && TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL
7733               && (OUTER_FIELD_ACCESS_IDENTIFIER_P 
7734                   (DECL_NAME (TREE_OPERAND (node, 0)))))
7735             identified = 1;
7736         }
7737     }
7738
7739   if (identified && name && arg_type && arg)
7740     {
7741       tree argument = TREE_OPERAND (node, 1);
7742       *name = DECL_NAME (TREE_OPERAND (node, 0));
7743       *arg_type = TREE_TYPE (TREE_TYPE (TREE_VALUE (argument)));
7744       *arg = TREE_VALUE (argument);
7745     }
7746   return identified;
7747 }
7748
7749 /* Detect in NODE an outer field read access from an inner class and
7750    transform it into a write with RHS as an argument. This function is
7751    called from the java_complete_lhs when an assignment to a LHS can
7752    be identified. */
7753
7754 static tree
7755 outer_field_access_fix (wfl, node, rhs)
7756     tree wfl, node, rhs;
7757 {
7758   tree name, arg_type, arg;
7759   
7760   if (outer_field_expanded_access_p (node, &name, &arg_type, &arg))
7761     {
7762       /* At any rate, check whether we're trying to assign a value to
7763          a final. */
7764       tree accessed = (JDECL_P (node) ? node : 
7765                        (TREE_CODE (node) == COMPONENT_REF ? 
7766                         TREE_OPERAND (node, 1) : node));
7767       if (check_final_assignment (accessed, wfl))
7768         return error_mark_node;
7769   
7770       node = build_outer_field_access_expr (EXPR_WFL_LINECOL (wfl), 
7771                                             arg_type, name, arg, rhs);
7772       return java_complete_tree (node);
7773     }
7774   return NULL_TREE;
7775 }
7776
7777 /* Construct the expression that calls an access method:
7778      <type>.access$<n>(<arg1> [, <arg2>]); 
7779
7780    ARG2 can be NULL and will be omitted in that case. It will denote a
7781    read access.  */
7782
7783 static tree
7784 build_outer_field_access_expr (lc, type, access_method_name, arg1, arg2)
7785     int lc;
7786     tree type, access_method_name, arg1, arg2;
7787 {
7788   tree args, cn, access;
7789
7790   args = arg1 ? arg1 : 
7791     build_wfl_node (build_current_thisn (current_class));
7792   args = build_tree_list (NULL_TREE, args);
7793
7794   if (arg2)
7795     args = tree_cons (NULL_TREE, arg2, args);
7796
7797   access = build_method_invocation (build_wfl_node (access_method_name), args);
7798   cn = build_wfl_node (DECL_NAME (TYPE_NAME (type)));
7799   return make_qualified_primary (cn, access, lc);
7800 }
7801
7802 static tree
7803 build_new_access_id ()
7804 {
7805   static int access_n_counter = 1;
7806   char buffer [128];
7807
7808   sprintf (buffer, "access$%d", access_n_counter++);
7809   return get_identifier (buffer);
7810 }
7811
7812 /* Create the static access functions for the outer field DECL. We define a
7813    read:
7814      TREE_TYPE (<field>) access$<n> (DECL_CONTEXT (<field>) inst$) {
7815        return inst$.field;
7816      }
7817    and a write access:
7818      TREE_TYPE (<field>) access$<n> (DECL_CONTEXT (<field>) inst$,
7819                                      TREE_TYPE (<field>) value$) {
7820        return inst$.field = value$;
7821      }
7822    We should have a usage flags on the DECL so we can lazily turn the ones
7823    we're using for code generation. FIXME.
7824 */
7825
7826 static tree
7827 build_outer_field_access_methods (decl)
7828     tree decl;
7829 {
7830   tree id, args, stmt, mdecl;
7831   
7832   /* Check point, to be removed. FIXME */
7833   if (FIELD_INNER_ACCESS (decl) 
7834       && TREE_CODE (FIELD_INNER_ACCESS (decl)) != IDENTIFIER_NODE)
7835     abort ();
7836
7837   if (FIELD_INNER_ACCESS (decl))
7838     return FIELD_INNER_ACCESS (decl);
7839
7840   push_obstacks (&permanent_obstack, &permanent_obstack);
7841
7842   /* Create the identifier and a function named after it. */
7843   id = build_new_access_id ();
7844
7845   /* The identifier is marked as bearing the name of a generated write
7846      access function for outer field accessed from inner classes. */
7847   OUTER_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
7848
7849   /* Create the read access */
7850   args = build_tree_list (inst_id, build_pointer_type (DECL_CONTEXT (decl)));
7851   TREE_CHAIN (args) = end_params_node;
7852   stmt = make_qualified_primary (build_wfl_node (inst_id),
7853                                  build_wfl_node (DECL_NAME (decl)), 0);
7854   stmt = build_return (0, stmt);
7855   mdecl = build_outer_field_access_method (DECL_CONTEXT (decl), 
7856                                            TREE_TYPE (decl), id, args, stmt);
7857   DECL_FUNCTION_ACCESS_DECL (mdecl) = decl;
7858
7859   /* Create the write access method */
7860   args = build_tree_list (inst_id, build_pointer_type (DECL_CONTEXT (decl)));
7861   TREE_CHAIN (args) = build_tree_list (wpv_id, TREE_TYPE (decl));
7862   TREE_CHAIN (TREE_CHAIN (args)) = end_params_node;
7863   stmt = make_qualified_primary (build_wfl_node (inst_id),
7864                                  build_wfl_node (DECL_NAME (decl)), 0);
7865   stmt = build_return (0, build_assignment (ASSIGN_TK, 0, stmt,
7866                                             build_wfl_node (wpv_id)));
7867
7868   mdecl = build_outer_field_access_method (DECL_CONTEXT (decl), 
7869                                            TREE_TYPE (decl), id, args, stmt);
7870   DECL_FUNCTION_ACCESS_DECL (mdecl) = decl;
7871   pop_obstacks ();
7872
7873   /* Return the access name */
7874   return FIELD_INNER_ACCESS (decl) = id;
7875 }
7876
7877 /* Build an field access method NAME.  */
7878
7879 static tree 
7880 build_outer_field_access_method (class, type, name, args, body)
7881     tree class, type, name, args, body;
7882 {
7883   tree saved_current_function_decl, mdecl;
7884
7885   /* Create the method */
7886   mdecl = create_artificial_method (class, ACC_STATIC, type, name, args);
7887   fix_method_argument_names (args, mdecl);
7888   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
7889
7890   /* Attach the method body. */
7891   saved_current_function_decl = current_function_decl;
7892   start_artificial_method_body (mdecl);
7893   java_method_add_stmt (mdecl, body);
7894   end_artificial_method_body (mdecl);
7895   current_function_decl = saved_current_function_decl;
7896
7897   return mdecl;
7898 }
7899
7900 \f
7901 /* This section deals with building access function necessary for
7902    certain kinds of method invocation from inner classes.  */
7903
7904 static tree
7905 build_outer_method_access_method (decl)
7906     tree decl;
7907 {
7908   tree saved_current_function_decl, mdecl;
7909   tree args = NULL_TREE, call_args = NULL_TREE;
7910   tree carg, id, body, class;
7911   char buffer [80];
7912   int parm_id_count = 0;
7913
7914   /* Test this abort with an access to a private field */
7915   if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), "access$"))
7916     abort ();
7917
7918   /* Check the cache first */
7919   if (DECL_FUNCTION_INNER_ACCESS (decl))
7920     return DECL_FUNCTION_INNER_ACCESS (decl);
7921
7922   class = DECL_CONTEXT (decl);
7923
7924   /* Obtain an access identifier and mark it */
7925   id = build_new_access_id ();
7926   OUTER_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
7927
7928   push_obstacks (&permanent_obstack, &permanent_obstack);
7929
7930   carg = TYPE_ARG_TYPES (TREE_TYPE (decl));
7931   /* Create the arguments, as much as the original */
7932   for (; carg && carg != end_params_node; 
7933        carg = TREE_CHAIN (carg))
7934     {
7935       sprintf (buffer, "write_parm_value$%d", parm_id_count++);
7936       args = chainon (args, build_tree_list (get_identifier (buffer), 
7937                                              TREE_VALUE (carg)));
7938     }
7939   args = chainon (args, end_params_node);
7940
7941   /* Create the method */
7942   mdecl = create_artificial_method (class, ACC_STATIC, 
7943                                     TREE_TYPE (TREE_TYPE (decl)), id, args);
7944   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
7945   /* There is a potential bug here. We should be able to use
7946      fix_method_argument_names, but then arg names get mixed up and
7947      eventually a constructor will have its this$0 altered and the
7948      outer context won't be assignment properly. The test case is
7949      stub.java FIXME */
7950   TYPE_ARG_TYPES (TREE_TYPE (mdecl)) = args;
7951
7952   /* Attach the method body. */
7953   saved_current_function_decl = current_function_decl;
7954   start_artificial_method_body (mdecl);
7955
7956   /* The actual method invocation uses the same args. When invoking a
7957      static methods that way, we don't want to skip the first
7958      argument. */
7959   carg = args;
7960   if (!METHOD_STATIC (decl))
7961     carg = TREE_CHAIN (carg);
7962   for (; carg && carg != end_params_node; carg = TREE_CHAIN (carg))
7963     call_args = tree_cons (NULL_TREE, build_wfl_node (TREE_PURPOSE (carg)),
7964                            call_args);
7965
7966   body = build_method_invocation (build_wfl_node (DECL_NAME (decl)), 
7967                                   call_args);
7968   if (!METHOD_STATIC (decl))
7969     body = make_qualified_primary (build_wfl_node (TREE_PURPOSE (args)), 
7970                                    body, 0);
7971   if (TREE_TYPE (TREE_TYPE (decl)) != void_type_node)
7972     body = build_return (0, body);
7973   java_method_add_stmt (mdecl,body);
7974   end_artificial_method_body (mdecl);
7975   current_function_decl = saved_current_function_decl;
7976   pop_obstacks ();
7977
7978   /* Back tag the access function so it know what it accesses */
7979   DECL_FUNCTION_ACCESS_DECL (decl) = mdecl;
7980
7981   /* Tag the current method so it knows it has an access generated */
7982   return DECL_FUNCTION_INNER_ACCESS (decl) = mdecl;
7983 }
7984
7985 \f
7986 /* This section of the code deals with building expressions to access
7987    the enclosing instance of an inner class. The enclosing instance is
7988    kept in a generated field called this$<n>, with <n> being the
7989    inner class nesting level (starting from 0.)  */
7990     
7991 /* Build an access to a given this$<n>, possibly by chaining access
7992    call to others. Access methods to this$<n> are build on the fly if
7993    necessary */
7994
7995 static tree
7996 build_access_to_thisn (from, to, lc)
7997      tree from, to;
7998      int lc;
7999 {
8000   tree access = NULL_TREE;
8001
8002   while (from != to)
8003     {
8004       tree access0_wfl, cn;
8005
8006       maybe_build_thisn_access_method (from);
8007       access0_wfl = build_wfl_node (access0_identifier_node);
8008       cn = build_wfl_node (DECL_NAME (TYPE_NAME (from)));
8009       EXPR_WFL_LINECOL (access0_wfl) = lc;
8010       
8011       if (!access)
8012         {
8013           access = build_current_thisn (current_class);
8014           access = build_wfl_node (access);
8015         }
8016       access = build_tree_list (NULL_TREE, access);
8017       access = build_method_invocation (access0_wfl, access);
8018       access = make_qualified_primary (cn, access, lc);
8019       
8020       from = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (from)));
8021     }
8022   return access;
8023 }
8024
8025 /* Build an access function to the this$<n> local to TYPE. NULL_TREE
8026    is returned if nothing needs to be generated. Otherwise, the method
8027    generated and a method decl is returned.  
8028
8029    NOTE: These generated methods should be declared in a class file
8030    attribute so that they can't be referred to directly.  */
8031
8032 static tree
8033 maybe_build_thisn_access_method (type)
8034     tree type;
8035 {
8036   tree mdecl, args, stmt, rtype;
8037   tree saved_current_function_decl;
8038
8039   /* If TYPE is a top-level class, no access method is required.
8040      If there already is such an access method, bail out. */
8041   if (CLASS_ACCESS0_GENERATED_P (type) || !INNER_CLASS_TYPE_P (type))
8042     return NULL_TREE;
8043
8044   /* We generate the method. The method looks like:
8045      static <outer_of_type> access$0 (<type> inst$) { return inst$.this$<n>; }
8046   */
8047   push_obstacks (&permanent_obstack, &permanent_obstack);
8048   args = build_tree_list (inst_id, build_pointer_type (type));
8049   TREE_CHAIN (args) = end_params_node;
8050   rtype = build_pointer_type (TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))));
8051   mdecl = create_artificial_method (type, ACC_STATIC, rtype,
8052                                     access0_identifier_node, args);
8053   fix_method_argument_names (args, mdecl);
8054   layout_class_method (type, NULL_TREE, mdecl, NULL_TREE);
8055   stmt = build_current_thisn (type);
8056   stmt = make_qualified_primary (build_wfl_node (inst_id), 
8057                                  build_wfl_node (stmt), 0);
8058   stmt = build_return (0, stmt);
8059
8060   saved_current_function_decl = current_function_decl;
8061   start_artificial_method_body (mdecl);
8062   java_method_add_stmt (mdecl, stmt);
8063   end_artificial_method_body (mdecl);
8064   current_function_decl = saved_current_function_decl;
8065   pop_obstacks ();
8066
8067   CLASS_ACCESS0_GENERATED_P (type) = 1;
8068
8069   return mdecl;
8070 }
8071
8072 /* Craft an correctly numbered `this$<n>'string. this$0 is used for
8073    the first level of innerclassing. this$1 for the next one, etc...
8074    This function can be invoked with TYPE to NULL, available and then
8075    has to count the parser context.  */
8076
8077 static tree
8078 build_current_thisn (type)
8079     tree type;
8080 {
8081   static int saved_i = -1;
8082   static tree saved_thisn = NULL_TREE;
8083
8084   tree decl;
8085   char buffer [80];
8086   int i = 0;
8087
8088   if (type)
8089     {
8090       static tree saved_type = NULL_TREE;
8091       static int saved_type_i = 0;
8092
8093       if (type == saved_type)
8094         i = saved_type_i;
8095       else
8096         {
8097           for (i = -1, decl = DECL_CONTEXT (TYPE_NAME (type)); 
8098                decl; decl = DECL_CONTEXT (decl), i++)
8099             ;
8100       
8101           saved_type = type;
8102           saved_type_i = i;
8103         }
8104     }
8105   else
8106     i = list_length (GET_CPC_LIST ())-2;
8107
8108   if (i == saved_i)
8109     return saved_thisn;
8110     
8111   sprintf (buffer, "this$%d", i);
8112   saved_i = i;
8113   saved_thisn = get_identifier (buffer);
8114   return saved_thisn;
8115 }
8116
8117 /* Return the assignement to the hidden enclosing context `this$<n>'
8118    by the second incoming parameter to the innerclass constructor. The
8119    form used is `this.this$<n> = this$<n>;'.  */
8120
8121 static tree
8122 build_thisn_assign ()
8123 {
8124   if (current_class && PURE_INNER_CLASS_TYPE_P (current_class))
8125     {
8126       tree thisn = build_current_thisn (current_class);
8127       tree lhs = make_qualified_primary (build_wfl_node (this_identifier_node),
8128                                          build_wfl_node (thisn), 0);
8129       tree rhs = build_wfl_node (thisn);
8130       EXPR_WFL_SET_LINECOL (lhs, lineno, 0);
8131       return build_assignment (ASSIGN_TK, EXPR_WFL_LINECOL (lhs), lhs, rhs);
8132     }
8133   return NULL_TREE;
8134 }
8135
8136 \f
8137 /* Building the synthetic `class$' used to implement the `.class' 1.1
8138    extension for non primitive types. This method looks like:
8139
8140     static Class class$(String type) throws NoClassDefFoundError
8141     {
8142       try {return (java.lang.Class.forName (String));}
8143       catch (ClassNotFoundException e) {
8144         throw new NoClassDefFoundError(e.getMessage());}
8145     } */
8146
8147 static tree
8148 build_dot_class_method (class)
8149      tree class;
8150 {
8151 #define BWF(S) build_wfl_node (get_identifier ((S)))
8152 #define MQN(X,Y) make_qualified_name ((X), (Y), 0)
8153   tree args, tmp, saved_current_function_decl, mdecl;
8154   tree stmt, throw_stmt, catch, catch_block, try_block;
8155   tree catch_clause_param;
8156   tree class_not_found_exception, no_class_def_found_error;
8157
8158   static tree get_message_wfl, type_parm_wfl;
8159
8160   if (!get_message_wfl)
8161     {
8162       get_message_wfl = build_wfl_node (get_identifier ("getMessage"));
8163       type_parm_wfl = build_wfl_node (get_identifier ("type$"));
8164     }
8165
8166   /* Build the arguments */
8167   args = build_tree_list (get_identifier ("type$"),
8168                           build_pointer_type (string_type_node));
8169   TREE_CHAIN (args) = end_params_node;
8170
8171   /* Build the qualified name java.lang.Class.forName */
8172   tmp = MQN (MQN (MQN (BWF ("java"), 
8173                        BWF ("lang")), BWF ("Class")), BWF ("forName"));
8174
8175   /* For things we have to catch and throw */
8176   class_not_found_exception = 
8177     lookup_class (get_identifier ("java.lang.ClassNotFoundException"));
8178   no_class_def_found_error = 
8179     lookup_class (get_identifier ("java.lang.NoClassDefFoundError"));
8180   load_class (class_not_found_exception, 1);
8181   load_class (no_class_def_found_error, 1);
8182
8183   /* Create the "class$" function */
8184   mdecl = create_artificial_method (class, ACC_STATIC, 
8185                                     build_pointer_type (class_type_node),
8186                                     get_identifier ("class$"), args);
8187   DECL_FUNCTION_THROWS (mdecl) = build_tree_list (NULL_TREE,
8188                                                   no_class_def_found_error);
8189   
8190   /* We start by building the try block. We need to build:
8191        return (java.lang.Class.forName (type)); */
8192   stmt = build_method_invocation (tmp, 
8193                                   build_tree_list (NULL_TREE, type_parm_wfl));
8194   stmt = build_return (0, stmt);
8195   /* Put it in a block. That's the try block */
8196   try_block = build_expr_block (stmt, NULL_TREE);
8197
8198   /* Now onto the catch block. We start by building the expression
8199      throwing a new exception: 
8200        throw new NoClassDefFoundError (_.getMessage); */
8201   throw_stmt = make_qualified_name (build_wfl_node (wpv_id), 
8202                                     get_message_wfl, 0);
8203   throw_stmt = build_method_invocation (throw_stmt, NULL_TREE);
8204   
8205   /* Build new NoClassDefFoundError (_.getMessage) */
8206   throw_stmt = build_new_invocation 
8207     (build_wfl_node (get_identifier ("NoClassDefFoundError")),
8208      build_tree_list (build_pointer_type (string_type_node), throw_stmt));
8209
8210   /* Build the throw, (it's too early to use BUILD_THROW) */
8211   throw_stmt = build1 (THROW_EXPR, NULL_TREE, throw_stmt);
8212
8213   /* Build the catch block to encapsulate all this. We begin by
8214      building an decl for the catch clause parameter and link it to
8215      newly created block, the catch block. */
8216   catch_clause_param = 
8217     build_decl (VAR_DECL, wpv_id, 
8218                 build_pointer_type (class_not_found_exception));
8219   catch_block = build_expr_block (NULL_TREE, catch_clause_param);
8220   
8221   /* We initialize the variable with the exception handler. */
8222   catch = build (MODIFY_EXPR, NULL_TREE, catch_clause_param,
8223                  soft_exceptioninfo_call_node);
8224   add_stmt_to_block (catch_block, NULL_TREE, catch);
8225
8226   /* We add the statement throwing the new exception */
8227   add_stmt_to_block (catch_block, NULL_TREE, throw_stmt);
8228
8229   /* Build a catch expression for all this */
8230   catch_block = build1 (CATCH_EXPR, NULL_TREE, catch_block);
8231
8232   /* Build the try/catch sequence */
8233   stmt = build_try_statement (0, try_block, catch_block);
8234
8235   fix_method_argument_names (args, mdecl);
8236   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
8237   saved_current_function_decl = current_function_decl;
8238   start_artificial_method_body (mdecl);
8239   java_method_add_stmt (mdecl, stmt);
8240   end_artificial_method_body (mdecl);
8241   current_function_decl = saved_current_function_decl;
8242   TYPE_DOT_CLASS (class) = mdecl;
8243
8244   return mdecl;
8245 }
8246
8247 static tree
8248 build_dot_class_method_invocation (name)
8249      tree name;
8250 {
8251   tree s = make_node (STRING_CST);
8252   TREE_STRING_LENGTH (s) = IDENTIFIER_LENGTH (name);
8253   TREE_STRING_POINTER (s) = obstack_alloc (expression_obstack,
8254                                            TREE_STRING_LENGTH (s)+1);
8255   strcpy (TREE_STRING_POINTER (s), IDENTIFIER_POINTER (name));
8256   return build_method_invocation (build_wfl_node (get_identifier ("class$")),
8257                                   build_tree_list (NULL_TREE, s));
8258 }
8259
8260 /* This section of the code deals with constructor.  */
8261
8262 /* Craft a body for default constructor. Patch existing constructor
8263    bodies with call to super() and field initialization statements if
8264    necessary.  */
8265
8266 static void
8267 fix_constructors (mdecl)
8268      tree mdecl;
8269 {
8270   tree body = DECL_FUNCTION_BODY (mdecl);
8271   tree thisn_assign, compound = NULL_TREE;
8272   tree class_type = DECL_CONTEXT (mdecl);
8273
8274   if (!body)
8275     {
8276       /* It is an error for the compiler to generate a default
8277          constructor if the superclass doesn't have a constructor that
8278          takes no argument, or the same args for an anonymous class */
8279       if (verify_constructor_super (mdecl))
8280         {
8281           tree sclass_decl = TYPE_NAME (CLASSTYPE_SUPER (class_type));
8282           tree save = DECL_NAME (mdecl);
8283           const char *n = IDENTIFIER_POINTER (DECL_NAME (sclass_decl));
8284           DECL_NAME (mdecl) = DECL_NAME (sclass_decl);
8285           parse_error_context
8286             (lookup_cl (TYPE_NAME (class_type)), 
8287              "No constructor matching `%s' found in class `%s'",
8288              lang_printable_name (mdecl, 0), n);
8289           DECL_NAME (mdecl) = save;
8290         }
8291       
8292       /* The constructor body must be crafted by hand. It's the
8293          constructor we defined when we realize we didn't have the
8294          CLASSNAME() constructor */
8295       start_artificial_method_body (mdecl);
8296       
8297       /* We don't generate a super constructor invocation if we're
8298          compiling java.lang.Object. build_super_invocation takes care
8299          of that. */
8300       compound = java_method_add_stmt (mdecl, build_super_invocation (mdecl));
8301
8302       /* Insert the instance initializer block right here, after the
8303          super invocation. */
8304       add_instance_initializer (mdecl);
8305
8306       /* Insert an assignment to the this$<n> hidden field, if
8307          necessary */
8308       if ((thisn_assign = build_thisn_assign ()))
8309         java_method_add_stmt (mdecl, thisn_assign);
8310
8311       end_artificial_method_body (mdecl);
8312     }
8313   /* Search for an explicit constructor invocation */
8314   else 
8315     {
8316       int found = 0;
8317       tree main_block = BLOCK_EXPR_BODY (body);
8318       
8319       while (body)
8320         switch (TREE_CODE (body))
8321           {
8322           case CALL_EXPR:
8323             found = CALL_EXPLICIT_CONSTRUCTOR_P (body);
8324             body = NULL_TREE;
8325             break;
8326           case COMPOUND_EXPR:
8327           case EXPR_WITH_FILE_LOCATION:
8328             body = TREE_OPERAND (body, 0);
8329             break;
8330           case BLOCK:
8331             body = BLOCK_EXPR_BODY (body);
8332             break;
8333           default:
8334             found = 0;
8335             body = NULL_TREE;
8336           }
8337       /* The constructor is missing an invocation of super() */
8338       if (!found)
8339         compound = add_stmt_to_compound (compound, NULL_TREE,
8340                                          build_super_invocation (mdecl));
8341       
8342       /* Insert the instance initializer block right here, after the
8343          super invocation. */
8344       add_instance_initializer (mdecl);
8345
8346       /* Generate the assignment to this$<n>, if necessary */
8347       if ((thisn_assign = build_thisn_assign ()))
8348         compound = add_stmt_to_compound (compound, NULL_TREE, thisn_assign);
8349
8350       /* Fix the constructor main block if we're adding extra stmts */
8351       if (compound)
8352         {
8353           compound = add_stmt_to_compound (compound, NULL_TREE,
8354                                            BLOCK_EXPR_BODY (main_block));
8355           BLOCK_EXPR_BODY (main_block) = compound;
8356         }
8357     }
8358 }
8359
8360 /* Browse constructors in the super class, searching for a constructor
8361    that doesn't take any argument. Return 0 if one is found, 1
8362    otherwise.  If the current class is an anonymous inner class, look
8363    for something that has the same signature. */
8364
8365 static int
8366 verify_constructor_super (mdecl)
8367      tree mdecl;
8368 {
8369   tree class = CLASSTYPE_SUPER (current_class);
8370   int super_inner = PURE_INNER_CLASS_TYPE_P (class);
8371   tree sdecl;
8372
8373   if (!class)
8374     return 0;
8375
8376   if (ANONYMOUS_CLASS_P (current_class))
8377     {
8378       tree mdecl_arg_type;
8379       SKIP_THIS_AND_ARTIFICIAL_PARMS (mdecl_arg_type, mdecl);
8380       for (sdecl = TYPE_METHODS (class); sdecl; sdecl = TREE_CHAIN (sdecl))
8381         if (DECL_CONSTRUCTOR_P (sdecl))
8382           {
8383             tree arg_type = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (sdecl)));
8384             if (super_inner)
8385               arg_type = TREE_CHAIN (arg_type);
8386             for (; (arg_type != end_params_node 
8387                     && mdecl_arg_type != end_params_node);
8388                  arg_type = TREE_CHAIN (arg_type), 
8389                  mdecl_arg_type = TREE_CHAIN (mdecl_arg_type))
8390               if (TREE_VALUE (arg_type) != TREE_VALUE (mdecl_arg_type))
8391                 break;
8392
8393             if (arg_type == end_params_node && 
8394                 mdecl_arg_type == end_params_node)
8395               return 0;
8396           }
8397     }
8398   else
8399     {
8400       for (sdecl = TYPE_METHODS (class); sdecl; sdecl = TREE_CHAIN (sdecl))
8401         {
8402           tree arg = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (sdecl)));
8403           if (super_inner)
8404             arg = TREE_CHAIN (arg);
8405           if (DECL_CONSTRUCTOR_P (sdecl) && arg == end_params_node)
8406             return 0;
8407         }
8408     }
8409   return 1;
8410 }
8411
8412 /* Generate code for all context remembered for code generation.  */
8413
8414 void
8415 java_expand_classes ()
8416 {
8417   int save_error_count = 0;
8418   static struct parser_ctxt *saved_ctxp = NULL;
8419
8420   java_parse_abort_on_error ();
8421   if (!(ctxp = ctxp_for_generation))
8422     return;
8423   java_layout_classes ();
8424   java_parse_abort_on_error ();
8425
8426   saved_ctxp = ctxp_for_generation;
8427   for (; ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
8428     {
8429       ctxp = ctxp_for_generation;
8430       lang_init_source (2);            /* Error msgs have method prototypes */
8431       java_complete_expand_classes (); /* Complete and expand classes */
8432       java_parse_abort_on_error ();
8433     }
8434
8435   /* Find anonymous classes and expand their constructor, now they
8436      have been fixed. */
8437   for (ctxp_for_generation = saved_ctxp;
8438        ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
8439     {
8440       tree current;
8441       ctxp = ctxp_for_generation;
8442       for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
8443         {
8444           current_class = TREE_TYPE (current);
8445           if (ANONYMOUS_CLASS_P (current_class))
8446             {
8447               tree d;
8448               for (d = TYPE_METHODS (current_class); d; d = TREE_CHAIN (d))
8449                 {
8450                   if (DECL_CONSTRUCTOR_P (d))
8451                     {
8452                       restore_line_number_status (1);
8453                       reset_method_name (d);
8454                       java_complete_expand_method (d);
8455                       restore_line_number_status (0);
8456                       break;    /* We now there are no other ones */
8457                     }
8458                 }
8459             }
8460         }
8461     }
8462
8463   /* If we've found error at that stage, don't try to generate
8464      anything, unless we're emitting xrefs or checking the syntax only
8465      (but not using -fsyntax-only for the purpose of generating
8466      bytecode. */
8467   if (java_error_count && !flag_emit_xref 
8468       && (!flag_syntax_only && !flag_emit_class_files))
8469     return;
8470
8471   /* Now things are stable, go for generation of the class data. */
8472   for (ctxp_for_generation = saved_ctxp;
8473        ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
8474     {
8475       tree current;
8476       ctxp = ctxp_for_generation;
8477       for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
8478         {
8479           current_class = TREE_TYPE (current);
8480           outgoing_cpool = TYPE_CPOOL (current_class);
8481           if (flag_emit_class_files)
8482             write_classfile (current_class);
8483           if (flag_emit_xref)
8484             expand_xref (current_class);
8485           else if (! flag_syntax_only)
8486             finish_class ();
8487         }
8488     }
8489 }
8490
8491 /* Wrap non WFL PRIMARY around a WFL and set EXPR_WFL_QUALIFICATION to
8492    a tree list node containing RIGHT. Fore coming RIGHTs will be
8493    chained to this hook. LOCATION contains the location of the
8494    separating `.' operator.  */
8495
8496 static tree
8497 make_qualified_primary (primary, right, location)
8498      tree primary, right;
8499      int location;
8500 {
8501   tree wfl;
8502
8503   if (TREE_CODE (primary) != EXPR_WITH_FILE_LOCATION)
8504     wfl = build_wfl_wrap (primary, location);
8505   else
8506     {
8507       wfl = primary;
8508       /* If wfl wasn't qualified, we build a first anchor */
8509       if (!EXPR_WFL_QUALIFICATION (wfl))
8510         EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (wfl, NULL_TREE);
8511     }
8512
8513   /* And chain them */
8514   EXPR_WFL_LINECOL (right) = location;
8515   chainon (EXPR_WFL_QUALIFICATION (wfl), build_tree_list (right, NULL_TREE));
8516   PRIMARY_P (wfl) =  1;
8517   return wfl;
8518 }
8519
8520 /* Simple merge of two name separated by a `.' */
8521
8522 static tree
8523 merge_qualified_name (left, right)
8524      tree left, right;
8525 {
8526   tree node;
8527   if (!left && !right)
8528     return NULL_TREE;
8529
8530   if (!left)
8531     return right;
8532
8533   if (!right)
8534     return left;
8535
8536   obstack_grow (&temporary_obstack, IDENTIFIER_POINTER (left),
8537                 IDENTIFIER_LENGTH (left));
8538   obstack_1grow (&temporary_obstack, '.');
8539   obstack_grow0 (&temporary_obstack, IDENTIFIER_POINTER (right),
8540                  IDENTIFIER_LENGTH (right));
8541   node =  get_identifier (obstack_base (&temporary_obstack));
8542   obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
8543   QUALIFIED_P (node) = 1;
8544   return node;
8545 }
8546
8547 /* Merge the two parts of a qualified name into LEFT.  Set the
8548    location information of the resulting node to LOCATION, usually
8549    inherited from the location information of the `.' operator. */
8550
8551 static tree
8552 make_qualified_name (left, right, location)
8553      tree left, right;
8554      int location;
8555 {
8556 #ifdef USE_COMPONENT_REF
8557   tree node = build (COMPONENT_REF, NULL_TREE, left, right);
8558   EXPR_WFL_LINECOL (node) = location;
8559   return node;
8560 #else
8561   tree left_id = EXPR_WFL_NODE (left);
8562   tree right_id = EXPR_WFL_NODE (right);
8563   tree wfl, merge;
8564
8565   merge = merge_qualified_name (left_id, right_id);
8566
8567   /* Left wasn't qualified and is now qualified */
8568   if (!QUALIFIED_P (left_id))
8569     {
8570       tree wfl = build_expr_wfl (left_id, ctxp->filename, 0, 0);
8571       EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (left);
8572       EXPR_WFL_QUALIFICATION (left) = build_tree_list (wfl, NULL_TREE);
8573     }
8574   
8575   wfl = build_expr_wfl (right_id, ctxp->filename, 0, 0);
8576   EXPR_WFL_LINECOL (wfl) = location;
8577   chainon (EXPR_WFL_QUALIFICATION (left), build_tree_list (wfl, NULL_TREE));
8578
8579   EXPR_WFL_NODE (left) = merge;
8580   return left;
8581 #endif
8582 }
8583
8584 /* Extract the last identifier component of the qualified in WFL. The
8585    last identifier is removed from the linked list */
8586
8587 static tree
8588 cut_identifier_in_qualified (wfl)
8589      tree wfl;
8590 {
8591   tree q;
8592   tree previous = NULL_TREE;
8593   for (q = EXPR_WFL_QUALIFICATION (wfl); ; previous = q, q = TREE_CHAIN (q))
8594     if (!TREE_CHAIN (q))
8595       {
8596         if (!previous)
8597           fatal ("Operating on a non qualified qualified WFL - cut_identifier_in_qualified");
8598         TREE_CHAIN (previous) = NULL_TREE;
8599         return TREE_PURPOSE (q);
8600       }
8601 }
8602
8603 /* Resolve the expression name NAME. Return its decl.  */
8604
8605 static tree
8606 resolve_expression_name (id, orig)
8607      tree id;
8608      tree *orig;
8609 {
8610   tree name = EXPR_WFL_NODE (id);
8611   tree decl;
8612
8613   /* 6.5.5.1: Simple expression names */
8614   if (!PRIMARY_P (id) && !QUALIFIED_P (name))
8615     {
8616       /* 15.13.1: NAME can appear within the scope of a local variable
8617          declaration */
8618       if ((decl = IDENTIFIER_LOCAL_VALUE (name)))
8619         return decl;
8620
8621       /* 15.13.1: NAME can appear within a class declaration */
8622       else 
8623         {
8624           decl = lookup_field_wrapper (current_class, name);
8625           if (decl)
8626             {
8627               tree access = NULL_TREE;
8628               int fs = FIELD_STATIC (decl);
8629
8630               /* If we're accessing an outer scope local alias, make
8631                  sure we change the name of the field we're going to
8632                  build access to. */
8633               if (FIELD_LOCAL_ALIAS_USED (decl))
8634                 name = DECL_NAME (decl);
8635
8636               /* Instance variable (8.3.1.1) can't appear within
8637                  static method, static initializer or initializer for
8638                  a static variable. */
8639               if (!fs && METHOD_STATIC (current_function_decl))
8640                 {
8641                   static_ref_err (id, name, current_class);
8642                   return error_mark_node;
8643                 }
8644               /* Instance variables can't appear as an argument of
8645                  an explicit constructor invocation */
8646               if (!fs && ctxp->explicit_constructor_p)
8647                 {
8648                   parse_error_context
8649                     (id, "Can't reference `%s' before the superclass constructor has been called", IDENTIFIER_POINTER (name));
8650                   return error_mark_node;
8651                 }
8652
8653               /* If we're processing an inner class and we're trying
8654                  to access a field belonging to an outer class, build
8655                  the access to the field */
8656               if (!fs && outer_field_access_p (current_class, decl))
8657                 return build_outer_field_access (id, decl);
8658
8659               /* Otherwise build what it takes to access the field */
8660               access = build_field_ref ((fs ? NULL_TREE : current_this),
8661                                         DECL_CONTEXT (decl), name);
8662               if (fs && !flag_emit_class_files && !flag_emit_xref)
8663                 access = build_class_init (DECL_CONTEXT (access), access);
8664               /* We may be asked to save the real field access node */
8665               if (orig)
8666                 *orig = access;
8667               /* And we return what we got */
8668               return access;
8669             }
8670           /* Fall down to error report on undefined variable */
8671         }
8672     }
8673   /* 6.5.5.2 Qualified Expression Names */
8674   else
8675     {
8676       if (orig)
8677         *orig = NULL_TREE;
8678       qualify_ambiguous_name (id);
8679       /* 15.10.1 Field Access Using a Primary and/or Expression Name */
8680       /* 15.10.2: Accessing Superclass Members using super */
8681       return resolve_field_access (id, orig, NULL);
8682     }
8683
8684   /* We've got an error here */
8685   parse_error_context (id, "Undefined variable `%s'", 
8686                        IDENTIFIER_POINTER (name));
8687
8688   return error_mark_node;
8689 }
8690
8691 static void
8692 static_ref_err (wfl, field_id, class_type)
8693     tree wfl, field_id, class_type;
8694 {
8695   parse_error_context 
8696     (wfl, 
8697      "Can't make a static reference to nonstatic variable `%s' in class `%s'",
8698      IDENTIFIER_POINTER (field_id), 
8699      IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class_type))));
8700 }
8701
8702 /* 15.10.1 Field Acess Using a Primary and/or Expression Name.
8703    We return something suitable to generate the field access. We also
8704    return the field decl in FIELD_DECL and its type in FIELD_TYPE.  If
8705    recipient's address can be null. */
8706
8707 static tree
8708 resolve_field_access (qual_wfl, field_decl, field_type)
8709      tree qual_wfl;
8710      tree *field_decl, *field_type;
8711 {
8712   int is_static = 0;
8713   tree field_ref;
8714   tree decl, where_found, type_found;
8715
8716   if (resolve_qualified_expression_name (qual_wfl, &decl,
8717                                          &where_found, &type_found))
8718     return error_mark_node;
8719
8720   /* Resolve the LENGTH field of an array here */
8721   if (DECL_P (decl) && DECL_NAME (decl) == length_identifier_node 
8722       && TYPE_ARRAY_P (type_found) 
8723       && ! flag_emit_class_files && ! flag_emit_xref)
8724     {
8725       tree length = build_java_array_length_access (where_found);
8726       field_ref =
8727         build_java_arraynull_check (type_found, length, int_type_node);
8728
8729       /* In case we're dealing with a static array, we need to
8730          initialize its class before the array length can be fetched.
8731          It's also a good time to create a DECL_RTL for the field if
8732          none already exists, otherwise if the field was declared in a
8733          class found in an external file and hasn't been (and won't
8734          be) accessed for its value, none will be created. */
8735       if (TREE_CODE (where_found) == VAR_DECL && FIELD_STATIC (where_found))
8736         {
8737           build_static_field_ref (where_found);
8738           field_ref = build_class_init (DECL_CONTEXT (where_found), field_ref);
8739         }
8740     }
8741   /* We might have been trying to resolve field.method(). In which
8742      case, the resolution is over and decl is the answer */
8743   else if (JDECL_P (decl) && IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)) == decl)
8744     field_ref = decl;
8745   else if (JDECL_P (decl))
8746     {
8747       int static_final_found = 0;
8748       if (!type_found)
8749         type_found = DECL_CONTEXT (decl);
8750       is_static = JDECL_P (decl) && FIELD_STATIC (decl);
8751       if (FIELD_FINAL (decl) 
8752           && JPRIMITIVE_TYPE_P (TREE_TYPE (decl))
8753           && DECL_INITIAL (decl))
8754         {
8755           field_ref = java_complete_tree (DECL_INITIAL (decl));
8756           static_final_found = 1;
8757         }
8758       else
8759         field_ref = build_field_ref ((is_static && !flag_emit_xref? 
8760                                       NULL_TREE : where_found), 
8761                                      type_found, DECL_NAME (decl));
8762       if (field_ref == error_mark_node)
8763         return error_mark_node;
8764       if (is_static && !static_final_found 
8765           && !flag_emit_class_files && !flag_emit_xref)
8766         field_ref = build_class_init (DECL_CONTEXT (decl), field_ref);
8767     }
8768   else
8769     field_ref = decl;
8770
8771   if (field_decl)
8772     *field_decl = decl;
8773   if (field_type)
8774     *field_type = (QUAL_DECL_TYPE (decl) ? 
8775                    QUAL_DECL_TYPE (decl) : TREE_TYPE (decl));
8776   return field_ref;
8777 }
8778
8779 /* If NODE is an access to f static field, strip out the class
8780    initialization part and return the field decl, otherwise, return
8781    NODE. */
8782
8783 static tree
8784 strip_out_static_field_access_decl (node)
8785     tree node;
8786 {
8787   if (TREE_CODE (node) == COMPOUND_EXPR)
8788     {
8789       tree op1 = TREE_OPERAND (node, 1);
8790       if (TREE_CODE (op1) == COMPOUND_EXPR)
8791          {
8792            tree call = TREE_OPERAND (op1, 0);
8793            if (TREE_CODE (call) == CALL_EXPR
8794                && TREE_CODE (TREE_OPERAND (call, 0)) == ADDR_EXPR
8795                && TREE_OPERAND (TREE_OPERAND (call, 0), 0)
8796                == soft_initclass_node)
8797              return TREE_OPERAND (op1, 1);
8798          }
8799       else if (JDECL_P (op1))
8800         return op1;
8801     }
8802   return node;
8803 }
8804
8805 /* 6.5.5.2: Qualified Expression Names */
8806
8807 static int
8808 resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
8809      tree wfl;
8810      tree *found_decl, *type_found, *where_found;
8811 {
8812   int from_type = 0;            /* Field search initiated from a type */
8813   int from_super = 0, from_cast = 0, from_qualified_this = 0;
8814   int previous_call_static = 0;
8815   int is_static;
8816   tree decl = NULL_TREE, type = NULL_TREE, q;
8817   /* For certain for of inner class instantiation */
8818   tree saved_current, saved_this;               
8819 #define RESTORE_THIS_AND_CURRENT_CLASS                          \
8820   { current_class = saved_current; current_this = saved_this;}
8821
8822   *type_found = *where_found = NULL_TREE;
8823
8824   for (q = EXPR_WFL_QUALIFICATION (wfl); q; q = TREE_CHAIN (q))
8825     {
8826       tree qual_wfl = QUAL_WFL (q);
8827       tree ret_decl;            /* for EH checking */
8828       int location;             /* for EH checking */
8829
8830       /* 15.10.1 Field Access Using a Primary */
8831       switch (TREE_CODE (qual_wfl))
8832         {
8833         case CALL_EXPR:
8834         case NEW_CLASS_EXPR:
8835           /* If the access to the function call is a non static field,
8836              build the code to access it. */
8837           if (JDECL_P (decl) && !FIELD_STATIC (decl))
8838             {
8839               decl = maybe_access_field (decl, *where_found, 
8840                                          DECL_CONTEXT (decl));
8841               if (decl == error_mark_node)
8842                 return 1;
8843             }
8844
8845           /* And code for the function call */
8846           if (complete_function_arguments (qual_wfl))
8847             return 1;
8848
8849           /* We might have to setup a new current class and a new this
8850              for the search of an inner class, relative to the type of
8851              a expression resolved as `decl'. The current values are
8852              saved and restored shortly after */
8853           saved_current = current_class;
8854           saved_this = current_this;
8855           if (decl && TREE_CODE (qual_wfl) == NEW_CLASS_EXPR)
8856             {
8857               current_class = type;
8858               current_this = decl;
8859             }
8860
8861           if (from_super && TREE_CODE (qual_wfl) == CALL_EXPR)
8862             CALL_USING_SUPER (qual_wfl) = 1;
8863           location = (TREE_CODE (qual_wfl) == CALL_EXPR ?
8864                       EXPR_WFL_LINECOL (TREE_OPERAND (qual_wfl, 0)) : 0);
8865           *where_found = patch_method_invocation (qual_wfl, decl, type, 
8866                                                   &is_static, &ret_decl);
8867           if (*where_found == error_mark_node)
8868             {
8869               RESTORE_THIS_AND_CURRENT_CLASS;
8870               return 1;
8871             }
8872           *type_found = type = QUAL_DECL_TYPE (*where_found);
8873
8874           /* If we're creating an inner class instance, check for that
8875              an enclosing instance is in scope */
8876           if (TREE_CODE (qual_wfl) == NEW_CLASS_EXPR
8877               && INNER_ENCLOSING_SCOPE_CHECK (type))
8878             {
8879               parse_error_context 
8880                 (qual_wfl, "No enclosing instance for inner class `%s' is in scope%s",
8881                  lang_printable_name (type, 0),
8882                  (!current_this ? "" :
8883                   "; an explicit one must be provided when creating this inner class"));
8884               RESTORE_THIS_AND_CURRENT_CLASS;
8885               return 1;
8886             }
8887
8888           /* In case we had to change then to resolve a inner class
8889              instantiation using a primary qualified by a `new' */
8890           RESTORE_THIS_AND_CURRENT_CLASS;
8891
8892           /* EH check */
8893           if (location)
8894             check_thrown_exceptions (location, ret_decl);
8895
8896           /* If the previous call was static and this one is too,
8897              build a compound expression to hold the two (because in
8898              that case, previous function calls aren't transported as
8899              forcoming function's argument. */
8900           if (previous_call_static && is_static)
8901             {
8902               decl = build (COMPOUND_EXPR, type, decl, *where_found);
8903               TREE_SIDE_EFFECTS (decl) = 1;
8904             }
8905           else
8906             {
8907               previous_call_static = is_static;
8908               decl = *where_found;
8909             }
8910           from_type = 0;
8911           continue;
8912
8913         case NEW_ARRAY_EXPR:
8914         case NEW_ANONYMOUS_ARRAY_EXPR:
8915           *where_found = decl = java_complete_tree (qual_wfl);
8916           if (decl == error_mark_node)
8917             return 1;
8918           *type_found = type = QUAL_DECL_TYPE (decl);
8919           CLASS_LOADED_P (type) = 1;
8920           continue;
8921
8922         case CONVERT_EXPR:
8923           *where_found = decl = java_complete_tree (qual_wfl);
8924           if (decl == error_mark_node)
8925             return 1;
8926           *type_found = type = QUAL_DECL_TYPE (decl);
8927           from_cast = 1;
8928           continue;
8929
8930         case CONDITIONAL_EXPR:
8931         case STRING_CST:
8932         case MODIFY_EXPR:
8933           *where_found = decl = java_complete_tree (qual_wfl);
8934           if (decl == error_mark_node)
8935             return 1;
8936           *type_found = type = QUAL_DECL_TYPE (decl);
8937           continue;
8938
8939         case ARRAY_REF:
8940           /* If the access to the function call is a non static field,
8941              build the code to access it. */
8942           if (JDECL_P (decl) && !FIELD_STATIC (decl))
8943             {
8944               decl = maybe_access_field (decl, *where_found, type);
8945               if (decl == error_mark_node)
8946                 return 1;
8947             }
8948           /* And code for the array reference expression */
8949           decl = java_complete_tree (qual_wfl);
8950           if (decl == error_mark_node)
8951             return 1;
8952           type = QUAL_DECL_TYPE (decl);
8953           continue;
8954
8955         case PLUS_EXPR:
8956           if ((decl = java_complete_tree (qual_wfl)) == error_mark_node)
8957             return 1;
8958           if ((type = patch_string (decl)))
8959             decl = type;
8960           *where_found = QUAL_RESOLUTION (q) = decl;
8961           *type_found = type = TREE_TYPE (decl);
8962           break;
8963
8964         case CLASS_LITERAL:
8965           if ((decl = java_complete_tree (qual_wfl)) == error_mark_node)
8966             return 1;
8967           *where_found = QUAL_RESOLUTION (q) = decl;
8968           *type_found = type = TREE_TYPE (decl);
8969           break;
8970
8971         default:
8972           /* Fix for -Wall Just go to the next statement. Don't
8973              continue */
8974           break;
8975         }
8976
8977       /* If we fall here, we weren't processing a (static) function call. */
8978       previous_call_static = 0;
8979
8980       /* It can be the keyword THIS */
8981       if (EXPR_WFL_NODE (qual_wfl) == this_identifier_node)
8982         {
8983           if (!current_this)
8984             {
8985               parse_error_context 
8986                 (wfl, "Keyword `this' used outside allowed context");
8987               return 1;
8988             }
8989           if (ctxp->explicit_constructor_p)
8990             {
8991               parse_error_context (wfl, "Can't reference `this' before the superclass constructor has been called");
8992               return 1;
8993             }
8994           /* We have to generate code for intermediate acess */
8995           if (!from_type || TREE_TYPE (TREE_TYPE (current_this)) == type)
8996             {
8997               *where_found = decl = current_this;
8998               *type_found = type = QUAL_DECL_TYPE (decl);
8999             }
9000           /* We're trying to access the this from somewhere else... */
9001           else
9002             {
9003               *where_found = decl = build_current_thisn (type);
9004               from_qualified_this = 1;
9005             }
9006
9007           from_type = 0;
9008           continue;
9009         }
9010
9011       /* 15.10.2 Accessing Superclass Members using SUPER */
9012       if (EXPR_WFL_NODE (qual_wfl) == super_identifier_node)
9013         {
9014           tree node;
9015           /* Check on the restricted use of SUPER */
9016           if (METHOD_STATIC (current_function_decl)
9017               || current_class == object_type_node)
9018             {
9019               parse_error_context 
9020                 (wfl, "Keyword `super' used outside allowed context");
9021               return 1;
9022             }
9023           /* Otherwise, treat SUPER as (SUPER_CLASS)THIS */
9024           node = build_cast (EXPR_WFL_LINECOL (qual_wfl), 
9025                              CLASSTYPE_SUPER (current_class),
9026                              build_this (EXPR_WFL_LINECOL (qual_wfl)));
9027           *where_found = decl = java_complete_tree (node);
9028           if (decl == error_mark_node)
9029             return 1;
9030           *type_found = type = QUAL_DECL_TYPE (decl);
9031           from_super = from_type = 1;
9032           continue;
9033         }
9034
9035       /* 15.13.1: Can't search for field name in packages, so we
9036          assume a variable/class name was meant. */
9037       if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
9038         {
9039           tree name = resolve_package (wfl, &q);
9040           if (name)
9041             {
9042               tree list;
9043               *where_found = decl = resolve_no_layout (name, qual_wfl);
9044               /* We want to be absolutely sure that the class is laid
9045                  out. We're going to search something inside it. */
9046               *type_found = type = TREE_TYPE (decl);
9047               layout_class (type);
9048               from_type = 1;
9049
9050               /* Fix them all the way down, if any are left. */
9051               if (q)
9052                 {
9053                   list = TREE_CHAIN (q);
9054                   while (list)
9055                     {
9056                       RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (list)) = 1;
9057                       RESOLVE_PACKAGE_NAME_P (QUAL_WFL (list)) = 0;
9058                       list = TREE_CHAIN (list);
9059                     }
9060                 }
9061             }
9062           else
9063             {
9064               if (from_super || from_cast)
9065                 parse_error_context 
9066                   ((from_cast ? qual_wfl : wfl),
9067                    "No variable `%s' defined in class `%s'",
9068                    IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
9069                    lang_printable_name (type, 0));
9070               else
9071                 parse_error_context
9072                   (qual_wfl, "Undefined variable or class name: `%s'",
9073                    IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)));
9074               return 1;
9075             }
9076         }
9077
9078       /* We have a type name. It's been already resolved when the
9079          expression was qualified. */
9080       else if (RESOLVE_TYPE_NAME_P (qual_wfl))
9081         {
9082           if (!(decl = QUAL_RESOLUTION (q)))
9083             return 1;           /* Error reported already */
9084
9085           /* Sneak preview. If next we see a `new', we're facing a
9086              qualification with resulted in a type being selected
9087              instead of a field.  Report the error */
9088           if(TREE_CHAIN (q) 
9089              && TREE_CODE (TREE_PURPOSE (TREE_CHAIN (q))) == NEW_CLASS_EXPR)
9090             {
9091               parse_error_context (qual_wfl, "Undefined variable `%s'",
9092                                    IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
9093               return 1;
9094             }
9095
9096           if (not_accessible_p (TREE_TYPE (decl), decl, 0))
9097             {
9098               parse_error_context 
9099                 (qual_wfl, "Can't access %s field `%s.%s' from `%s'",
9100                  java_accstring_lookup (get_access_flags_from_decl (decl)),
9101                  GET_TYPE_NAME (type),
9102                  IDENTIFIER_POINTER (DECL_NAME (decl)),
9103                  IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
9104               return 1;
9105             }
9106           check_deprecation (qual_wfl, decl);
9107
9108           type = TREE_TYPE (decl);
9109           from_type = 1;
9110         }
9111       /* We resolve and expression name */
9112       else 
9113         {
9114           tree field_decl = NULL_TREE;
9115
9116           /* If there exists an early resolution, use it. That occurs
9117              only once and we know that there are more things to
9118              come. Don't do that when processing something after SUPER
9119              (we need more thing to be put in place below */
9120           if (!from_super && QUAL_RESOLUTION (q))
9121             {
9122               decl = QUAL_RESOLUTION (q);
9123               if (!type)
9124                 {
9125                   if (TREE_CODE (decl) == FIELD_DECL && !FIELD_STATIC (decl))
9126                     {
9127                       if (current_this)
9128                         *where_found = current_this;
9129                       else
9130                         {
9131                           static_ref_err (qual_wfl, DECL_NAME (decl),
9132                                           current_class);
9133                           return 1;
9134                         }
9135                     }
9136                   else
9137                     {
9138                       *where_found = TREE_TYPE (decl);
9139                       if (TREE_CODE (*where_found) == POINTER_TYPE)
9140                         *where_found = TREE_TYPE (*where_found);
9141                     }
9142                 }
9143             }
9144
9145           /* We have to search for a field, knowing the type of its
9146              container. The flag FROM_TYPE indicates that we resolved
9147              the last member of the expression as a type name, which
9148              means that for the resolution of this field, we'll look
9149              for other errors than if it was resolved as a member of
9150              an other field. */
9151           else
9152             {
9153               int is_static;
9154               tree field_decl_type; /* For layout */
9155
9156               if (!from_type && !JREFERENCE_TYPE_P (type))
9157                 {
9158                   parse_error_context 
9159                     (qual_wfl, "Attempt to reference field `%s' in `%s %s'",
9160                      IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
9161                      lang_printable_name (type, 0),
9162                      IDENTIFIER_POINTER (DECL_NAME (field_decl)));
9163                   return 1;
9164                 }
9165               
9166               field_decl = lookup_field_wrapper (type,
9167                                                  EXPR_WFL_NODE (qual_wfl));
9168               if (field_decl == NULL_TREE)
9169                 {
9170                   parse_error_context 
9171                     (qual_wfl, "No variable `%s' defined in type `%s'",
9172                      IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)), 
9173                      GET_TYPE_NAME (type));
9174                   return 1;
9175                 }
9176               if (field_decl == error_mark_node)
9177                 return 1;
9178
9179               /* Layout the type of field_decl, since we may need
9180                  it. Don't do primitive types or loaded classes. The
9181                  situation of non primitive arrays may not handled
9182                  properly here. FIXME */
9183               if (TREE_CODE (TREE_TYPE (field_decl)) == POINTER_TYPE)
9184                 field_decl_type = TREE_TYPE (TREE_TYPE (field_decl));
9185               else
9186                 field_decl_type = TREE_TYPE (field_decl);
9187               if (!JPRIMITIVE_TYPE_P (field_decl_type) 
9188                   && !CLASS_LOADED_P (field_decl_type)
9189                   && !TYPE_ARRAY_P (field_decl_type))
9190                 resolve_and_layout (field_decl_type, NULL_TREE);
9191               if (TYPE_ARRAY_P (field_decl_type))
9192                 CLASS_LOADED_P (field_decl_type) = 1;
9193               
9194               /* Check on accessibility here */
9195               if (not_accessible_p (type, field_decl, from_super))
9196                 {
9197                   parse_error_context 
9198                     (qual_wfl,
9199                      "Can't access %s field `%s.%s' from `%s'",
9200                      java_accstring_lookup 
9201                        (get_access_flags_from_decl (field_decl)),
9202                      GET_TYPE_NAME (type),
9203                      IDENTIFIER_POINTER (DECL_NAME (field_decl)),
9204                      IDENTIFIER_POINTER 
9205                        (DECL_NAME (TYPE_NAME (current_class))));
9206                   return 1;
9207                 }
9208               check_deprecation (qual_wfl, field_decl);
9209               
9210               /* There are things to check when fields are accessed
9211                  from type. There are no restrictions on a static
9212                  declaration of the field when it is accessed from an
9213                  interface */
9214               is_static = FIELD_STATIC (field_decl);
9215               if (!from_super && from_type 
9216                   && !TYPE_INTERFACE_P (type) 
9217                   && !is_static 
9218                   && (current_function_decl 
9219                       && METHOD_STATIC (current_function_decl)))
9220                 {
9221                   static_ref_err (qual_wfl, EXPR_WFL_NODE (qual_wfl), type);
9222                   return 1;
9223                 }
9224               from_cast = from_super = 0;
9225
9226               /* It's an access from a type but it isn't static, we
9227                  make it relative to `this'. */
9228               if (!is_static && from_type)
9229                 decl = current_this;
9230
9231               /* If we need to generate something to get a proper
9232                  handle on what this field is accessed from, do it
9233                  now. */
9234               if (!is_static)
9235                 {
9236                   decl = maybe_access_field (decl, *where_found, *type_found);
9237                   if (decl == error_mark_node)
9238                     return 1;
9239                 }
9240
9241               /* We want to keep the location were found it, and the type
9242                  we found. */
9243               *where_found = decl;
9244               *type_found = type;
9245
9246               /* Generate the correct expression for field access from
9247                  qualified this */
9248               if (from_qualified_this)
9249                 {
9250                   field_decl = build_outer_field_access (qual_wfl, field_decl);
9251                   from_qualified_this = 0;
9252                 }
9253
9254               /* This is the decl found and eventually the next one to
9255                  search from */
9256               decl = field_decl;
9257             }
9258           from_type = 0;
9259           type = QUAL_DECL_TYPE (decl);
9260
9261           /* Sneak preview. If decl is qualified by a `new', report
9262              the error here to be accurate on the peculiar construct */
9263           if (TREE_CHAIN (q) 
9264               && TREE_CODE (TREE_PURPOSE (TREE_CHAIN (q))) == NEW_CLASS_EXPR
9265               && !JREFERENCE_TYPE_P (type))
9266             {
9267               parse_error_context (qual_wfl, "Attempt to reference field `new' in a `%s'", 
9268                                    lang_printable_name (type, 0));
9269               return 1;
9270             }
9271         }
9272       /* `q' might have changed due to a after package resolution
9273          re-qualification */
9274       if (!q)
9275         break;
9276     }
9277   *found_decl = decl;
9278   return 0;
9279 }
9280
9281 /* 6.6 Qualified name and access control. Returns 1 if MEMBER (a decl)
9282    can't be accessed from REFERENCE (a record type). */
9283
9284 static int
9285 not_accessible_p (reference, member, from_super)
9286      tree reference, member;
9287      int from_super;
9288 {
9289   int access_flag = get_access_flags_from_decl (member);
9290
9291   /* Access always granted for members declared public */
9292   if (access_flag & ACC_PUBLIC)
9293     return 0;
9294   
9295   /* Check access on protected members */
9296   if (access_flag & ACC_PROTECTED)
9297     {
9298       /* Access granted if it occurs from within the package
9299          containing the class in which the protected member is
9300          declared */
9301       if (class_in_current_package (DECL_CONTEXT (member)))
9302         return 0;
9303
9304       /* If accessed with the form `super.member', then access is granted */
9305       if (from_super)
9306         return 0;
9307
9308       /* Otherwise, access is granted if occuring from the class where
9309          member is declared or a subclass of it */
9310       if (inherits_from_p (reference, DECL_CONTEXT (member)))
9311         return 0;
9312       return 1;
9313     }
9314
9315   /* Check access on private members. Access is granted only if it
9316      occurs from within the class in which it is declared. Exceptions
9317      are accesses from inner-classes. This section is probably not
9318      complete. FIXME */
9319   if (access_flag & ACC_PRIVATE)
9320     return (current_class == DECL_CONTEXT (member) ? 0 : 
9321             (INNER_CLASS_TYPE_P (current_class) ? 0 : 1));
9322
9323   /* Default access are permitted only when occuring within the
9324      package in which the type (REFERENCE) is declared. In other words,
9325      REFERENCE is defined in the current package */
9326   if (ctxp->package)
9327     return !class_in_current_package (reference);
9328
9329   /* Otherwise, access is granted */
9330   return 0;
9331 }
9332
9333 /* Test deprecated decl access.  */
9334 static void
9335 check_deprecation (wfl, decl)
9336      tree wfl, decl;
9337 {
9338   const char *file = DECL_SOURCE_FILE (decl);
9339   /* Complain if the field is deprecated and the file it was defined
9340      in isn't compiled at the same time the file which contains its
9341      use is */
9342   if (DECL_DEPRECATED (decl) 
9343       && !IS_A_COMMAND_LINE_FILENAME_P (get_identifier (file)))
9344     {
9345       char the [20];
9346       switch (TREE_CODE (decl))
9347         {
9348         case FUNCTION_DECL:
9349           strcpy (the, "method");
9350           break;
9351         case FIELD_DECL:
9352           strcpy (the, "field");
9353           break;
9354         case TYPE_DECL:
9355           strcpy (the, "class");
9356           break;
9357         default:
9358           fatal ("unexpected DECL code - check_deprecation");
9359         }
9360       parse_warning_context 
9361         (wfl, "The %s `%s' in class `%s' has been deprecated", 
9362          the, lang_printable_name (decl, 0),
9363          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)))));
9364     }
9365 }
9366
9367 /* Returns 1 if class was declared in the current package, 0 otherwise */
9368
9369 static int
9370 class_in_current_package (class)
9371      tree class;
9372 {
9373   static tree cache = NULL_TREE;
9374   int qualified_flag;
9375   tree left;
9376
9377   if (cache == class)
9378     return 1;
9379
9380   qualified_flag = QUALIFIED_P (DECL_NAME (TYPE_NAME (class)));
9381
9382   /* If the current package is empty and the name of CLASS is
9383      qualified, class isn't in the current package.  If there is a
9384      current package and the name of the CLASS is not qualified, class
9385      isn't in the current package */
9386   if ((!ctxp->package && qualified_flag) || (ctxp->package && !qualified_flag))
9387     return 0;
9388
9389   /* If there is not package and the name of CLASS isn't qualified,
9390      they belong to the same unnamed package */
9391   if (!ctxp->package && !qualified_flag)
9392     return 1;
9393
9394   /* Compare the left part of the name of CLASS with the package name */
9395   breakdown_qualified (&left, NULL, DECL_NAME (TYPE_NAME (class)));
9396   if (ctxp->package == left)
9397     {
9398       cache = class;
9399       return 1;
9400     }
9401   return 0;
9402 }
9403
9404 /* This function may generate code to access DECL from WHERE. This is
9405    done only if certain conditions meet.  */
9406
9407 static tree
9408 maybe_access_field (decl, where, type)
9409   tree decl, where, type;
9410 {
9411   if (TREE_CODE (decl) == FIELD_DECL && decl != current_this
9412       && !FIELD_STATIC (decl))
9413     decl = build_field_ref (where ? where : current_this, 
9414                             (type ? type : DECL_CONTEXT (decl)),
9415                             DECL_NAME (decl));
9416   return decl;
9417 }
9418
9419 /* Build a method invocation, by patching PATCH. If non NULL
9420    and according to the situation, PRIMARY and WHERE may be
9421    used. IS_STATIC is set to 1 if the invoked function is static. */
9422
9423 static tree
9424 patch_method_invocation (patch, primary, where, is_static, ret_decl)
9425      tree patch, primary, where;
9426      int *is_static;
9427      tree *ret_decl;
9428 {
9429   tree wfl = TREE_OPERAND (patch, 0);
9430   tree args = TREE_OPERAND (patch, 1);
9431   tree name = EXPR_WFL_NODE (wfl);
9432   tree list;
9433   int is_static_flag = 0;
9434   int is_super_init = 0;
9435   tree this_arg = NULL_TREE;
9436   
9437   /* Should be overriden if everything goes well. Otherwise, if
9438      something fails, it should keep this value. It stop the
9439      evaluation of a bogus assignment. See java_complete_tree,
9440      MODIFY_EXPR: for the reasons why we sometimes want to keep on
9441      evaluating an assignment */
9442   TREE_TYPE (patch) = error_mark_node;
9443
9444   /* Since lookup functions are messing with line numbers, save the
9445      context now.  */
9446   java_parser_context_save_global ();
9447
9448   /* 15.11.1: Compile-Time Step 1: Determine Class or Interface to Search */
9449
9450   /* Resolution of qualified name, excluding constructors */
9451   if (QUALIFIED_P (name) && !CALL_CONSTRUCTOR_P (patch))
9452     {
9453       tree identifier, identifier_wfl, type, resolved;
9454       /* Extract the last IDENTIFIER of the qualified
9455          expression. This is a wfl and we will use it's location
9456          data during error report. */
9457       identifier_wfl = cut_identifier_in_qualified (wfl);
9458       identifier = EXPR_WFL_NODE (identifier_wfl);
9459       
9460       /* Given the context, IDENTIFIER is syntactically qualified
9461          as a MethodName. We need to qualify what's before */
9462       qualify_ambiguous_name (wfl);
9463       resolved = resolve_field_access (wfl, NULL, NULL);
9464
9465       if (resolved == error_mark_node)
9466         PATCH_METHOD_RETURN_ERROR ();
9467
9468       type = GET_SKIP_TYPE (resolved);
9469       resolve_and_layout (type, NULL_TREE);
9470       
9471       if (JPRIMITIVE_TYPE_P (type))
9472         {
9473         parse_error_context
9474           (identifier_wfl,
9475           "Can't invoke a method on primitive type `%s'",
9476           IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
9477         PATCH_METHOD_RETURN_ERROR ();         
9478       }      
9479       
9480       list = lookup_method_invoke (0, identifier_wfl, type, identifier, args);
9481       args = nreverse (args);
9482
9483       /* We're resolving a call from a type */
9484       if (TREE_CODE (resolved) == TYPE_DECL)
9485         {
9486           if (CLASS_INTERFACE (resolved))
9487             {
9488               parse_error_context
9489                 (identifier_wfl,
9490                 "Can't make static reference to method `%s' in interface `%s'",
9491                  IDENTIFIER_POINTER (identifier), 
9492                  IDENTIFIER_POINTER (name));
9493               PATCH_METHOD_RETURN_ERROR ();
9494             }
9495           if (list && !METHOD_STATIC (list))
9496             {
9497               char *fct_name = xstrdup (lang_printable_name (list, 0));
9498               parse_error_context 
9499                 (identifier_wfl,
9500                  "Can't make static reference to method `%s %s' in class `%s'",
9501                  lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0), 
9502                  fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
9503               free (fct_name);
9504               PATCH_METHOD_RETURN_ERROR ();
9505             }
9506         }
9507       else
9508         this_arg = primary = resolved;
9509       
9510       /* IDENTIFIER_WFL will be used to report any problem further */
9511       wfl = identifier_wfl;
9512     }
9513   /* Resolution of simple names, names generated after a primary: or
9514      constructors */
9515   else
9516     {
9517       tree class_to_search = NULL_TREE;
9518       int lc;                   /* Looking for Constructor */
9519       
9520       /* We search constructor in their target class */
9521       if (CALL_CONSTRUCTOR_P (patch))
9522         {
9523           if (TREE_CODE (patch) == NEW_CLASS_EXPR)
9524             class_to_search = EXPR_WFL_NODE (wfl);
9525           else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) == 
9526                    this_identifier_node)
9527             class_to_search = NULL_TREE;
9528           else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) ==
9529                    super_identifier_node)
9530             {
9531               is_super_init = 1;
9532               if (CLASSTYPE_SUPER (current_class))
9533                 class_to_search = 
9534                   DECL_NAME (TYPE_NAME (CLASSTYPE_SUPER (current_class)));
9535               else
9536                 {
9537                   parse_error_context (wfl, "Can't invoke super constructor on java.lang.Object");
9538                   PATCH_METHOD_RETURN_ERROR ();
9539                 }
9540             }
9541
9542           /* Class to search is NULL if we're searching the current one */
9543           if (class_to_search)
9544             {
9545               class_to_search = resolve_and_layout (class_to_search, wfl);
9546
9547               if (!class_to_search)
9548                 {
9549                   parse_error_context 
9550                     (wfl, "Class `%s' not found in type declaration",
9551                      IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
9552                   PATCH_METHOD_RETURN_ERROR ();
9553                 }
9554               
9555               /* Can't instantiate an abstract class, but we can
9556                  invoke it's constructor. It's use within the `new'
9557                  context is denied here. */
9558               if (CLASS_ABSTRACT (class_to_search) 
9559                   && TREE_CODE (patch) == NEW_CLASS_EXPR)
9560                 {
9561                   parse_error_context 
9562                     (wfl, "Class `%s' is an abstract class. It can't be instantiated",
9563                      IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
9564                   PATCH_METHOD_RETURN_ERROR ();
9565                 }
9566
9567               class_to_search = TREE_TYPE (class_to_search);
9568             }
9569           else
9570             class_to_search = current_class;
9571           lc = 1;
9572         }
9573       /* This is a regular search in the local class, unless an
9574          alternate class is specified. */
9575       else
9576         {
9577           class_to_search = (where ? where : current_class);
9578           lc = 0;
9579         }
9580
9581       /* NAME is a simple identifier or comes from a primary. Search
9582          in the class whose declaration contain the method being
9583          invoked. */
9584       resolve_and_layout (class_to_search, NULL_TREE);
9585
9586       list = lookup_method_invoke (lc, wfl, class_to_search, name, args);
9587       /* Don't continue if no method were found, as the next statement
9588          can't be executed then. */
9589       if (!list)
9590         PATCH_METHOD_RETURN_ERROR ();
9591
9592       /* Check for static reference if non static methods */
9593       if (check_for_static_method_reference (wfl, patch, list, 
9594                                              class_to_search, primary))
9595         PATCH_METHOD_RETURN_ERROR ();
9596
9597       /* Check for inner classes creation from illegal contexts */
9598       if (lc && (INNER_CLASS_TYPE_P (class_to_search)
9599                  && !CLASS_STATIC (TYPE_NAME (class_to_search)))
9600           && INNER_ENCLOSING_SCOPE_CHECK (class_to_search))
9601         {
9602           parse_error_context 
9603             (wfl, "No enclosing instance for inner class `%s' is in scope%s",
9604              lang_printable_name (class_to_search, 0),
9605              (!current_this ? "" :
9606               "; an explicit one must be provided when creating this inner class"));
9607           PATCH_METHOD_RETURN_ERROR ();
9608         }
9609
9610       /* Non static methods are called with the current object extra
9611          argument. If patch a `new TYPE()', the argument is the value
9612          returned by the object allocator. If method is resolved as a
9613          primary, use the primary otherwise use the current THIS. */
9614       args = nreverse (args);
9615       if (TREE_CODE (patch) != NEW_CLASS_EXPR)
9616         {
9617           this_arg = primary ? primary : current_this;
9618
9619           /* If we're using an access method, things are different.
9620              There are two familly of cases:
9621
9622              1) We're not generating bytecodes:
9623
9624              - LIST is non static. It's invocation is transformed from
9625                x(a1,...,an) into this$<n>.x(a1,....an).
9626              - LIST is static. It's invocation is transformed from
9627                x(a1,...,an) into TYPE_OF(this$<n>).x(a1,....an)
9628
9629              2) We're generating bytecodes:
9630              
9631              - LIST is non static. It's invocation is transformed from
9632                x(a1,....,an) into access$<n>(this$<n>,a1,...,an).
9633              - LIST is static. It's invocation is transformed from
9634                x(a1,....,an) into TYPEOF(this$<n>).x(a1,....an).
9635
9636              Of course, this$<n> can be abitrary complex, ranging from
9637              this$0 (the immediate outer context) to 
9638              access$0(access$0(...(this$0))). 
9639              
9640              maybe_use_access_method returns a non zero value if the
9641              this_arg has to be moved into the (then generated) stub
9642              argument list. In the mean time, the selected function
9643              might have be replaced by a generated stub. */
9644           if (maybe_use_access_method (is_super_init, &list, &this_arg))
9645             args = tree_cons (NULL_TREE, this_arg, args);
9646         }
9647     }
9648
9649   /* Merge point of all resolution schemes. If we have nothing, this
9650      is an error, already signaled */
9651   if (!list) 
9652     PATCH_METHOD_RETURN_ERROR ();
9653
9654   /* Check accessibility, position the is_static flag, build and
9655      return the call */
9656   if (not_accessible_p (DECL_CONTEXT (current_function_decl), list, 0))
9657     {
9658       char *fct_name = xstrdup (lang_printable_name (list, 0));
9659       parse_error_context 
9660         (wfl, "Can't access %s method `%s %s.%s' from `%s'",
9661          java_accstring_lookup (get_access_flags_from_decl (list)),
9662          lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0), 
9663          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (list)))), 
9664          fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
9665       free (fct_name);
9666       PATCH_METHOD_RETURN_ERROR ();
9667     }
9668   check_deprecation (wfl, list);
9669
9670   /* If invoking a innerclass constructor, there are hidden parameters
9671      to pass */
9672   if (TREE_CODE (patch) == NEW_CLASS_EXPR 
9673       && PURE_INNER_CLASS_TYPE_P (DECL_CONTEXT (list)))
9674     {
9675       /* And make sure we add the accessed local variables to be saved
9676          in field aliases. */
9677       args = build_alias_initializer_parameter_list
9678         (AIPL_FUNCTION_CTOR_INVOCATION, DECL_CONTEXT (list), args, NULL);
9679
9680       /* We have to reverse things. Find out why. FIXME */
9681       if (ANONYMOUS_CLASS_P (DECL_CONTEXT (list)))
9682         args = nreverse (args);
9683       
9684       /* Secretely pass the current_this/primary as a second argument */
9685       if (primary || current_this)
9686         args = tree_cons (NULL_TREE, (primary ? primary : current_this), args);
9687       else
9688         args = tree_cons (NULL_TREE, integer_zero_node, args);
9689     }
9690
9691   /* This handles the situation where a constructor invocation needs
9692      to have an enclosing context passed as a second parameter (the
9693      constructor is one of an inner class. We extract it from the
9694      current function.  */
9695   if (is_super_init && PURE_INNER_CLASS_TYPE_P (DECL_CONTEXT (list)))
9696     {
9697       tree enclosing_decl = DECL_CONTEXT (TYPE_NAME (current_class));
9698       tree extra_arg;
9699
9700       if (ANONYMOUS_CLASS_P (current_class) || !DECL_CONTEXT (enclosing_decl))
9701         {
9702           extra_arg = DECL_FUNCTION_BODY (current_function_decl);
9703           extra_arg = TREE_CHAIN (BLOCK_EXPR_DECLS (extra_arg));
9704         }
9705       else
9706         {
9707           tree dest = TREE_TYPE (DECL_CONTEXT (enclosing_decl));
9708           extra_arg = 
9709             build_access_to_thisn (TREE_TYPE (enclosing_decl), dest, 0);
9710           extra_arg = java_complete_tree (extra_arg);
9711         }
9712       args = tree_cons (NULL_TREE, extra_arg, args);
9713     }
9714
9715   is_static_flag = METHOD_STATIC (list);
9716   if (! METHOD_STATIC (list) && this_arg != NULL_TREE)
9717     args = tree_cons (NULL_TREE, this_arg, args);
9718
9719   /* In the context of an explicit constructor invocation, we can't
9720      invoke any method relying on `this'. Exceptions are: we're
9721      invoking a static function, primary exists and is not the current
9722      this, we're creating a new object. */
9723   if (ctxp->explicit_constructor_p 
9724       && !is_static_flag 
9725       && (!primary || primary == current_this)
9726       && (TREE_CODE (patch) != NEW_CLASS_EXPR))
9727     {
9728       parse_error_context (wfl, "Can't reference `this' before the superclass constructor has been called");
9729       PATCH_METHOD_RETURN_ERROR ();
9730     }
9731   java_parser_context_restore_global ();
9732   if (is_static) 
9733     *is_static = is_static_flag;
9734   /* Sometimes, we want the decl of the selected method. Such as for
9735      EH checking */
9736   if (ret_decl)
9737     *ret_decl = list;
9738   patch = patch_invoke (patch, list, args);
9739   if (is_super_init && CLASS_HAS_FINIT_P (current_class))
9740     {
9741       tree finit_parms, finit_call;
9742       
9743       /* Prepare to pass hidden parameters to $finit$, if any. */
9744       finit_parms = build_alias_initializer_parameter_list 
9745         (AIPL_FUNCTION_FINIT_INVOCATION, current_class, NULL_TREE, NULL);
9746
9747       finit_call = 
9748         build_method_invocation (build_wfl_node (finit_identifier_node),
9749                                  finit_parms);
9750
9751       /* Generate the code used to initialize fields declared with an
9752          initialization statement and build a compound statement along
9753          with the super constructor invocation. */
9754       patch = build (COMPOUND_EXPR, void_type_node, patch,
9755                      java_complete_tree (finit_call));
9756       CAN_COMPLETE_NORMALLY (patch) = 1;
9757     }
9758   return patch;
9759 }
9760
9761 /* Check that we're not trying to do a static reference to a method in
9762    non static method. Return 1 if it's the case, 0 otherwise. */
9763
9764 static int
9765 check_for_static_method_reference (wfl, node, method, where, primary)
9766      tree wfl, node, method, where, primary;
9767 {
9768   if (METHOD_STATIC (current_function_decl) 
9769       && !METHOD_STATIC (method) && !primary && !CALL_CONSTRUCTOR_P (node))
9770     {
9771       char *fct_name = xstrdup (lang_printable_name (method, 0));
9772       parse_error_context 
9773         (wfl, "Can't make static reference to method `%s %s' in class `%s'", 
9774          lang_printable_name (TREE_TYPE (TREE_TYPE (method)), 0), fct_name,
9775          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (where))));
9776       free (fct_name);
9777       return 1;
9778     }
9779   return 0;
9780 }
9781
9782 /* Fix the invocation of *MDECL if necessary in the case of a
9783    invocation from an inner class. *THIS_ARG might be modified
9784    appropriately and an alternative access to *MDECL might be
9785    returned.  */
9786
9787 static int
9788 maybe_use_access_method (is_super_init, mdecl, this_arg)
9789      int is_super_init;
9790      tree *mdecl, *this_arg;
9791 {
9792   tree ctx;
9793   tree md = *mdecl, ta = *this_arg;
9794   int to_return = 0;
9795   int non_static_context = !METHOD_STATIC (md);
9796
9797   if (is_super_init 
9798       || DECL_CONTEXT (md) == current_class
9799       || !PURE_INNER_CLASS_TYPE_P (current_class) 
9800       || DECL_FINIT_P (md))
9801     return 0;
9802   
9803   /* If we're calling a method found in an enclosing class, generate
9804      what it takes to retrieve the right this. Don't do that if we're
9805      invoking a static method. */
9806
9807   if (non_static_context)
9808     {
9809       ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class)));
9810       if (ctx == DECL_CONTEXT (md))
9811         {
9812           ta = build_current_thisn (current_class);
9813           ta = build_wfl_node (ta);
9814         }
9815       else
9816         {
9817           tree type = ctx;
9818           while (type)
9819             {
9820               maybe_build_thisn_access_method (type);
9821               if (type == DECL_CONTEXT (md))
9822                 {
9823                   ta = build_access_to_thisn (ctx, type, 0);
9824                   break;
9825                 }
9826               type = (DECL_CONTEXT (TYPE_NAME (type)) ? 
9827                       TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))) : NULL_TREE);
9828             }
9829         }
9830       ta = java_complete_tree (ta);
9831     }
9832
9833   /* We might have to use an access method to get to MD. We can
9834      break the method access rule as far as we're not generating
9835      bytecode */
9836   if (METHOD_PRIVATE (md) && flag_emit_class_files)
9837     {
9838       md = build_outer_method_access_method (md);
9839       to_return = 1;
9840     }
9841
9842   *mdecl = md;
9843   *this_arg = ta;
9844
9845   /* Returnin a non zero value indicates we were doing a non static
9846      method invokation that is now a static invocation. It will have
9847      callee displace `this' to insert it in the regular argument
9848      list. */
9849   return (non_static_context && to_return);
9850 }
9851
9852 /* Patch an invoke expression METHOD and ARGS, based on its invocation
9853    mode.  */
9854
9855 static tree
9856 patch_invoke (patch, method, args)
9857      tree patch, method, args;
9858 {
9859   tree dtable, func;
9860   tree original_call, t, ta;
9861   tree cond = NULL_TREE;
9862
9863   /* Last step for args: convert build-in types. If we're dealing with
9864      a new TYPE() type call, the first argument to the constructor
9865      isn't found in the incoming argument list, but delivered by
9866      `new' */
9867   t = TYPE_ARG_TYPES (TREE_TYPE (method));
9868   if (TREE_CODE (patch) == NEW_CLASS_EXPR)
9869     t = TREE_CHAIN (t);
9870   for (ta = args; t != end_params_node && ta; 
9871        t = TREE_CHAIN (t), ta = TREE_CHAIN (ta))
9872     if (JPRIMITIVE_TYPE_P (TREE_TYPE (TREE_VALUE (ta))) &&
9873         TREE_TYPE (TREE_VALUE (ta)) != TREE_VALUE (t))
9874       TREE_VALUE (ta) = convert (TREE_VALUE (t), TREE_VALUE (ta));
9875
9876   /* Resolve unresolved returned type isses */
9877   t = TREE_TYPE (TREE_TYPE (method));
9878   if (TREE_CODE (t) == POINTER_TYPE && !CLASS_LOADED_P (TREE_TYPE (t)))
9879     resolve_and_layout (TREE_TYPE (t), NULL);
9880
9881   if (flag_emit_class_files || flag_emit_xref)
9882     func = method;
9883   else
9884     {
9885       tree signature = build_java_signature (TREE_TYPE (method));
9886       switch (invocation_mode (method, CALL_USING_SUPER (patch)))
9887         {
9888         case INVOKE_VIRTUAL:
9889           dtable = invoke_build_dtable (0, args);
9890           func = build_invokevirtual (dtable, method);
9891           break;
9892
9893         case INVOKE_NONVIRTUAL:
9894           /* If the object for the method call is null, we throw an
9895              exception.  We don't do this if the object is the current
9896              method's `this'.  In other cases we just rely on an
9897              optimization pass to eliminate redundant checks.  */
9898           if (TREE_VALUE (args) != current_this)
9899             {
9900               /* We use a SAVE_EXPR here to make sure we only evaluate
9901                  the new `self' expression once.  */
9902               tree save_arg = save_expr (TREE_VALUE (args));
9903               TREE_VALUE (args) = save_arg;
9904               cond = build (EQ_EXPR, boolean_type_node, save_arg,
9905                             null_pointer_node);
9906             }
9907           /* Fall through.  */
9908
9909         case INVOKE_SUPER:
9910         case INVOKE_STATIC:
9911           func = build_known_method_ref (method, TREE_TYPE (method),
9912                                          DECL_CONTEXT (method),
9913                                          signature, args);
9914           break;
9915
9916         case INVOKE_INTERFACE:
9917           dtable = invoke_build_dtable (1, args);
9918           func = build_invokeinterface (dtable, method);
9919           break;
9920
9921         default:
9922           fatal ("internal error - unknown invocation_mode result");
9923         }
9924
9925       /* Ensure self_type is initialized, (invokestatic). FIXME */
9926       func = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (method)), func);
9927     }
9928
9929   TREE_TYPE (patch) = TREE_TYPE (TREE_TYPE (method));
9930   TREE_OPERAND (patch, 0) = func;
9931   TREE_OPERAND (patch, 1) = args;
9932   original_call = patch;
9933
9934   /* We're processing a `new TYPE ()' form. New is called and its
9935      returned value is the first argument to the constructor. We build
9936      a COMPOUND_EXPR and use saved expression so that the overall NEW
9937      expression value is a pointer to a newly created and initialized
9938      class. */
9939   if (TREE_CODE (original_call) == NEW_CLASS_EXPR)
9940     {
9941       tree class = DECL_CONTEXT (method);
9942       tree c1, saved_new, size, new;
9943       if (flag_emit_class_files || flag_emit_xref)
9944         {
9945           TREE_TYPE (patch) = build_pointer_type (class);
9946           return patch;
9947         }
9948       if (!TYPE_SIZE (class))
9949         safe_layout_class (class);
9950       size = size_in_bytes (class);
9951       new = build (CALL_EXPR, promote_type (class),
9952                    build_address_of (alloc_object_node),
9953                    tree_cons (NULL_TREE, build_class_ref (class),
9954                               build_tree_list (NULL_TREE, 
9955                                                size_in_bytes (class))),
9956                    NULL_TREE);
9957       saved_new = save_expr (new);
9958       c1 = build_tree_list (NULL_TREE, saved_new);
9959       TREE_CHAIN (c1) = TREE_OPERAND (original_call, 1);
9960       TREE_OPERAND (original_call, 1) = c1;
9961       TREE_SET_CODE (original_call, CALL_EXPR);
9962       patch = build (COMPOUND_EXPR, TREE_TYPE (new), patch, saved_new);
9963     }
9964
9965   /* If COND is set, then we are building a check to see if the object
9966      is NULL.  */
9967   if (cond != NULL_TREE)
9968     {
9969       /* We have to make the `then' branch a compound expression to
9970          make the types turn out right.  This seems bizarre.  */
9971       patch = build (COND_EXPR, TREE_TYPE (patch), cond,
9972                      build (COMPOUND_EXPR, TREE_TYPE (patch),
9973                             build (CALL_EXPR, void_type_node,
9974                                    build_address_of (soft_nullpointer_node),
9975                                    NULL_TREE, NULL_TREE),
9976                             (FLOAT_TYPE_P (TREE_TYPE (patch))
9977                              ? build_real (TREE_TYPE (patch), dconst0)
9978                              : build1 (CONVERT_EXPR, TREE_TYPE (patch),
9979                                        integer_zero_node))),
9980                      patch);
9981       TREE_SIDE_EFFECTS (patch) = 1;
9982     }
9983
9984   return patch;
9985 }
9986
9987 static int
9988 invocation_mode (method, super)
9989      tree method;
9990      int super;
9991 {
9992   int access = get_access_flags_from_decl (method);
9993
9994   if (super)
9995     return INVOKE_SUPER;
9996
9997   if (access & ACC_STATIC)
9998     return INVOKE_STATIC;
9999
10000   /* We have to look for a constructor before we handle nonvirtual
10001      calls; otherwise the constructor will look nonvirtual.  */
10002   if (DECL_CONSTRUCTOR_P (method))
10003     return INVOKE_STATIC;
10004
10005   if (access & ACC_FINAL || access & ACC_PRIVATE)
10006     return INVOKE_NONVIRTUAL;
10007
10008   if (CLASS_FINAL (TYPE_NAME (DECL_CONTEXT (method))))
10009     return INVOKE_NONVIRTUAL;
10010
10011   if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))))
10012     return INVOKE_INTERFACE;
10013
10014   return INVOKE_VIRTUAL;
10015 }
10016
10017 /* Retrieve a refined list of matching methods. It covers the step
10018    15.11.2 (Compile-Time Step 2) */
10019
10020 static tree
10021 lookup_method_invoke (lc, cl, class, name, arg_list)
10022      int lc;
10023      tree cl;
10024      tree class, name, arg_list;
10025 {
10026   tree atl = end_params_node;           /* Arg Type List */
10027   tree method, signature, list, node;
10028   const char *candidates;               /* Used for error report */
10029   char *dup;
10030
10031   /* Fix the arguments */
10032   for (node = arg_list; node; node = TREE_CHAIN (node))
10033     {
10034       tree current_arg = TREE_TYPE (TREE_VALUE (node));
10035       /* Non primitive type may have to be resolved */
10036       if (!JPRIMITIVE_TYPE_P (current_arg))
10037         resolve_and_layout (current_arg, NULL_TREE);
10038       /* And promoted */
10039       if (TREE_CODE (current_arg) == RECORD_TYPE)
10040         current_arg = promote_type (current_arg);
10041       atl = tree_cons (NULL_TREE, current_arg, atl);
10042     }
10043
10044   /* Presto. If we're dealing with an anonymous class and a
10045      constructor call, generate the right constructor now, since we
10046      know the arguments' types. */
10047
10048   if (lc && ANONYMOUS_CLASS_P (class))
10049     craft_constructor (TYPE_NAME (class), atl);
10050
10051   /* Find all candidates and then refine the list, searching for the
10052      most specific method. */
10053   list = find_applicable_accessible_methods_list (lc, class, name, atl);
10054   list = find_most_specific_methods_list (list);
10055   if (list && !TREE_CHAIN (list))
10056     return TREE_VALUE (list);
10057
10058   /* Issue an error. List candidates if any. Candidates are listed
10059      only if accessible (non accessible methods may end-up here for
10060      the sake of a better error report). */
10061   candidates = NULL;
10062   if (list)
10063     {
10064       tree current;
10065       obstack_grow (&temporary_obstack, ". Candidates are:\n", 18);
10066       for (current = list; current; current = TREE_CHAIN (current))
10067         {
10068           tree cm = TREE_VALUE (current);
10069           char string [4096];
10070           if (!cm || not_accessible_p (class, cm, 0))
10071             continue;
10072           sprintf 
10073             (string, "  `%s' in `%s'%s",
10074              get_printable_method_name (cm),
10075              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (cm)))),
10076              (TREE_CHAIN (current) ? "\n" : ""));
10077           obstack_grow (&temporary_obstack, string, strlen (string));
10078         }
10079       obstack_1grow (&temporary_obstack, '\0');
10080       candidates = obstack_finish (&temporary_obstack);
10081     }
10082   /* Issue the error message */
10083   method = make_node (FUNCTION_TYPE);
10084   TYPE_ARG_TYPES (method) = atl;
10085   signature = build_java_argument_signature (method);
10086   dup = xstrdup (lang_printable_name (class, 0));
10087   parse_error_context (cl, "Can't find %s `%s(%s)' in type `%s'%s",
10088                        (lc ? "constructor" : "method"),
10089                        (lc ? dup : IDENTIFIER_POINTER (name)),
10090                        IDENTIFIER_POINTER (signature), dup,
10091                        (candidates ? candidates : ""));
10092   free (dup);
10093   return NULL_TREE;
10094 }
10095
10096 /* 15.11.2.1: Find Methods that are Applicable and Accessible. LC is 1
10097    when we're looking for a constructor. */
10098
10099 static tree
10100 find_applicable_accessible_methods_list (lc, class, name, arglist)
10101      int lc;
10102      tree class, name, arglist;
10103 {
10104   static struct hash_table t, *searched_classes = NULL;
10105   static int search_not_done = 0;
10106   tree list = NULL_TREE, all_list = NULL_TREE;
10107
10108   /* Check the hash table to determine if this class has been searched 
10109      already. */
10110   if (searched_classes)
10111     {
10112       if (hash_lookup (searched_classes, 
10113                       (const hash_table_key) class, FALSE, NULL))
10114        return NULL;
10115     }
10116   else
10117     {
10118       hash_table_init (&t, hash_newfunc, java_hash_hash_tree_node,
10119                       java_hash_compare_tree_node);
10120       searched_classes = &t;
10121     }
10122     
10123   search_not_done++;
10124   hash_lookup (searched_classes, 
10125               (const hash_table_key) class, TRUE, NULL);
10126
10127   if (!CLASS_LOADED_P (class) && !CLASS_FROM_SOURCE_P (class))
10128     {
10129       load_class (class, 1);
10130       safe_layout_class (class);
10131     }
10132
10133   /* Search interfaces */
10134   if (TREE_CODE (TYPE_NAME (class)) == TYPE_DECL 
10135       && CLASS_INTERFACE (TYPE_NAME (class)))
10136     {
10137       int i, n;
10138       tree basetype_vec = TYPE_BINFO_BASETYPES (class);
10139       search_applicable_methods_list (lc, TYPE_METHODS (class), 
10140                                       name, arglist, &list, &all_list);
10141       n = TREE_VEC_LENGTH (basetype_vec);
10142       for (i = 1; i < n; i++)
10143         {
10144           tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
10145           tree rlist;
10146
10147           rlist = find_applicable_accessible_methods_list (lc,  t, name, 
10148                                                            arglist);
10149           list = chainon (rlist, list);
10150         }
10151     }
10152   /* Search classes */
10153   else
10154     {
10155       tree sc = class;
10156       int seen_inner_class = 0;
10157       search_applicable_methods_list (lc, TYPE_METHODS (class), 
10158                                       name, arglist, &list, &all_list);
10159
10160       /* We must search all interfaces of this class */
10161       if (!lc)
10162       {
10163         tree basetype_vec = TYPE_BINFO_BASETYPES (sc);
10164         int n = TREE_VEC_LENGTH (basetype_vec), i;
10165         for (i = 1; i < n; i++)
10166           {
10167             tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
10168             if (t != object_type_node)
10169               {
10170                 tree rlist
10171                   = find_applicable_accessible_methods_list (lc, t,
10172                                                              name, arglist);
10173                 list = chainon (rlist, list);
10174               }
10175           }
10176       }
10177
10178       /* Search enclosing context of inner classes before looking
10179          ancestors up. */
10180       while (!lc && INNER_CLASS_TYPE_P (class))
10181         {
10182           tree rlist;
10183           seen_inner_class = 1;
10184           class = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class)));
10185           rlist = find_applicable_accessible_methods_list (lc, class, 
10186                                                            name, arglist);
10187           list = chainon (rlist, list);
10188         }
10189
10190       if (!lc && seen_inner_class 
10191           && TREE_TYPE (DECL_CONTEXT (TYPE_NAME (sc))) == CLASSTYPE_SUPER (sc))
10192         class = CLASSTYPE_SUPER (sc);
10193       else
10194         class = sc;
10195
10196       /* Search superclass */
10197       if (!lc && CLASSTYPE_SUPER (class) != NULL_TREE)
10198         {
10199           tree rlist;
10200           class = CLASSTYPE_SUPER (class);
10201           rlist = find_applicable_accessible_methods_list (lc, class, 
10202                                                            name, arglist);
10203           list = chainon (rlist, list);
10204         }
10205     }
10206
10207   search_not_done--;
10208
10209   /* We're done. Reset the searched classes list and finally search
10210      java.lang.Object if it wasn't searched already. */
10211   if (!search_not_done)
10212     {
10213       if (!lc
10214           && TYPE_METHODS (object_type_node)
10215           && !hash_lookup (searched_classes, 
10216                            (const hash_table_key) object_type_node, 
10217                            FALSE, NULL))
10218         {
10219           search_applicable_methods_list (lc, 
10220                                           TYPE_METHODS (object_type_node),
10221                                           name, arglist, &list, &all_list);
10222         }
10223       hash_table_free (searched_classes);
10224       searched_classes = NULL;
10225     }
10226
10227   /* Either return the list obtained or all selected (but
10228      inaccessible) methods for better error report. */
10229   return (!list ? all_list : list);
10230 }
10231
10232 /* Effectively search for the appropriate method in method */
10233
10234 static void 
10235 search_applicable_methods_list (lc, method, name, arglist, list, all_list)
10236      int lc;
10237      tree method, name, arglist;
10238      tree *list, *all_list;
10239 {
10240   for (; method; method = TREE_CHAIN (method))
10241     {
10242       /* When dealing with constructor, stop here, otherwise search
10243          other classes */
10244       if (lc && !DECL_CONSTRUCTOR_P (method))
10245         continue;
10246       else if (!lc && (DECL_CONSTRUCTOR_P (method) 
10247                        || (GET_METHOD_NAME (method) != name)))
10248         continue;
10249           
10250       if (argument_types_convertible (method, arglist))
10251         {
10252           /* Retain accessible methods only */
10253           if (!not_accessible_p (DECL_CONTEXT (current_function_decl), 
10254                                  method, 0))
10255             *list = tree_cons (NULL_TREE, method, *list);
10256           else
10257             /* Also retain all selected method here */
10258             *all_list = tree_cons (NULL_TREE, method, *list);
10259         }
10260     }
10261 }
10262
10263 /* 15.11.2.2 Choose the Most Specific Method */
10264
10265 static tree
10266 find_most_specific_methods_list (list)
10267      tree list;
10268 {
10269   int max = 0;
10270   int abstract, candidates;
10271   tree current, new_list = NULL_TREE;
10272   for (current = list; current; current = TREE_CHAIN (current))
10273     {
10274       tree method;
10275       DECL_SPECIFIC_COUNT (TREE_VALUE (current)) = 0;
10276
10277       for (method = list; method; method = TREE_CHAIN (method))
10278         {
10279           /* Don't test a method against itself */
10280           if (method == current)
10281             continue;
10282
10283           /* Compare arguments and location where method where declared */
10284           if (argument_types_convertible (TREE_VALUE (method), 
10285                                           TREE_VALUE (current))
10286               && valid_method_invocation_conversion_p 
10287                    (DECL_CONTEXT (TREE_VALUE (method)), 
10288                     DECL_CONTEXT (TREE_VALUE (current))))
10289             {
10290               int v = ++DECL_SPECIFIC_COUNT (TREE_VALUE (current));
10291               max = (v > max ? v : max);
10292             }
10293         }
10294     }
10295
10296   /* Review the list and select the maximally specific methods */
10297   for (current = list, abstract = -1, candidates = -1;
10298        current; current = TREE_CHAIN (current))
10299     if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
10300       {
10301         new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
10302         abstract += (METHOD_ABSTRACT (TREE_VALUE (current)) ? 1 : 0);
10303         candidates++;
10304       }
10305
10306   /* If we have several and they're all abstract, just pick the
10307      closest one. */
10308   if (candidates > 0 && (candidates == abstract))
10309     {
10310       new_list = nreverse (new_list);
10311       TREE_CHAIN (new_list) = NULL_TREE;
10312     }
10313
10314   /* We have several, we couldn't find a most specific, all but one are
10315      abstract, we pick the only non abstract one. */
10316   if (candidates > 0 && !max && (candidates == abstract+1))
10317     {
10318       for (current = new_list; current; current = TREE_CHAIN (current))
10319         if (!METHOD_ABSTRACT (TREE_VALUE (current)))
10320           {
10321             TREE_CHAIN (current) = NULL_TREE;
10322             new_list = current;
10323           }
10324     }
10325
10326   /* If we can't find one, lower expectations and try to gather multiple
10327      maximally specific methods */
10328   while (!new_list && max)
10329     {
10330       while (--max > 0)
10331         {
10332           if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
10333             new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
10334         }
10335     }
10336
10337   return new_list;
10338 }
10339
10340 /* Make sure that the type of each M2_OR_ARGLIST arguments can be
10341    converted by method invocation conversion (5.3) to the type of the
10342    corresponding parameter of M1. Implementation expects M2_OR_ARGLIST
10343    to change less often than M1. */
10344
10345 static int
10346 argument_types_convertible (m1, m2_or_arglist)
10347     tree m1, m2_or_arglist;
10348 {
10349   static tree m2_arg_value = NULL_TREE;
10350   static tree m2_arg_cache = NULL_TREE;
10351
10352   register tree m1_arg, m2_arg;
10353
10354   SKIP_THIS_AND_ARTIFICIAL_PARMS (m1_arg, m1)
10355
10356   if (m2_arg_value == m2_or_arglist)
10357     m2_arg = m2_arg_cache;
10358   else
10359     {
10360       /* M2_OR_ARGLIST can be a function DECL or a raw list of
10361          argument types */
10362       if (m2_or_arglist && TREE_CODE (m2_or_arglist) == FUNCTION_DECL)
10363         {
10364           m2_arg = TYPE_ARG_TYPES (TREE_TYPE (m2_or_arglist));
10365           if (!METHOD_STATIC (m2_or_arglist))
10366             m2_arg = TREE_CHAIN (m2_arg);
10367         }
10368       else
10369         m2_arg = m2_or_arglist;
10370
10371       m2_arg_value = m2_or_arglist;
10372       m2_arg_cache = m2_arg;
10373     }
10374
10375   while (m1_arg != end_params_node && m2_arg != end_params_node)
10376     {
10377       resolve_and_layout (TREE_VALUE (m1_arg), NULL_TREE);
10378       if (!valid_method_invocation_conversion_p (TREE_VALUE (m1_arg),
10379                                                  TREE_VALUE (m2_arg)))
10380         break;
10381       m1_arg = TREE_CHAIN (m1_arg);
10382       m2_arg = TREE_CHAIN (m2_arg);
10383     }
10384   return m1_arg == end_params_node && m2_arg == end_params_node;
10385 }
10386
10387 /* Qualification routines */
10388
10389 static void
10390 qualify_ambiguous_name (id)
10391      tree id;
10392 {
10393   tree qual, qual_wfl, name = NULL_TREE, decl, ptr_type = NULL_TREE,
10394     saved_current_class;
10395   int again, super_found = 0, this_found = 0, new_array_found = 0;
10396   int code;
10397
10398   /* We first qualify the first element, then derive qualification of
10399      others based on the first one. If the first element is qualified
10400      by a resolution (field or type), this resolution is stored in the
10401      QUAL_RESOLUTION of the qual element being examined. We need to
10402      save the current_class since the use of SUPER might change the
10403      its value. */
10404   saved_current_class = current_class;
10405   qual = EXPR_WFL_QUALIFICATION (id);
10406   do {
10407
10408     /* Simple qualified expression feature a qual_wfl that is a
10409        WFL. Expression derived from a primary feature more complicated
10410        things like a CALL_EXPR. Expression from primary need to be
10411        worked out to extract the part on which the qualification will
10412        take place. */
10413     qual_wfl = QUAL_WFL (qual);
10414     switch (TREE_CODE (qual_wfl))
10415       {
10416       case CALL_EXPR:
10417         qual_wfl = TREE_OPERAND (qual_wfl, 0);
10418         if (TREE_CODE (qual_wfl) != EXPR_WITH_FILE_LOCATION)
10419           {
10420             qual = EXPR_WFL_QUALIFICATION (qual_wfl);
10421             qual_wfl = QUAL_WFL (qual);
10422           }
10423         break;
10424       case NEW_ARRAY_EXPR:
10425       case NEW_ANONYMOUS_ARRAY_EXPR:
10426         qual = TREE_CHAIN (qual);
10427         again = new_array_found = 1;
10428         continue;
10429       case CONVERT_EXPR:
10430         break;
10431       case NEW_CLASS_EXPR:
10432         qual_wfl = TREE_OPERAND (qual_wfl, 0);
10433         break;
10434       case ARRAY_REF:
10435         while (TREE_CODE (qual_wfl) == ARRAY_REF)
10436           qual_wfl = TREE_OPERAND (qual_wfl, 0);
10437         break;
10438       case STRING_CST:
10439         qual = TREE_CHAIN (qual);
10440         qual_wfl = QUAL_WFL (qual);
10441         break;
10442       case CLASS_LITERAL:
10443         qual = TREE_CHAIN (qual);
10444         qual_wfl = QUAL_WFL (qual);
10445       break;
10446       default:
10447         /* Fix for -Wall. Just break doing nothing */
10448         break;
10449       }
10450
10451     ptr_type = current_class;
10452     again = 0;
10453     code = TREE_CODE (qual_wfl);
10454
10455     /* Pos evaluation: non WFL leading expression nodes */
10456     if (code == CONVERT_EXPR
10457         && TREE_CODE (TREE_TYPE (qual_wfl)) == EXPR_WITH_FILE_LOCATION)
10458       name = EXPR_WFL_NODE (TREE_TYPE (qual_wfl));
10459
10460     else if (code == INTEGER_CST)
10461       name = qual_wfl;
10462     
10463     else if ((code == ARRAY_REF || code == CALL_EXPR || code == MODIFY_EXPR) &&
10464              TREE_CODE (TREE_OPERAND (qual_wfl, 0)) == EXPR_WITH_FILE_LOCATION)
10465       name = EXPR_WFL_NODE (TREE_OPERAND (qual_wfl, 0));
10466
10467     else if (code == TREE_LIST)
10468       name = EXPR_WFL_NODE (TREE_PURPOSE (qual_wfl));
10469
10470     else if (code == STRING_CST || code == CONDITIONAL_EXPR 
10471              || code == PLUS_EXPR)
10472       {
10473         qual = TREE_CHAIN (qual);
10474         qual_wfl = QUAL_WFL (qual);
10475         again = 1;
10476       }
10477     else 
10478       {
10479         name = EXPR_WFL_NODE (qual_wfl);
10480         if (!name)
10481           {
10482             qual = EXPR_WFL_QUALIFICATION (qual_wfl);
10483             again = 1;
10484           }
10485       }
10486
10487     /* If we have a THIS (from a primary), we set the context accordingly */
10488     if (name == this_identifier_node)
10489       {
10490         qual = TREE_CHAIN (qual);
10491         qual_wfl = QUAL_WFL (qual);
10492         if (TREE_CODE (qual_wfl) == CALL_EXPR)
10493           again = 1;
10494         else
10495           name = EXPR_WFL_NODE (qual_wfl);
10496         this_found = 1;
10497       }
10498     /* If we have a SUPER, we set the context accordingly */
10499     if (name == super_identifier_node)
10500       {
10501         current_class = CLASSTYPE_SUPER (ptr_type);
10502         /* Check that there is such a thing as a super class. If not,
10503            return.  The error will be caught later on, during the
10504            resolution */
10505         if (!current_class)
10506           {
10507             current_class = saved_current_class;
10508             return;
10509           }
10510         qual = TREE_CHAIN (qual);
10511         /* Do one more interation to set things up */
10512         super_found = again = 1;
10513       }
10514   } while (again);
10515   
10516   /* If name appears within the scope of a local variable declaration
10517      or parameter declaration, then it is an expression name. We don't
10518      carry this test out if we're in the context of the use of SUPER
10519      or THIS */
10520   if (!this_found && !super_found 
10521       && TREE_CODE (name) != STRING_CST && TREE_CODE (name) != INTEGER_CST
10522       && (decl = IDENTIFIER_LOCAL_VALUE (name)))
10523     {
10524       RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
10525       QUAL_RESOLUTION (qual) = decl;
10526     }
10527
10528   /* If within the class/interface NAME was found to be used there
10529      exists a (possibly inherited) field named NAME, then this is an
10530      expression name. If we saw a NEW_ARRAY_EXPR before and want to
10531      address length, it is OK. */
10532   else if ((decl = lookup_field_wrapper (ptr_type, name))
10533            || (new_array_found && name == length_identifier_node))
10534     {
10535       RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
10536       QUAL_RESOLUTION (qual) = (new_array_found ? NULL_TREE : decl);
10537     }
10538
10539   /* We reclassify NAME as yielding to a type name resolution if:
10540      - NAME is a class/interface declared within the compilation
10541        unit containing NAME,
10542      - NAME is imported via a single-type-import declaration,
10543      - NAME is declared in an another compilation unit of the package
10544        of the compilation unit containing NAME,
10545      - NAME is declared by exactly on type-import-on-demand declaration
10546      of the compilation unit containing NAME. 
10547      - NAME is actually a STRING_CST. */
10548   else if (TREE_CODE (name) == STRING_CST || TREE_CODE (name) == INTEGER_CST
10549            || (decl = resolve_and_layout (name, NULL_TREE)))
10550     {
10551       RESOLVE_TYPE_NAME_P (qual_wfl) = 1;
10552       QUAL_RESOLUTION (qual) = decl;
10553     }
10554
10555   /* Method call, array references and cast are expression name */
10556   else if (TREE_CODE (QUAL_WFL (qual)) == CALL_EXPR
10557            || TREE_CODE (QUAL_WFL (qual)) == ARRAY_REF
10558            || TREE_CODE (QUAL_WFL (qual)) == CONVERT_EXPR)
10559     RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
10560
10561   /* Check here that NAME isn't declared by more than one
10562      type-import-on-demand declaration of the compilation unit
10563      containing NAME. FIXME */
10564
10565   /* Otherwise, NAME is reclassified as a package name */
10566   else 
10567     RESOLVE_PACKAGE_NAME_P (qual_wfl) = 1;
10568
10569   /* Propagate the qualification accross other components of the
10570      qualified name */
10571   for (qual = TREE_CHAIN (qual); qual;
10572        qual_wfl = QUAL_WFL (qual), qual = TREE_CHAIN (qual))
10573     {
10574       if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
10575         RESOLVE_PACKAGE_NAME_P (QUAL_WFL (qual)) = 1;
10576       else 
10577         RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (qual)) = 1;
10578     }
10579
10580   /* Store the global qualification for the ambiguous part of ID back
10581      into ID fields */
10582   if (RESOLVE_EXPRESSION_NAME_P (qual_wfl))
10583     RESOLVE_EXPRESSION_NAME_P (id) = 1;
10584   else if (RESOLVE_TYPE_NAME_P (qual_wfl))
10585     RESOLVE_TYPE_NAME_P (id) = 1;
10586   else if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
10587     RESOLVE_PACKAGE_NAME_P (id) = 1;
10588
10589   /* Restore the current class */
10590   current_class = saved_current_class;
10591 }
10592
10593 static int
10594 breakdown_qualified (left, right, source)
10595     tree *left, *right, source;
10596 {
10597   char *p = IDENTIFIER_POINTER (source), *base;
10598   int   l = IDENTIFIER_LENGTH (source);
10599
10600   /* Breakdown NAME into REMAINDER . IDENTIFIER */
10601   base = p;
10602   p += (l-1);
10603   while (*p != '.' && p != base)
10604     p--;
10605
10606   /* We didn't find a '.'. Return an error */
10607   if (p == base)
10608     return 1;
10609
10610   *p = '\0';
10611   if (right)
10612     *right = get_identifier (p+1);
10613   *left = get_identifier (IDENTIFIER_POINTER (source));
10614   *p = '.';
10615   
10616   return 0;
10617 }
10618
10619 /* Patch tree nodes in a function body. When a BLOCK is found, push
10620    local variable decls if present.
10621    Same as java_complete_lhs, but does resolve static finals to values. */
10622
10623 static tree
10624 java_complete_tree (node)
10625      tree node;
10626 {
10627   node = java_complete_lhs (node);
10628   if (TREE_CODE (node) == VAR_DECL && FIELD_STATIC (node)
10629       && FIELD_FINAL (node) && DECL_INITIAL (node) != NULL_TREE
10630       && !flag_emit_xref)
10631     {
10632       tree value = DECL_INITIAL (node);
10633       DECL_INITIAL (node) = NULL_TREE;
10634       push_obstacks (&permanent_obstack, &permanent_obstack);
10635       value = fold_constant_for_init (value, node);
10636       pop_obstacks ();
10637       DECL_INITIAL (node) = value;
10638       if (value != NULL_TREE)
10639         {
10640           /* fold_constant_for_init sometimes widen the original type
10641              of the constant (i.e. byte to int.) It's not desirable,
10642              especially if NODE is a function argument. */
10643           if (TREE_CODE (value) == INTEGER_CST
10644               && TREE_TYPE (node) != TREE_TYPE (value))
10645             return convert (TREE_TYPE (node), value);
10646           else
10647             return value;
10648         }
10649     }
10650   return node;
10651 }
10652
10653 static tree
10654 java_stabilize_reference (node)
10655      tree node;
10656 {
10657   if (TREE_CODE (node) == COMPOUND_EXPR)
10658     {
10659       tree op0 = TREE_OPERAND (node, 0);
10660       tree op1 = TREE_OPERAND (node, 1);
10661       TREE_OPERAND (node, 0) = save_expr (op0);
10662       TREE_OPERAND (node, 1) = java_stabilize_reference (op1);
10663       return node;
10664     }
10665   return stabilize_reference (node);
10666 }
10667
10668 /* Patch tree nodes in a function body. When a BLOCK is found, push
10669    local variable decls if present.
10670    Same as java_complete_tree, but does not resolve static finals to values. */
10671
10672 static tree
10673 java_complete_lhs (node)
10674      tree node;
10675 {
10676   tree nn, cn, wfl_op1, wfl_op2, wfl_op3;
10677   int flag;
10678
10679   /* CONVERT_EXPR always has its type set, even though it needs to be
10680      worked out. */
10681   if (TREE_TYPE (node) && TREE_CODE (node) != CONVERT_EXPR)
10682     return node;
10683
10684   /* The switch block implements cases processing container nodes
10685      first.  Contained nodes are always written back. Leaves come
10686      next and return a value. */
10687   switch (TREE_CODE (node))
10688     {
10689     case BLOCK:
10690
10691       /* 1- Block section.
10692          Set the local values on decl names so we can identify them
10693          faster when they're referenced. At that stage, identifiers
10694          are legal so we don't check for declaration errors. */
10695       for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
10696         {
10697           DECL_CONTEXT (cn) = current_function_decl;
10698           IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = cn;
10699         }
10700       if (BLOCK_EXPR_BODY (node) == NULL_TREE)
10701           CAN_COMPLETE_NORMALLY (node) = 1;
10702       else
10703         {
10704           tree stmt = BLOCK_EXPR_BODY (node);
10705           tree *ptr;
10706           int error_seen = 0;
10707           if (TREE_CODE (stmt) == COMPOUND_EXPR)
10708             {
10709               /* Re-order from (((A; B); C); ...; Z) to 
10710                  (A; (B; (C ; (...; Z)))).
10711                  This makes it easier to scan the statements left-to-right
10712                  without using recursion (which might overflow the stack
10713                  if the block has many statements. */
10714               for (;;)
10715                 {
10716                   tree left = TREE_OPERAND (stmt, 0);
10717                   if (TREE_CODE (left) != COMPOUND_EXPR)
10718                     break;
10719                   TREE_OPERAND (stmt, 0) = TREE_OPERAND (left, 1);
10720                   TREE_OPERAND (left, 1) = stmt;
10721                   stmt = left;
10722                 }
10723               BLOCK_EXPR_BODY (node) = stmt;
10724             }
10725
10726           /* Now do the actual complete, without deep recursion for
10727              long blocks. */
10728           ptr = &BLOCK_EXPR_BODY (node);
10729           while (TREE_CODE (*ptr) == COMPOUND_EXPR
10730                  && TREE_OPERAND (*ptr, 1) != empty_stmt_node)
10731             {
10732               tree cur = java_complete_tree (TREE_OPERAND (*ptr, 0));
10733               tree *next = &TREE_OPERAND (*ptr, 1);
10734               TREE_OPERAND (*ptr, 0) = cur;
10735               if (cur == empty_stmt_node)
10736                 {
10737                   /* Optimization;  makes it easier to detect empty bodies.
10738                      Most useful for <clinit> with all-constant initializer. */
10739                   *ptr = *next;
10740                   continue;
10741                 }
10742               if (TREE_CODE (cur) == ERROR_MARK)
10743                 error_seen++;
10744               else if (! CAN_COMPLETE_NORMALLY (cur))
10745                 {
10746                   wfl_op2 = *next;
10747                   for (;;)
10748                     {
10749                       if (TREE_CODE (wfl_op2) == BLOCK)
10750                         wfl_op2 = BLOCK_EXPR_BODY (wfl_op2);
10751                       else if (TREE_CODE (wfl_op2) == COMPOUND_EXPR)
10752                         wfl_op2 = TREE_OPERAND (wfl_op2, 0);
10753                       else
10754                         break;
10755                     }
10756                   if (TREE_CODE (wfl_op2) != CASE_EXPR
10757                       && TREE_CODE (wfl_op2) != DEFAULT_EXPR)
10758                     unreachable_stmt_error (*ptr);
10759                 }
10760               ptr = next;
10761             }
10762           *ptr = java_complete_tree (*ptr);
10763
10764           if (TREE_CODE (*ptr) == ERROR_MARK || error_seen > 0)
10765             return error_mark_node;
10766           CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (*ptr);
10767         }
10768       /* Turn local bindings to null */
10769       for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
10770         IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = NULL_TREE;
10771
10772       TREE_TYPE (node) = void_type_node;
10773       break;
10774
10775       /* 2- They are expressions but ultimately deal with statements */
10776
10777     case THROW_EXPR:
10778       wfl_op1 = TREE_OPERAND (node, 0);
10779       COMPLETE_CHECK_OP_0 (node);
10780       /* 14.19 A throw statement cannot complete normally. */
10781       CAN_COMPLETE_NORMALLY (node) = 0;
10782       return patch_throw_statement (node, wfl_op1);
10783
10784     case SYNCHRONIZED_EXPR:
10785       wfl_op1 = TREE_OPERAND (node, 0);
10786       return patch_synchronized_statement (node, wfl_op1);
10787
10788     case TRY_EXPR:
10789       return patch_try_statement (node);
10790
10791     case TRY_FINALLY_EXPR:
10792       COMPLETE_CHECK_OP_0 (node);
10793       COMPLETE_CHECK_OP_1 (node);
10794       CAN_COMPLETE_NORMALLY (node)
10795         = (CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0))
10796            && CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)));
10797       TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 0));
10798       return node;
10799
10800     case CLEANUP_POINT_EXPR:
10801       COMPLETE_CHECK_OP_0 (node);
10802       TREE_TYPE (node) = void_type_node;
10803       CAN_COMPLETE_NORMALLY (node) = 
10804         CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
10805       return node;
10806
10807     case WITH_CLEANUP_EXPR:
10808       COMPLETE_CHECK_OP_0 (node);
10809       COMPLETE_CHECK_OP_2 (node);
10810       CAN_COMPLETE_NORMALLY (node) = 
10811         CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
10812       TREE_TYPE (node) = void_type_node;
10813       return node;
10814
10815     case LABELED_BLOCK_EXPR:
10816       PUSH_LABELED_BLOCK (node);
10817       if (LABELED_BLOCK_BODY (node))
10818         COMPLETE_CHECK_OP_1 (node);
10819       TREE_TYPE (node) = void_type_node;
10820       POP_LABELED_BLOCK ();
10821
10822       if (LABELED_BLOCK_BODY (node) == empty_stmt_node)
10823         {
10824           LABELED_BLOCK_BODY (node) = NULL_TREE;
10825           CAN_COMPLETE_NORMALLY (node) = 1;
10826         }
10827       else if (CAN_COMPLETE_NORMALLY (LABELED_BLOCK_BODY (node)))
10828         CAN_COMPLETE_NORMALLY (node) = 1;
10829       return node;
10830
10831     case EXIT_BLOCK_EXPR:
10832       /* We don't complete operand 1, because it's the return value of
10833          the EXIT_BLOCK_EXPR which doesn't exist it Java */
10834       return patch_bc_statement (node);
10835
10836     case CASE_EXPR:
10837       cn = java_complete_tree (TREE_OPERAND (node, 0));
10838       if (cn == error_mark_node)
10839         return cn;
10840
10841       /* First, the case expression must be constant. Values of final
10842          fields are accepted. */
10843       cn = fold (cn);
10844       if ((TREE_CODE (cn) == COMPOUND_EXPR || TREE_CODE (cn) == COMPONENT_REF)
10845           && JDECL_P (TREE_OPERAND (cn, 1))
10846           && FIELD_FINAL (TREE_OPERAND (cn, 1))
10847           && DECL_INITIAL (TREE_OPERAND (cn, 1)))
10848         {
10849           push_obstacks (&permanent_obstack, &permanent_obstack);
10850           cn = fold_constant_for_init (DECL_INITIAL (TREE_OPERAND (cn, 1)),
10851                                        TREE_OPERAND (cn, 1));
10852           pop_obstacks ();
10853         }
10854
10855       if (!TREE_CONSTANT (cn) && !flag_emit_xref)
10856         {
10857           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10858           parse_error_context (node, "Constant expression required");
10859           return error_mark_node;
10860         }
10861
10862       nn = ctxp->current_loop;
10863
10864       /* It must be assignable to the type of the switch expression. */
10865       if (!try_builtin_assignconv (NULL_TREE, 
10866                                    TREE_TYPE (TREE_OPERAND (nn, 0)), cn))
10867         {
10868           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10869           parse_error_context 
10870             (wfl_operator,
10871              "Incompatible type for case. Can't convert `%s' to `int'",
10872              lang_printable_name (TREE_TYPE (cn), 0));
10873           return error_mark_node;
10874         }
10875
10876       cn = fold (convert (int_type_node, cn));
10877
10878       /* Multiple instance of a case label bearing the same
10879          value is checked during code generation. The case
10880          expression is allright so far. */
10881       TREE_OPERAND (node, 0) = cn;
10882       TREE_TYPE (node) = void_type_node;
10883       CAN_COMPLETE_NORMALLY (node) = 1;
10884       TREE_SIDE_EFFECTS (node) = 1;
10885       break;
10886
10887     case DEFAULT_EXPR:
10888       nn = ctxp->current_loop;
10889       /* Only one default label is allowed per switch statement */
10890       if (SWITCH_HAS_DEFAULT (nn))
10891         {
10892           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10893           parse_error_context (wfl_operator, 
10894                                "Duplicate case label: `default'");
10895           return error_mark_node;
10896         }
10897       else
10898         SWITCH_HAS_DEFAULT (nn) = 1;
10899       TREE_TYPE (node) = void_type_node;
10900       TREE_SIDE_EFFECTS (node) = 1;
10901       CAN_COMPLETE_NORMALLY (node) = 1;
10902       break;
10903
10904     case SWITCH_EXPR:
10905     case LOOP_EXPR:
10906       PUSH_LOOP (node);
10907       /* Check whether the loop was enclosed in a labeled
10908          statement. If not, create one, insert the loop in it and
10909          return the node */
10910       nn = patch_loop_statement (node);
10911
10912       /* Anyways, walk the body of the loop */
10913       if (TREE_CODE (node) == LOOP_EXPR)
10914         TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
10915       /* Switch statement: walk the switch expression and the cases */
10916       else
10917         node = patch_switch_statement (node);
10918
10919       if (TREE_OPERAND (node, 0) == error_mark_node)
10920         nn = error_mark_node;
10921       else
10922         {
10923           TREE_TYPE (nn) = TREE_TYPE (node) = void_type_node;
10924           /* If we returned something different, that's because we
10925              inserted a label. Pop the label too. */
10926           if (nn != node)
10927             {
10928               if (CAN_COMPLETE_NORMALLY (node))
10929                 CAN_COMPLETE_NORMALLY (nn) = 1;
10930               POP_LABELED_BLOCK ();
10931             }
10932         }
10933       POP_LOOP ();
10934       return nn;
10935
10936     case EXIT_EXPR:
10937       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
10938       return patch_exit_expr (node);
10939
10940     case COND_EXPR:
10941       /* Condition */
10942       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
10943       if (TREE_OPERAND (node, 0) == error_mark_node)
10944         return error_mark_node;
10945       /* then-else branches */
10946       TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
10947       if (TREE_OPERAND (node, 1) == error_mark_node)
10948         return error_mark_node;
10949       TREE_OPERAND (node, 2) = java_complete_tree (TREE_OPERAND (node, 2));
10950       if (TREE_OPERAND (node, 2) == error_mark_node)
10951         return error_mark_node;
10952       return patch_if_else_statement (node);
10953       break;
10954
10955     case CONDITIONAL_EXPR:
10956       /* Condition */
10957       wfl_op1 = TREE_OPERAND (node, 0);
10958       COMPLETE_CHECK_OP_0 (node);
10959       wfl_op2 = TREE_OPERAND (node, 1);
10960       COMPLETE_CHECK_OP_1 (node);
10961       wfl_op3 = TREE_OPERAND (node, 2);
10962       COMPLETE_CHECK_OP_2 (node);
10963       return patch_conditional_expr (node, wfl_op1, wfl_op2);
10964
10965       /* 3- Expression section */
10966     case COMPOUND_EXPR:
10967       wfl_op2 = TREE_OPERAND (node, 1);
10968       TREE_OPERAND (node, 0) = nn = 
10969         java_complete_tree (TREE_OPERAND (node, 0));
10970       if (wfl_op2 == empty_stmt_node)
10971         CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (nn);
10972       else
10973         {
10974           if (! CAN_COMPLETE_NORMALLY (nn) && TREE_CODE (nn) != ERROR_MARK)
10975             {
10976               /* An unreachable condition in a do-while statement
10977                  is *not* (technically) an unreachable statement. */
10978               nn = wfl_op2;
10979               if (TREE_CODE (nn) == EXPR_WITH_FILE_LOCATION)
10980                 nn = EXPR_WFL_NODE (nn);
10981               if (TREE_CODE (nn) != EXIT_EXPR)
10982                 {
10983                   SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
10984                   parse_error_context (wfl_operator, "Unreachable statement");
10985                 }
10986             }
10987           TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
10988           if (TREE_OPERAND (node, 1) == error_mark_node)
10989             return error_mark_node;
10990           CAN_COMPLETE_NORMALLY (node)
10991             = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1));
10992         }
10993       TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 1));
10994       break;
10995
10996     case RETURN_EXPR:
10997       /* CAN_COMPLETE_NORMALLY (node) = 0; */
10998       return patch_return (node);
10999
11000     case EXPR_WITH_FILE_LOCATION:
11001       if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
11002           || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
11003         {
11004           tree wfl = node;
11005           node = resolve_expression_name (node, NULL);
11006           if (node == error_mark_node)
11007             return node;
11008           /* Keep line number information somewhere were it doesn't
11009              disrupt the completion process. */
11010           if (flag_emit_xref && TREE_CODE (node) != CALL_EXPR)
11011             {
11012               EXPR_WFL_NODE (wfl) = TREE_OPERAND (node, 1);
11013               TREE_OPERAND (node, 1) = wfl;
11014             }
11015           CAN_COMPLETE_NORMALLY (node) = 1;
11016         }
11017       else
11018         {
11019           tree body;
11020           int save_lineno = lineno;
11021           lineno = EXPR_WFL_LINENO (node);
11022           body = java_complete_tree (EXPR_WFL_NODE (node));
11023           lineno = save_lineno;
11024           EXPR_WFL_NODE (node) = body;
11025           TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (body);
11026           CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (body);
11027           if (body == empty_stmt_node)
11028             {
11029               /* Optimization;  makes it easier to detect empty bodies. */
11030               return body;
11031             }
11032           if (body == error_mark_node)
11033             {
11034               /* Its important for the evaluation of assignment that
11035                  this mark on the TREE_TYPE is propagated. */
11036               TREE_TYPE (node) = error_mark_node;
11037               return error_mark_node;
11038             }
11039           else
11040             TREE_TYPE (node) = TREE_TYPE (EXPR_WFL_NODE (node));
11041           
11042         }
11043       break;
11044
11045     case NEW_ARRAY_EXPR:
11046       /* Patch all the dimensions */
11047       flag = 0;
11048       for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
11049         {
11050           int location = EXPR_WFL_LINECOL (TREE_VALUE (cn));
11051           tree dim = convert (int_type_node, 
11052                               java_complete_tree (TREE_VALUE (cn)));
11053           if (dim == error_mark_node)
11054             {
11055               flag = 1;
11056               continue;
11057             }
11058           else
11059             {
11060               TREE_VALUE (cn) = dim;
11061               /* Setup the location of the current dimension, for
11062                  later error report. */
11063               TREE_PURPOSE (cn) = 
11064                 build_expr_wfl (NULL_TREE, input_filename, 0, 0);
11065               EXPR_WFL_LINECOL (TREE_PURPOSE (cn)) = location;
11066             }
11067         }
11068       /* They complete the array creation expression, if no errors
11069          were found. */
11070       CAN_COMPLETE_NORMALLY (node) = 1;
11071       return (flag ? error_mark_node
11072               : force_evaluation_order (patch_newarray (node)));
11073
11074     case NEW_ANONYMOUS_ARRAY_EXPR:
11075       /* Create the array type if necessary. */
11076       if (ANONYMOUS_ARRAY_DIMS_SIG (node))
11077         {
11078           tree type = ANONYMOUS_ARRAY_BASE_TYPE (node);
11079           if (!(type = resolve_type_during_patch (type)))
11080             return error_mark_node;
11081           type = build_array_from_name (type, NULL_TREE,
11082                                         ANONYMOUS_ARRAY_DIMS_SIG (node), NULL);
11083           ANONYMOUS_ARRAY_BASE_TYPE (node) = build_pointer_type (type);
11084         }
11085       node = patch_new_array_init (ANONYMOUS_ARRAY_BASE_TYPE (node),
11086                                    ANONYMOUS_ARRAY_INITIALIZER (node));
11087       if (node == error_mark_node)
11088         return error_mark_node;
11089       CAN_COMPLETE_NORMALLY (node) = 1;
11090       return node;
11091
11092     case NEW_CLASS_EXPR:
11093     case CALL_EXPR:
11094       /* Complete function's argument(s) first */
11095       if (complete_function_arguments (node))
11096         return error_mark_node;
11097       else
11098         {
11099           tree decl, wfl = TREE_OPERAND (node, 0);
11100           int in_this = CALL_THIS_CONSTRUCTOR_P (node);
11101
11102           node = patch_method_invocation (node, NULL_TREE, 
11103                                           NULL_TREE, 0, &decl);
11104           if (node == error_mark_node)
11105             return error_mark_node;
11106
11107           check_thrown_exceptions (EXPR_WFL_LINECOL (node), decl);
11108           /* If we call this(...), register signature and positions */
11109           if (in_this)
11110             DECL_CONSTRUCTOR_CALLS (current_function_decl) = 
11111               tree_cons (wfl, decl, 
11112                          DECL_CONSTRUCTOR_CALLS (current_function_decl));
11113           CAN_COMPLETE_NORMALLY (node) = 1;
11114           return force_evaluation_order (node);
11115         }
11116
11117     case MODIFY_EXPR:
11118       /* Save potential wfls */
11119       wfl_op1 = TREE_OPERAND (node, 0);
11120       TREE_OPERAND (node, 0) = nn = java_complete_lhs (wfl_op1);
11121       
11122       if (MODIFY_EXPR_FROM_INITIALIZATION_P (node)
11123           && TREE_CODE (nn) == VAR_DECL && TREE_STATIC (nn)
11124           && DECL_INITIAL (nn) != NULL_TREE)
11125         {
11126           tree value;
11127           
11128           push_obstacks (&permanent_obstack, &permanent_obstack);
11129           value = fold_constant_for_init (nn, nn);
11130           pop_obstacks ();
11131
11132           if (value != NULL_TREE)
11133             {
11134               tree type = TREE_TYPE (value);
11135               if (JPRIMITIVE_TYPE_P (type) || 
11136                   (type == string_ptr_type_node && ! flag_emit_class_files))
11137                 return empty_stmt_node;
11138             }
11139           DECL_INITIAL (nn) = NULL_TREE;
11140         }
11141       wfl_op2 = TREE_OPERAND (node, 1);
11142
11143       if (TREE_OPERAND (node, 0) == error_mark_node)
11144         return error_mark_node;
11145
11146       flag = COMPOUND_ASSIGN_P (wfl_op2);
11147       if (flag)
11148         {
11149           /* This might break when accessing outer field from inner
11150              class. TESTME, FIXME */
11151           tree lvalue = java_stabilize_reference (TREE_OPERAND (node, 0)); 
11152
11153           /* Hand stablize the lhs on both places */
11154           TREE_OPERAND (node, 0) = lvalue;
11155           TREE_OPERAND (TREE_OPERAND (node, 1), 0) = 
11156             (flag_emit_class_files ? lvalue : save_expr (lvalue));
11157
11158           /* 15.25.2.a: Left hand is not an array access. FIXME */
11159           /* Now complete the RHS. We write it back later on. */
11160           nn = java_complete_tree (TREE_OPERAND (node, 1));
11161
11162           if ((cn = patch_string (nn)))
11163             nn = cn;
11164
11165           /* The last part of the rewrite for E1 op= E2 is to have 
11166              E1 = (T)(E1 op E2), with T being the type of E1. */
11167           nn = java_complete_tree (build_cast (EXPR_WFL_LINECOL (wfl_op2), 
11168                                                TREE_TYPE (lvalue), nn));
11169
11170           /* 15.25.2.b: Left hand is an array access. FIXME */
11171         }
11172
11173       /* If we're about to patch a NEW_ARRAY_INIT, we call a special
11174          function to complete this RHS. Note that a NEW_ARRAY_INIT
11175          might have been already fully expanded if created as a result
11176          of processing an anonymous array initializer. We avoid doing
11177          the operation twice by testing whether the node already bears
11178          a type. */
11179       else if (TREE_CODE (wfl_op2) == NEW_ARRAY_INIT && !TREE_TYPE (wfl_op2))
11180         nn = patch_new_array_init (TREE_TYPE (TREE_OPERAND (node, 0)),
11181                                    TREE_OPERAND (node, 1));
11182       /* Otherwise we simply complete the RHS */
11183       else
11184         nn = java_complete_tree (TREE_OPERAND (node, 1));
11185
11186       if (nn == error_mark_node)
11187         return error_mark_node;
11188
11189       /* Write back the RHS as we evaluated it. */
11190       TREE_OPERAND (node, 1) = nn;
11191
11192       /* In case we're handling = with a String as a RHS, we need to
11193          produce a String out of the RHS (it might still be a
11194          STRING_CST or a StringBuffer at this stage */
11195       if ((nn = patch_string (TREE_OPERAND (node, 1))))
11196         TREE_OPERAND (node, 1) = nn;
11197
11198       if ((nn = outer_field_access_fix (wfl_op1, TREE_OPERAND (node, 0),
11199                                         TREE_OPERAND (node, 1))))
11200         {
11201           /* We return error_mark_node if outer_field_access_fix
11202              detects we write into a final. */
11203           if (nn == error_mark_node)
11204             return error_mark_node;
11205           node = nn;
11206         }
11207       else
11208         {
11209           node = patch_assignment (node, wfl_op1, wfl_op2);
11210           /* Reorganize the tree if necessary. */
11211           if (flag && (!JREFERENCE_TYPE_P (TREE_TYPE (node)) 
11212                        || JSTRING_P (TREE_TYPE (node))))
11213             node = java_refold (node);
11214         }
11215       
11216       CAN_COMPLETE_NORMALLY (node) = 1;
11217       return node;
11218
11219     case MULT_EXPR:
11220     case PLUS_EXPR:
11221     case MINUS_EXPR:
11222     case LSHIFT_EXPR:
11223     case RSHIFT_EXPR:
11224     case URSHIFT_EXPR:
11225     case BIT_AND_EXPR:
11226     case BIT_XOR_EXPR:
11227     case BIT_IOR_EXPR:
11228     case TRUNC_MOD_EXPR:
11229     case TRUNC_DIV_EXPR:
11230     case RDIV_EXPR:
11231     case TRUTH_ANDIF_EXPR:
11232     case TRUTH_ORIF_EXPR:
11233     case EQ_EXPR: 
11234     case NE_EXPR:
11235     case GT_EXPR:
11236     case GE_EXPR:
11237     case LT_EXPR:
11238     case LE_EXPR:
11239       /* Operands 0 and 1 are WFL in certain cases only. patch_binop
11240          knows how to handle those cases. */
11241       wfl_op1 = TREE_OPERAND (node, 0);
11242       wfl_op2 = TREE_OPERAND (node, 1);
11243
11244       CAN_COMPLETE_NORMALLY (node) = 1;
11245       /* Don't complete string nodes if dealing with the PLUS operand. */
11246       if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op1))
11247         {
11248           nn = java_complete_tree (wfl_op1);
11249           if (nn == error_mark_node)
11250             return error_mark_node;
11251
11252           TREE_OPERAND (node, 0) = nn;
11253         }
11254       if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op2))
11255         {
11256           nn = java_complete_tree (wfl_op2);
11257           if (nn == error_mark_node)
11258             return error_mark_node;
11259
11260           TREE_OPERAND (node, 1) = nn;
11261         }
11262       return force_evaluation_order (patch_binop (node, wfl_op1, wfl_op2));
11263
11264     case INSTANCEOF_EXPR:
11265       wfl_op1 = TREE_OPERAND (node, 0);
11266       COMPLETE_CHECK_OP_0 (node);
11267       if (flag_emit_xref)
11268         {
11269           TREE_TYPE (node) = boolean_type_node;
11270           return node;
11271         }
11272       return patch_binop (node, wfl_op1, TREE_OPERAND (node, 1));
11273
11274     case UNARY_PLUS_EXPR:
11275     case NEGATE_EXPR:
11276     case TRUTH_NOT_EXPR:
11277     case BIT_NOT_EXPR:
11278     case PREDECREMENT_EXPR:
11279     case PREINCREMENT_EXPR:
11280     case POSTDECREMENT_EXPR:
11281     case POSTINCREMENT_EXPR:
11282     case CONVERT_EXPR:
11283       /* There are cases were wfl_op1 is a WFL. patch_unaryop knows
11284          how to handle those cases. */
11285       wfl_op1 = TREE_OPERAND (node, 0);
11286       CAN_COMPLETE_NORMALLY (node) = 1;
11287       TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
11288       if (TREE_OPERAND (node, 0) == error_mark_node)
11289         return error_mark_node;
11290       node = patch_unaryop (node, wfl_op1);
11291       CAN_COMPLETE_NORMALLY (node) = 1;
11292       break;
11293
11294     case ARRAY_REF:
11295       /* There are cases were wfl_op1 is a WFL. patch_array_ref knows
11296          how to handle those cases. */
11297       wfl_op1 = TREE_OPERAND (node, 0);
11298       TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
11299       if (TREE_OPERAND (node, 0) == error_mark_node)
11300         return error_mark_node;
11301       if (!flag_emit_class_files && !flag_emit_xref)
11302         TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
11303       /* The same applies to wfl_op2 */
11304       wfl_op2 = TREE_OPERAND (node, 1);
11305       TREE_OPERAND (node, 1) = java_complete_tree (wfl_op2);
11306       if (TREE_OPERAND (node, 1) == error_mark_node)
11307         return error_mark_node;
11308       if (!flag_emit_class_files && !flag_emit_xref)
11309         TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1));
11310       return patch_array_ref (node);
11311
11312     case RECORD_TYPE:
11313       return node;;
11314
11315     case COMPONENT_REF:
11316       /* The first step in the re-write of qualified name handling.  FIXME.
11317          So far, this is only to support PRIMTYPE.class -> PRIMCLASS.TYPE. */
11318       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
11319       if (TREE_CODE (TREE_OPERAND (node, 0)) == RECORD_TYPE)
11320         {
11321           tree name = TREE_OPERAND (node, 1);
11322           tree field = lookup_field_wrapper (TREE_OPERAND (node, 0), name);
11323           if (field == NULL_TREE)
11324             {
11325               error ("missing static field `%s'", IDENTIFIER_POINTER (name));
11326               return error_mark_node;
11327             }
11328           if (! FIELD_STATIC (field))
11329             {
11330               error ("not a static field `%s'", IDENTIFIER_POINTER (name));
11331               return error_mark_node;
11332             }
11333           return field;
11334         }
11335       else
11336         fatal ("unimplemented java_complete_tree for COMPONENT_REF");
11337       break;
11338
11339     case THIS_EXPR:
11340       /* Can't use THIS in a static environment */
11341       if (!current_this)
11342         {
11343           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11344           parse_error_context (wfl_operator,
11345                                "Keyword `this' used outside allowed context");
11346           TREE_TYPE (node) = error_mark_node;
11347           return error_mark_node;
11348         }
11349       if (ctxp->explicit_constructor_p)
11350         {
11351           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11352           parse_error_context 
11353             (wfl_operator, "Can't reference `this' or `super' before the superclass constructor has been called");
11354           TREE_TYPE (node) = error_mark_node;
11355           return error_mark_node;
11356         }
11357       return current_this;
11358       
11359     case CLASS_LITERAL:
11360       CAN_COMPLETE_NORMALLY (node) = 1;
11361       node = patch_incomplete_class_ref (node);
11362       if (node == error_mark_node)
11363         return error_mark_node;
11364       break;
11365
11366     case INSTANCE_INITIALIZERS_EXPR:
11367       in_instance_initializer++;
11368       node = java_complete_tree (TREE_OPERAND (node, 0));
11369       in_instance_initializer--;
11370       if (node != error_mark_node)
11371         TREE_TYPE (node) = void_type_node;
11372       else
11373         return error_mark_node;
11374       break;
11375
11376     default:
11377       CAN_COMPLETE_NORMALLY (node) = 1;
11378       /* Ok: may be we have a STRING_CST or a crafted `StringBuffer'
11379          and it's time to turn it into the appropriate String object */
11380       if ((nn = patch_string (node)))
11381         node = nn;
11382       else
11383         fatal ("No case for tree code `%s' - java_complete_tree\n",
11384                tree_code_name [TREE_CODE (node)]);
11385     }
11386   return node;
11387 }
11388
11389 /* Complete function call's argument. Return a non zero value is an
11390    error was found.  */
11391
11392 static int
11393 complete_function_arguments (node)
11394      tree node;
11395 {
11396   int flag = 0;
11397   tree cn;
11398
11399   ctxp->explicit_constructor_p += (CALL_EXPLICIT_CONSTRUCTOR_P (node) ? 1 : 0);
11400   for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
11401     {
11402       tree wfl = TREE_VALUE (cn), parm, temp;
11403       parm = java_complete_tree (wfl);
11404
11405       if (parm == error_mark_node)
11406         {
11407           flag = 1;
11408           continue;
11409         }
11410       /* If have a string literal that we haven't transformed yet or a
11411          crafted string buffer, as a result of use of the the String
11412          `+' operator. Build `parm.toString()' and expand it. */
11413       if ((temp = patch_string (parm)))
11414         parm = temp;
11415       /* Inline PRIMTYPE.TYPE read access */
11416       parm = maybe_build_primttype_type_ref (parm, wfl);
11417
11418       TREE_VALUE (cn) = parm;
11419     }
11420   ctxp->explicit_constructor_p -= (CALL_EXPLICIT_CONSTRUCTOR_P (node) ? 1 : 0);
11421   return flag;
11422 }
11423
11424 /* Sometimes (for loops and variable initialized during their
11425    declaration), we want to wrap a statement around a WFL and turn it
11426    debugable.  */
11427
11428 static tree
11429 build_debugable_stmt (location, stmt)
11430     int location;
11431     tree stmt;
11432 {
11433   if (TREE_CODE (stmt) != EXPR_WITH_FILE_LOCATION)
11434     {
11435       stmt = build_expr_wfl (stmt, input_filename, 0, 0);
11436       EXPR_WFL_LINECOL (stmt) = location;
11437     }
11438   JAVA_MAYBE_GENERATE_DEBUG_INFO (stmt);
11439   return stmt;
11440 }
11441
11442 static tree
11443 build_expr_block (body, decls)
11444      tree body, decls;
11445 {
11446   tree node = make_node (BLOCK);
11447   BLOCK_EXPR_DECLS (node) = decls;
11448   BLOCK_EXPR_BODY (node) = body;
11449   if (body)
11450     TREE_TYPE (node) = TREE_TYPE (body);
11451   TREE_SIDE_EFFECTS (node) = 1;
11452   return node;
11453 }
11454
11455 /* Create a new function block and link it approriately to current
11456    function block chain */
11457
11458 static tree
11459 enter_block ()
11460 {
11461   return (enter_a_block (build_expr_block (NULL_TREE, NULL_TREE)));
11462 }
11463
11464 /* Link block B supercontext to the previous block. The current
11465    function DECL is used as supercontext when enter_a_block is called
11466    for the first time for a given function. The current function body
11467    (DECL_FUNCTION_BODY) is set to be block B.  */
11468
11469 static tree
11470 enter_a_block (b)
11471      tree b;
11472 {
11473   tree fndecl = current_function_decl; 
11474
11475   if (!fndecl) {
11476     BLOCK_SUPERCONTEXT (b) = current_static_block;
11477     current_static_block = b;
11478   }
11479
11480   else if (!DECL_FUNCTION_BODY (fndecl))
11481     {
11482       BLOCK_SUPERCONTEXT (b) = fndecl;
11483       DECL_FUNCTION_BODY (fndecl) = b;
11484     }
11485   else
11486     {
11487       BLOCK_SUPERCONTEXT (b) = DECL_FUNCTION_BODY (fndecl);
11488       DECL_FUNCTION_BODY (fndecl) = b;
11489     }
11490   return b;
11491 }
11492
11493 /* Exit a block by changing the current function body
11494    (DECL_FUNCTION_BODY) to the current block super context, only if
11495    the block being exited isn't the method's top level one.  */
11496
11497 static tree
11498 exit_block ()
11499 {
11500   tree b;
11501   if (current_function_decl)
11502     {
11503       b = DECL_FUNCTION_BODY (current_function_decl);
11504       if (BLOCK_SUPERCONTEXT (b) != current_function_decl)
11505         DECL_FUNCTION_BODY (current_function_decl) = BLOCK_SUPERCONTEXT (b);
11506     }
11507   else
11508     {
11509       b = current_static_block;
11510
11511       if (BLOCK_SUPERCONTEXT (b))
11512         current_static_block = BLOCK_SUPERCONTEXT (b);
11513     }
11514   return b;
11515 }
11516
11517 /* Lookup for NAME in the nested function's blocks, all the way up to
11518    the current toplevel one. It complies with Java's local variable
11519    scoping rules.  */
11520
11521 static tree
11522 lookup_name_in_blocks (name)
11523      tree name;
11524 {
11525   tree b = GET_CURRENT_BLOCK (current_function_decl);
11526
11527   while (b != current_function_decl)
11528     {
11529       tree current;
11530
11531       /* Paranoid sanity check. To be removed */
11532       if (TREE_CODE (b) != BLOCK)
11533         fatal ("non block expr function body - lookup_name_in_blocks");
11534
11535       for (current = BLOCK_EXPR_DECLS (b); current; 
11536            current = TREE_CHAIN (current))
11537         if (DECL_NAME (current) == name)
11538           return current;
11539       b = BLOCK_SUPERCONTEXT (b);
11540     }
11541   return NULL_TREE;
11542 }
11543
11544 static void
11545 maybe_absorb_scoping_blocks ()
11546 {
11547   while (BLOCK_EXPR_ORIGIN (GET_CURRENT_BLOCK (current_function_decl)))
11548     {
11549       tree b = exit_block ();
11550       java_method_add_stmt (current_function_decl, b);
11551       SOURCE_FRONTEND_DEBUG (("Absorbing scoping block at line %d", lineno));
11552     }
11553 }
11554
11555 \f
11556 /* This section of the source is reserved to build_* functions that
11557    are building incomplete tree nodes and the patch_* functions that
11558    are completing them.  */
11559
11560 /* Wrap a non WFL node around a WFL.  */
11561 static tree
11562 build_wfl_wrap (node, location)
11563     tree node;
11564     int location;
11565 {
11566   tree wfl, node_to_insert = node;
11567   
11568   /* We want to process THIS . xxx symbolicaly, to keep it consistent
11569      with the way we're processing SUPER. A THIS from a primary as a
11570      different form than a SUPER. Turn THIS into something symbolic */
11571   if (TREE_CODE (node) == THIS_EXPR)
11572     node_to_insert = wfl = build_wfl_node (this_identifier_node);
11573   else
11574     wfl = build_expr_wfl (NULL_TREE, ctxp->filename, 0, 0);
11575
11576   EXPR_WFL_LINECOL (wfl) = location;
11577   EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (node_to_insert, NULL_TREE);
11578   return wfl;
11579 }
11580
11581
11582 /* Build a super() constructor invocation. Returns empty_stmt_node if
11583    we're currently dealing with the class java.lang.Object. */
11584
11585 static tree
11586 build_super_invocation (mdecl)
11587      tree mdecl;
11588 {
11589   if (DECL_CONTEXT (mdecl) == object_type_node)
11590     return empty_stmt_node;
11591   else
11592     {
11593       tree super_wfl = build_wfl_node (super_identifier_node);
11594       tree a = NULL_TREE, t;
11595       /* If we're dealing with an anonymous class, pass the arguments
11596          of the crafted constructor along. */
11597       if (ANONYMOUS_CLASS_P (DECL_CONTEXT (mdecl)))
11598         {
11599           SKIP_THIS_AND_ARTIFICIAL_PARMS (t, mdecl);
11600           for (; t != end_params_node; t = TREE_CHAIN (t))
11601             a = tree_cons (NULL_TREE, build_wfl_node (TREE_PURPOSE (t)), a);
11602         }
11603       return build_method_invocation (super_wfl, a);
11604     }
11605 }
11606
11607 /* Build a SUPER/THIS qualified method invocation.  */
11608
11609 static tree
11610 build_this_super_qualified_invocation (use_this, name, args, lloc, rloc)
11611      int use_this;
11612      tree name, args;
11613      int lloc, rloc;
11614 {
11615   tree invok;
11616   tree wfl = 
11617     build_wfl_node (use_this ? this_identifier_node : super_identifier_node);
11618   EXPR_WFL_LINECOL (wfl) = lloc;
11619   invok = build_method_invocation (name, args);
11620   return make_qualified_primary (wfl, invok, rloc);
11621 }
11622
11623 /* Build an incomplete CALL_EXPR node. */
11624
11625 static tree
11626 build_method_invocation (name, args)
11627     tree name;
11628     tree args;
11629 {
11630   tree call = build (CALL_EXPR, NULL_TREE, name, args, NULL_TREE);
11631   TREE_SIDE_EFFECTS (call) = 1;
11632   EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
11633   return call;
11634 }
11635
11636 /* Build an incomplete new xxx(...) node. */
11637
11638 static tree
11639 build_new_invocation (name, args)
11640     tree name, args;
11641 {
11642   tree call = build (NEW_CLASS_EXPR, NULL_TREE, name, args, NULL_TREE);
11643   TREE_SIDE_EFFECTS (call) = 1;
11644   EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
11645   return call;
11646 }
11647
11648 /* Build an incomplete assignment expression. */
11649
11650 static tree
11651 build_assignment (op, op_location, lhs, rhs)
11652      int op, op_location;
11653      tree lhs, rhs;
11654 {
11655   tree assignment;
11656   /* Build the corresponding binop if we deal with a Compound
11657      Assignment operator. Mark the binop sub-tree as part of a
11658      Compound Assignment expression */
11659   if (op != ASSIGN_TK)
11660     {
11661       rhs = build_binop (BINOP_LOOKUP (op), op_location, lhs, rhs);
11662       COMPOUND_ASSIGN_P (rhs) = 1;
11663     }
11664   assignment = build (MODIFY_EXPR, NULL_TREE, lhs, rhs);
11665   TREE_SIDE_EFFECTS (assignment) = 1;
11666   EXPR_WFL_LINECOL (assignment) = op_location;
11667   return assignment;
11668 }
11669
11670 /* Print an INTEGER_CST node in a static buffer, and return the buffer. */
11671
11672 char *
11673 print_int_node (node)
11674     tree node;
11675 {
11676   static char buffer [80];
11677   if (TREE_CONSTANT_OVERFLOW (node))
11678     sprintf (buffer, "<overflow>");
11679     
11680   if (TREE_INT_CST_HIGH (node) == 0)
11681     sprintf (buffer, HOST_WIDE_INT_PRINT_UNSIGNED,
11682              TREE_INT_CST_LOW (node));
11683   else if (TREE_INT_CST_HIGH (node) == -1
11684            && TREE_INT_CST_LOW (node) != 0)
11685     {
11686       buffer [0] = '-';
11687       sprintf (&buffer [1], HOST_WIDE_INT_PRINT_UNSIGNED,
11688                -TREE_INT_CST_LOW (node));
11689     }
11690   else
11691     sprintf (buffer, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
11692              TREE_INT_CST_HIGH (node), TREE_INT_CST_LOW (node));
11693
11694   return buffer;
11695 }
11696
11697 /* Return 1 if an assignment to a FINAL is attempted in a non suitable
11698    context.  */
11699
11700 static int
11701 check_final_assignment (lvalue, wfl)
11702      tree lvalue, wfl;
11703 {
11704   if (TREE_CODE (lvalue) == COMPOUND_EXPR 
11705       && JDECL_P (TREE_OPERAND (lvalue, 1)))
11706     lvalue = TREE_OPERAND (lvalue, 1);
11707
11708   /* When generating class files, references to the `length' field
11709      look a bit different.  */
11710   if ((flag_emit_class_files
11711        && TREE_CODE (lvalue) == COMPONENT_REF
11712        && TYPE_ARRAY_P (TREE_TYPE (TREE_OPERAND (lvalue, 0)))
11713        && FIELD_FINAL (TREE_OPERAND (lvalue, 1)))
11714       || (TREE_CODE (lvalue) == FIELD_DECL
11715           && FIELD_FINAL (lvalue)
11716           && !DECL_CLINIT_P (current_function_decl)
11717           && !DECL_FINIT_P (current_function_decl)))
11718     {
11719       parse_error_context 
11720         (wfl, "Can't assign a value to the final variable `%s'",
11721          IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
11722       return 1;
11723     }
11724   return 0;
11725 }
11726
11727 /* Inline references to java.lang.PRIMTYPE.TYPE when accessed in
11728    read. This is needed to avoid circularities in the implementation
11729    of these fields in libjava. */
11730
11731 static tree
11732 maybe_build_primttype_type_ref (rhs, wfl)
11733     tree rhs, wfl;
11734 {
11735   tree to_return = NULL_TREE;
11736   tree rhs_type = TREE_TYPE (rhs);
11737   if (TREE_CODE (rhs) == COMPOUND_EXPR)
11738     {
11739       tree n = TREE_OPERAND (rhs, 1);
11740       if (TREE_CODE (n) == VAR_DECL 
11741           && DECL_NAME (n) == TYPE_identifier_node
11742           && rhs_type == class_ptr_type
11743           && TREE_CODE (EXPR_WFL_NODE (wfl)) == IDENTIFIER_NODE)
11744         {
11745           const char *self_name = IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl));
11746           if (!strncmp (self_name, "java.lang.", 10))
11747             to_return = build_primtype_type_ref (self_name);
11748         }
11749     }
11750   return (to_return ? to_return : rhs );
11751 }
11752
11753 /* 15.25 Assignment operators. */
11754
11755 static tree
11756 patch_assignment (node, wfl_op1, wfl_op2)
11757      tree node;
11758      tree wfl_op1;
11759      tree wfl_op2;
11760 {
11761   tree rhs = TREE_OPERAND (node, 1);
11762   tree lvalue = TREE_OPERAND (node, 0), llvalue;
11763   tree lhs_type = NULL_TREE, rhs_type, new_rhs = NULL_TREE;
11764   int error_found = 0;
11765   int lvalue_from_array = 0;
11766
11767   /* Can't assign to a (blank) final. */
11768   if (check_final_assignment (lvalue, wfl_op1))
11769     error_found = 1;
11770
11771   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11772
11773   /* Lhs can be a named variable */
11774   if (JDECL_P (lvalue))
11775     {
11776       lhs_type = TREE_TYPE (lvalue);
11777     }
11778   /* Or Lhs can be a array acccess. Should that be lvalue ? FIXME +
11779      comment on reason why */
11780   else if (TREE_CODE (wfl_op1) == ARRAY_REF)
11781     {
11782       lhs_type = TREE_TYPE (lvalue);
11783       lvalue_from_array = 1;
11784     }
11785   /* Or a field access */
11786   else if (TREE_CODE (lvalue) == COMPONENT_REF)
11787     lhs_type = TREE_TYPE (lvalue);
11788   /* Or a function return slot */
11789   else if (TREE_CODE (lvalue) == RESULT_DECL)
11790     lhs_type = TREE_TYPE (lvalue);
11791   /* Otherwise, we might want to try to write into an optimized static
11792      final, this is an of a different nature, reported further on. */
11793   else if (TREE_CODE (wfl_op1) == EXPR_WITH_FILE_LOCATION
11794            && resolve_expression_name (wfl_op1, &llvalue))
11795     {
11796       if (!error_found && check_final_assignment (llvalue, wfl_op1))
11797         {
11798           /* What we should do instead is resetting the all the flags
11799              previously set, exchange lvalue for llvalue and continue. */
11800           error_found = 1;
11801           return error_mark_node;
11802         }
11803       else 
11804         lhs_type = TREE_TYPE (lvalue);
11805     }
11806   else 
11807     {
11808       parse_error_context (wfl_op1, "Invalid left hand side of assignment");
11809       error_found = 1;
11810     }
11811
11812   rhs_type = TREE_TYPE (rhs);
11813   /* 5.1 Try the assignment conversion for builtin type. */
11814   new_rhs = try_builtin_assignconv (wfl_op1, lhs_type, rhs);
11815
11816   /* 5.2 If it failed, try a reference conversion */
11817   if (!new_rhs && (new_rhs = try_reference_assignconv (lhs_type, rhs)))
11818     lhs_type = promote_type (rhs_type);
11819
11820   /* 15.25.2 If we have a compound assignment, convert RHS into the
11821      type of the LHS */
11822   else if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
11823     new_rhs = convert (lhs_type, rhs);
11824
11825   /* Explicit cast required. This is an error */
11826   if (!new_rhs)
11827     {
11828       char *t1 = xstrdup (lang_printable_name (TREE_TYPE (rhs), 0));
11829       char *t2 = xstrdup (lang_printable_name (lhs_type, 0));
11830       tree wfl;
11831       char operation [32];      /* Max size known */
11832
11833       /* If the assignment is part of a declaration, we use the WFL of
11834          the declared variable to point out the error and call it a
11835          declaration problem. If the assignment is a genuine =
11836          operator, we call is a operator `=' problem, otherwise we
11837          call it an assignment problem. In both of these last cases,
11838          we use the WFL of the operator to indicate the error. */
11839
11840       if (MODIFY_EXPR_FROM_INITIALIZATION_P (node))
11841         {
11842           wfl = wfl_op1;
11843           strcpy (operation, "declaration");
11844         }
11845       else
11846         {
11847           wfl = wfl_operator;
11848           if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
11849             strcpy (operation, "assignment");
11850           else if (TREE_CODE (TREE_OPERAND (node, 0)) == RESULT_DECL)
11851             strcpy (operation, "`return'");
11852           else
11853             strcpy (operation, "`='");
11854         }
11855
11856       if (!valid_cast_to_p (rhs_type, lhs_type))
11857         parse_error_context
11858           (wfl, "Incompatible type for %s. Can't convert `%s' to `%s'",
11859            operation, t1, t2);
11860       else
11861         parse_error_context (wfl, "Incompatible type for %s. Explicit cast needed to convert `%s' to `%s'",
11862                              operation, t1, t2);
11863       free (t1); free (t2);
11864       error_found = 1;
11865     }
11866
11867   /* Inline read access to java.lang.PRIMTYPE.TYPE */
11868   if (new_rhs)
11869     new_rhs = maybe_build_primttype_type_ref (new_rhs, wfl_op2);
11870
11871   if (error_found)
11872     return error_mark_node;
11873
11874   /* 10.10: Array Store Exception runtime check */
11875   if (!flag_emit_class_files
11876       && !flag_emit_xref
11877       && lvalue_from_array 
11878       && JREFERENCE_TYPE_P (TYPE_ARRAY_ELEMENT (lhs_type)))
11879     {
11880       tree check;
11881       tree base = lvalue;
11882
11883       /* We need to retrieve the right argument for _Jv_CheckArrayStore */
11884       if (TREE_CODE (lvalue) == COMPOUND_EXPR)
11885         base = TREE_OPERAND (lvalue, 0);
11886       else
11887         {
11888           if (flag_bounds_check)
11889             base = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (base, 0), 1), 0);
11890           else
11891             base = TREE_OPERAND (TREE_OPERAND (base, 0), 0);
11892         }
11893
11894       /* Build the invocation of _Jv_CheckArrayStore */
11895       new_rhs = save_expr (new_rhs);
11896       check = build (CALL_EXPR, void_type_node,
11897                      build_address_of (soft_checkarraystore_node),
11898                      tree_cons (NULL_TREE, base,
11899                                 build_tree_list (NULL_TREE, new_rhs)),
11900                      NULL_TREE);
11901       TREE_SIDE_EFFECTS (check) = 1;
11902
11903       /* We have to decide on an insertion point */
11904       if (TREE_CODE (lvalue) == COMPOUND_EXPR)
11905         {
11906           tree t;
11907           if (flag_bounds_check)
11908             {
11909               t = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (lvalue, 1), 0), 0);
11910               TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (lvalue, 1), 0), 0) =
11911                 build (COMPOUND_EXPR, void_type_node, t, check);
11912             }
11913           else
11914             TREE_OPERAND (lvalue, 1) = build (COMPOUND_EXPR, lhs_type,
11915                                               check, TREE_OPERAND (lvalue, 1));
11916         }
11917       else 
11918         {
11919           /* Make sure the bound check will happen before the store check */
11920           if (flag_bounds_check)
11921             TREE_OPERAND (TREE_OPERAND (lvalue, 0), 0) =
11922               build (COMPOUND_EXPR, void_type_node,
11923                      TREE_OPERAND (TREE_OPERAND (lvalue, 0), 0), check);
11924           else
11925             lvalue = build (COMPOUND_EXPR, lhs_type, check, lvalue);
11926         }
11927     }
11928
11929   TREE_OPERAND (node, 0) = lvalue;
11930   TREE_OPERAND (node, 1) = new_rhs;
11931   TREE_TYPE (node) = lhs_type;
11932   return node;
11933 }
11934
11935 /* Check that type SOURCE can be cast into type DEST. If the cast
11936    can't occur at all, return 0 otherwise 1. This function is used to
11937    produce accurate error messages on the reasons why an assignment
11938    failed. */
11939
11940 static tree
11941 try_reference_assignconv (lhs_type, rhs)
11942      tree lhs_type, rhs;
11943 {
11944   tree new_rhs = NULL_TREE;
11945   tree rhs_type = TREE_TYPE (rhs);
11946
11947   if (!JPRIMITIVE_TYPE_P (rhs_type) && JREFERENCE_TYPE_P (lhs_type))
11948     {
11949       /* `null' may be assigned to any reference type */
11950       if (rhs == null_pointer_node)
11951         new_rhs = null_pointer_node;
11952       /* Try the reference assignment conversion */
11953       else if (valid_ref_assignconv_cast_p (rhs_type, lhs_type, 0))
11954         new_rhs = rhs;
11955       /* This is a magic assignment that we process differently */
11956       else if (rhs == soft_exceptioninfo_call_node)
11957         new_rhs = rhs;
11958     }
11959   return new_rhs;
11960 }
11961
11962 /* Check that RHS can be converted into LHS_TYPE by the assignment
11963    conversion (5.2), for the cases of RHS being a builtin type. Return
11964    NULL_TREE if the conversion fails or if because RHS isn't of a
11965    builtin type. Return a converted RHS if the conversion is possible.  */
11966
11967 static tree
11968 try_builtin_assignconv (wfl_op1, lhs_type, rhs)
11969      tree wfl_op1, lhs_type, rhs;
11970 {
11971   tree new_rhs = NULL_TREE;
11972   tree rhs_type = TREE_TYPE (rhs);
11973
11974   /* Zero accepted everywhere */
11975   if (TREE_CODE (rhs) == INTEGER_CST 
11976       && TREE_INT_CST_HIGH (rhs) == 0 && TREE_INT_CST_LOW (rhs) == 0
11977       && JPRIMITIVE_TYPE_P (rhs_type))
11978     new_rhs = convert (lhs_type, rhs);
11979
11980   /* 5.1.1 Try Identity Conversion,
11981      5.1.2 Try Widening Primitive Conversion */
11982   else if (valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type))
11983     new_rhs = convert (lhs_type, rhs);
11984
11985   /* Try a narrowing primitive conversion (5.1.3): 
11986        - expression is a constant expression of type int AND
11987        - variable is byte, short or char AND
11988        - The value of the expression is representable in the type of the 
11989          variable */
11990   else if (rhs_type == int_type_node && TREE_CONSTANT (rhs)
11991            && (lhs_type == byte_type_node || lhs_type == char_type_node
11992                || lhs_type == short_type_node))
11993     {
11994       if (int_fits_type_p (rhs, lhs_type))
11995         new_rhs = convert (lhs_type, rhs);
11996       else if (wfl_op1)         /* Might be called with a NULL */
11997         parse_warning_context 
11998           (wfl_op1, "Constant expression `%s' to wide for narrowing primitive conversion to `%s'", 
11999            print_int_node (rhs), lang_printable_name (lhs_type, 0));
12000       /* Reported a warning that will turn into an error further
12001          down, so we don't return */
12002     }
12003
12004   return new_rhs;
12005 }
12006
12007 /* Return 1 if RHS_TYPE can be converted to LHS_TYPE by identity
12008    conversion (5.1.1) or widening primitve conversion (5.1.2).  Return
12009    0 is the conversion test fails.  This implements parts the method
12010    invocation convertion (5.3).  */
12011
12012 static int
12013 valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type)
12014      tree lhs_type, rhs_type;
12015 {
12016   /* 5.1.1: This is the identity conversion part. */
12017   if (lhs_type == rhs_type)
12018     return 1;
12019
12020   /* Reject non primitive types */
12021   if (!JPRIMITIVE_TYPE_P (lhs_type) || !JPRIMITIVE_TYPE_P (rhs_type))
12022     return 0;
12023
12024   /* 5.1.2: widening primitive conversion. byte, even if it's smaller
12025      than a char can't be converted into a char. Short can't too, but
12026      the < test below takes care of that */
12027   if (lhs_type == char_type_node && rhs_type == byte_type_node)
12028     return 0;
12029
12030   /* Accept all promoted type here. Note, we can't use <= in the test
12031      below, because we still need to bounce out assignments of short
12032      to char and the likes */
12033   if (lhs_type == int_type_node
12034       && (rhs_type == promoted_byte_type_node
12035           || rhs_type == promoted_short_type_node
12036           || rhs_type == promoted_char_type_node
12037           || rhs_type == promoted_boolean_type_node))
12038     return 1;
12039
12040   /* From here, an integral is widened if its precision is smaller
12041      than the precision of the LHS or if the LHS is a floating point
12042      type, or the RHS is a float and the RHS a double. */
12043   if ((JINTEGRAL_TYPE_P (rhs_type) && JINTEGRAL_TYPE_P (lhs_type) 
12044        && (TYPE_PRECISION (rhs_type) < TYPE_PRECISION (lhs_type)))
12045       || (JINTEGRAL_TYPE_P (rhs_type) && JFLOAT_TYPE_P (lhs_type))
12046       || (rhs_type == float_type_node && lhs_type == double_type_node))
12047     return 1;
12048
12049   return 0;
12050 }
12051
12052 /* Check that something of SOURCE type can be assigned or cast to
12053    something of DEST type at runtime. Return 1 if the operation is
12054    valid, 0 otherwise. If CAST is set to 1, we're treating the case
12055    were SOURCE is cast into DEST, which borrows a lot of the
12056    assignment check. */
12057
12058 static int
12059 valid_ref_assignconv_cast_p (source, dest, cast)
12060      tree source;
12061      tree dest;
12062      int cast;
12063 {
12064   /* SOURCE or DEST might be null if not from a declared entity. */
12065   if (!source || !dest)
12066     return 0;
12067   if (JNULLP_TYPE_P (source))
12068     return 1;
12069   if (TREE_CODE (source) == POINTER_TYPE)
12070     source = TREE_TYPE (source);
12071   if (TREE_CODE (dest) == POINTER_TYPE)
12072     dest = TREE_TYPE (dest);
12073   /* Case where SOURCE is a class type */
12074   if (TYPE_CLASS_P (source))
12075     {
12076       if (TYPE_CLASS_P (dest))
12077         return  (source == dest 
12078                  || inherits_from_p (source, dest)
12079                  || enclosing_context_p (source, dest)
12080                  || (cast && inherits_from_p (dest, source)));
12081       if (TYPE_INTERFACE_P (dest))
12082         {
12083           /* If doing a cast and SOURCE is final, the operation is
12084              always correct a compile time (because even if SOURCE
12085              does not implement DEST, a subclass of SOURCE might). */
12086           if (cast && !CLASS_FINAL (TYPE_NAME (source)))
12087             return 1;
12088           /* Otherwise, SOURCE must implement DEST */
12089           return interface_of_p (dest, source);
12090         }
12091       /* DEST is an array, cast permited if SOURCE is of Object type */
12092       return (cast && source == object_type_node ? 1 : 0);
12093     }
12094   if (TYPE_INTERFACE_P (source))
12095     {
12096       if (TYPE_CLASS_P (dest))
12097         {
12098           /* If not casting, DEST must be the Object type */
12099           if (!cast)
12100             return dest == object_type_node;
12101           /* We're doing a cast. The cast is always valid is class
12102              DEST is not final, otherwise, DEST must implement SOURCE */
12103           else if (!CLASS_FINAL (TYPE_NAME (dest)))
12104             return 1;
12105           else
12106             return interface_of_p (source, dest);
12107         }
12108       if (TYPE_INTERFACE_P (dest))
12109         {
12110           /* If doing a cast, then if SOURCE and DEST contain method
12111              with the same signature but different return type, then
12112              this is a (compile time) error */
12113           if (cast)
12114             {
12115               tree method_source, method_dest;
12116               tree source_type;
12117               tree source_sig;
12118               tree source_name;
12119               for (method_source = TYPE_METHODS (source); method_source; 
12120                    method_source = TREE_CHAIN (method_source))
12121                 {
12122                   source_sig = 
12123                     build_java_argument_signature (TREE_TYPE (method_source));
12124                   source_type = TREE_TYPE (TREE_TYPE (method_source));
12125                   source_name = DECL_NAME (method_source);
12126                   for (method_dest = TYPE_METHODS (dest);
12127                        method_dest; method_dest = TREE_CHAIN (method_dest))
12128                     if (source_sig == 
12129                         build_java_argument_signature (TREE_TYPE (method_dest))
12130                         && source_name == DECL_NAME (method_dest)
12131                         && source_type != TREE_TYPE (TREE_TYPE (method_dest)))
12132                       return 0;
12133                 }
12134               return 1;
12135             }
12136           else
12137             return source == dest || interface_of_p (dest, source);
12138         }
12139       else                      /* Array */
12140         return (cast ? 
12141                 (DECL_NAME (TYPE_NAME (source)) == java_lang_cloneable) : 0);
12142     }
12143   if (TYPE_ARRAY_P (source))
12144     {
12145       if (TYPE_CLASS_P (dest))
12146         return dest == object_type_node;
12147       /* Can't cast an array to an interface unless the interface is
12148          java.lang.Cloneable */
12149       if (TYPE_INTERFACE_P (dest))
12150         return (DECL_NAME (TYPE_NAME (dest)) == java_lang_cloneable ? 1 : 0);
12151       else                      /* Arrays */
12152         {
12153           tree source_element_type = TYPE_ARRAY_ELEMENT (source);
12154           tree dest_element_type = TYPE_ARRAY_ELEMENT (dest);
12155           
12156           /* In case of severe errors, they turn out null */
12157           if (!dest_element_type || !source_element_type)
12158             return 0;
12159           if (source_element_type == dest_element_type)
12160             return 1;
12161           return valid_ref_assignconv_cast_p (source_element_type,
12162                                               dest_element_type, cast);
12163         }
12164       return 0;
12165     }
12166   return 0;
12167 }
12168
12169 static int
12170 valid_cast_to_p (source, dest)
12171      tree source;
12172      tree dest;
12173 {
12174   if (TREE_CODE (source) == POINTER_TYPE)
12175     source = TREE_TYPE (source);
12176   if (TREE_CODE (dest) == POINTER_TYPE)
12177     dest = TREE_TYPE (dest);
12178
12179   if (TREE_CODE (source) == RECORD_TYPE && TREE_CODE (dest) == RECORD_TYPE)
12180     return valid_ref_assignconv_cast_p (source, dest, 1);
12181
12182   else if (JNUMERIC_TYPE_P (source) && JNUMERIC_TYPE_P (dest))
12183     return 1;
12184
12185   return 0;
12186 }
12187
12188 /* Method invocation conversion test. Return 1 if type SOURCE can be
12189    converted to type DEST through the methond invocation conversion
12190    process (5.3) */
12191
12192 static tree
12193 do_unary_numeric_promotion (arg)
12194      tree arg;
12195 {
12196   tree type = TREE_TYPE (arg);
12197   if (TREE_CODE (type) == INTEGER_TYPE ? TYPE_PRECISION (type) < 32
12198       : TREE_CODE (type) == CHAR_TYPE)
12199     arg = convert (int_type_node, arg);
12200   return arg;
12201 }
12202
12203 /* Return a non zero value if SOURCE can be converted into DEST using
12204    the method invocation conversion rule (5.3).  */
12205 static int
12206 valid_method_invocation_conversion_p (dest, source)
12207      tree dest, source;
12208 {
12209   return ((JPRIMITIVE_TYPE_P (source) && JPRIMITIVE_TYPE_P (dest)
12210            && valid_builtin_assignconv_identity_widening_p (dest, source))
12211           || ((JREFERENCE_TYPE_P (source) || JNULLP_TYPE_P (source))
12212               && (JREFERENCE_TYPE_P (dest) || JNULLP_TYPE_P (dest))
12213               && valid_ref_assignconv_cast_p (source, dest, 0)));
12214 }
12215
12216 /* Build an incomplete binop expression. */
12217
12218 static tree
12219 build_binop (op, op_location, op1, op2)
12220      enum tree_code op;
12221      int op_location;
12222      tree op1, op2;
12223 {
12224   tree binop = build (op, NULL_TREE, op1, op2);
12225   TREE_SIDE_EFFECTS (binop) = 1;
12226   /* Store the location of the operator, for better error report. The
12227      string of the operator will be rebuild based on the OP value. */
12228   EXPR_WFL_LINECOL (binop) = op_location;
12229   return binop;
12230 }
12231
12232 /* Build the string of the operator retained by NODE. If NODE is part
12233    of a compound expression, add an '=' at the end of the string. This
12234    function is called when an error needs to be reported on an
12235    operator. The string is returned as a pointer to a static character
12236    buffer. */
12237
12238 static char *
12239 operator_string (node)
12240      tree node;
12241 {
12242 #define BUILD_OPERATOR_STRING(S)                                        \
12243   {                                                                     \
12244     sprintf (buffer, "%s%s", S, (COMPOUND_ASSIGN_P (node) ? "=" : "")); \
12245     return buffer;                                                      \
12246   }
12247   
12248   static char buffer [10];
12249   switch (TREE_CODE (node))
12250     {
12251     case MULT_EXPR: BUILD_OPERATOR_STRING ("*");
12252     case RDIV_EXPR: BUILD_OPERATOR_STRING ("/");
12253     case TRUNC_MOD_EXPR: BUILD_OPERATOR_STRING ("%");
12254     case PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
12255     case MINUS_EXPR: BUILD_OPERATOR_STRING ("-");
12256     case LSHIFT_EXPR: BUILD_OPERATOR_STRING ("<<");
12257     case RSHIFT_EXPR: BUILD_OPERATOR_STRING (">>");
12258     case URSHIFT_EXPR: BUILD_OPERATOR_STRING (">>>");
12259     case BIT_AND_EXPR: BUILD_OPERATOR_STRING ("&");
12260     case BIT_XOR_EXPR: BUILD_OPERATOR_STRING ("^");
12261     case BIT_IOR_EXPR: BUILD_OPERATOR_STRING ("|");
12262     case TRUTH_ANDIF_EXPR: BUILD_OPERATOR_STRING ("&&");
12263     case TRUTH_ORIF_EXPR: BUILD_OPERATOR_STRING ("||");
12264     case EQ_EXPR: BUILD_OPERATOR_STRING ("==");
12265     case NE_EXPR: BUILD_OPERATOR_STRING ("!=");
12266     case GT_EXPR: BUILD_OPERATOR_STRING (">");
12267     case GE_EXPR: BUILD_OPERATOR_STRING (">=");
12268     case LT_EXPR: BUILD_OPERATOR_STRING ("<");
12269     case LE_EXPR: BUILD_OPERATOR_STRING ("<=");
12270     case UNARY_PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
12271     case NEGATE_EXPR: BUILD_OPERATOR_STRING ("-");
12272     case TRUTH_NOT_EXPR: BUILD_OPERATOR_STRING ("!");
12273     case BIT_NOT_EXPR: BUILD_OPERATOR_STRING ("~");
12274     case PREINCREMENT_EXPR:     /* Fall through */
12275     case POSTINCREMENT_EXPR: BUILD_OPERATOR_STRING ("++");
12276     case PREDECREMENT_EXPR:     /* Fall through */
12277     case POSTDECREMENT_EXPR: BUILD_OPERATOR_STRING ("--");
12278     default:
12279       fatal ("unregistered operator %s - operator_string",
12280              tree_code_name [TREE_CODE (node)]);
12281     }
12282   return NULL;
12283 #undef BUILD_OPERATOR_STRING
12284 }
12285
12286 /* Return 1 if VAR_ACCESS1 is equivalent to VAR_ACCESS2.  */
12287
12288 static int
12289 java_decl_equiv (var_acc1, var_acc2)
12290      tree var_acc1, var_acc2;
12291 {
12292   if (JDECL_P (var_acc1))
12293     return (var_acc1 == var_acc2);
12294   
12295   return (TREE_CODE (var_acc1) == COMPONENT_REF
12296           && TREE_CODE (var_acc2) == COMPONENT_REF
12297           && TREE_OPERAND (TREE_OPERAND (var_acc1, 0), 0)
12298              == TREE_OPERAND (TREE_OPERAND (var_acc2, 0), 0)
12299           && TREE_OPERAND (var_acc1, 1) == TREE_OPERAND (var_acc2, 1));
12300 }
12301
12302 /* Return a non zero value if CODE is one of the operators that can be
12303    used in conjunction with the `=' operator in a compound assignment.  */
12304
12305 static int
12306 binop_compound_p (code)
12307     enum tree_code code;
12308 {
12309   int i;
12310   for (i = 0; i < BINOP_COMPOUND_CANDIDATES; i++)
12311     if (binop_lookup [i] == code)
12312       break;
12313
12314   return i < BINOP_COMPOUND_CANDIDATES;
12315 }
12316
12317 /* Reorganize after a fold to get SAVE_EXPR to generate what we want.  */
12318
12319 static tree
12320 java_refold (t)
12321      tree t;
12322 {
12323   tree c, b, ns, decl;
12324
12325   if (TREE_CODE (t) != MODIFY_EXPR)
12326     return t;
12327
12328   c = TREE_OPERAND (t, 1);
12329   if (! (c && TREE_CODE (c) == COMPOUND_EXPR
12330          && TREE_CODE (TREE_OPERAND (c, 0)) == MODIFY_EXPR
12331          && binop_compound_p (TREE_CODE (TREE_OPERAND (c, 1)))))
12332     return t;
12333
12334   /* Now the left branch of the binary operator. */
12335   b = TREE_OPERAND (TREE_OPERAND (c, 1), 0);
12336   if (! (b && TREE_CODE (b) == NOP_EXPR 
12337          && TREE_CODE (TREE_OPERAND (b, 0)) == SAVE_EXPR))
12338     return t;
12339
12340   ns = TREE_OPERAND (TREE_OPERAND (b, 0), 0);
12341   if (! (ns && TREE_CODE (ns) == NOP_EXPR
12342          && TREE_CODE (TREE_OPERAND (ns, 0)) == SAVE_EXPR))
12343     return t;
12344
12345   decl = TREE_OPERAND (TREE_OPERAND (ns, 0), 0);
12346   if ((JDECL_P (decl) || TREE_CODE (decl) == COMPONENT_REF)
12347       /* It's got to be the an equivalent decl */
12348       && java_decl_equiv (decl, TREE_OPERAND (TREE_OPERAND (c, 0), 0)))
12349     {
12350       /* Shorten the NOP_EXPR/SAVE_EXPR path. */
12351       TREE_OPERAND (TREE_OPERAND (c, 1), 0) = TREE_OPERAND (ns, 0);
12352       /* Substitute the COMPOUND_EXPR by the BINOP_EXPR */
12353       TREE_OPERAND (t, 1) = TREE_OPERAND (c, 1);
12354       /* Change the right part of the BINOP_EXPR */
12355       TREE_OPERAND (TREE_OPERAND (t, 1), 1) = TREE_OPERAND (c, 0);
12356     }
12357
12358   return t;
12359 }
12360
12361 /* Binary operators (15.16 up to 15.18). We return error_mark_node on
12362    errors but we modify NODE so that it contains the type computed
12363    according to the expression, when it's fixed. Otherwise, we write
12364    error_mark_node as the type. It allows us to further the analysis
12365    of remaining nodes and detects more errors in certain cases.  */
12366
12367 static tree
12368 patch_binop (node, wfl_op1, wfl_op2)
12369      tree node;
12370      tree wfl_op1;
12371      tree wfl_op2;
12372 {
12373   tree op1 = TREE_OPERAND (node, 0);
12374   tree op2 = TREE_OPERAND (node, 1);
12375   tree op1_type = TREE_TYPE (op1);
12376   tree op2_type = TREE_TYPE (op2);
12377   tree prom_type = NULL_TREE, cn;
12378   int code = TREE_CODE (node);
12379
12380   /* If 1, tell the routine that we have to return error_mark_node
12381      after checking for the initialization of the RHS */
12382   int error_found = 0;
12383
12384   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
12385
12386   switch (code)
12387     {
12388     /* 15.16 Multiplicative operators */
12389     case MULT_EXPR:             /* 15.16.1 Multiplication Operator * */
12390     case RDIV_EXPR:             /* 15.16.2 Division Operator / */
12391     case TRUNC_DIV_EXPR:        /* 15.16.2 Integral type Division Operator / */
12392     case TRUNC_MOD_EXPR:        /* 15.16.3 Remainder operator % */
12393       if (!JPRIMITIVE_TYPE_P (op1_type) || !JPRIMITIVE_TYPE_P (op2_type))
12394         {
12395           if (!JPRIMITIVE_TYPE_P (op1_type))
12396             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
12397           if (!JPRIMITIVE_TYPE_P (op2_type) && (op1_type != op2_type))
12398             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
12399           TREE_TYPE (node) = error_mark_node;
12400           error_found = 1;
12401           break;
12402         }
12403       prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12404       /* Change the division operator if necessary */
12405       if (code == RDIV_EXPR && TREE_CODE (prom_type) == INTEGER_TYPE)
12406         TREE_SET_CODE (node, TRUNC_DIV_EXPR);
12407
12408       if (TREE_CODE (prom_type) == INTEGER_TYPE
12409           && flag_use_divide_subroutine
12410           && ! flag_emit_class_files
12411           && (code == RDIV_EXPR || code == TRUNC_MOD_EXPR))
12412         return build_java_soft_divmod (TREE_CODE (node), prom_type, op1, op2);
12413  
12414       /* This one is more complicated. FLOATs are processed by a
12415          function call to soft_fmod. Duplicate the value of the
12416          COMPOUND_ASSIGN_P flag. */
12417       if (code == TRUNC_MOD_EXPR)
12418         {
12419           tree mod = build_java_binop (TRUNC_MOD_EXPR, prom_type, op1, op2);
12420           COMPOUND_ASSIGN_P (mod) = COMPOUND_ASSIGN_P (node);
12421           TREE_SIDE_EFFECTS (mod)
12422             = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
12423           return mod;
12424         }
12425       break;
12426
12427     /* 15.17 Additive Operators */
12428     case PLUS_EXPR:             /* 15.17.1 String Concatenation Operator + */
12429
12430       /* Operation is valid if either one argument is a string
12431          constant, a String object or a StringBuffer crafted for the
12432          purpose of the a previous usage of the String concatenation
12433          operator */
12434
12435       if (TREE_CODE (op1) == STRING_CST 
12436           || TREE_CODE (op2) == STRING_CST
12437           || JSTRING_TYPE_P (op1_type)
12438           || JSTRING_TYPE_P (op2_type)
12439           || IS_CRAFTED_STRING_BUFFER_P (op1)
12440           || IS_CRAFTED_STRING_BUFFER_P (op2))
12441         return build_string_concatenation (op1, op2);
12442
12443     case MINUS_EXPR:            /* 15.17.2 Additive Operators (+ and -) for
12444                                    Numeric Types */
12445       if (!JPRIMITIVE_TYPE_P (op1_type) || !JPRIMITIVE_TYPE_P (op2_type))
12446         {
12447           if (!JPRIMITIVE_TYPE_P (op1_type))
12448             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
12449           if (!JPRIMITIVE_TYPE_P (op2_type) && (op1_type != op2_type))
12450             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
12451           TREE_TYPE (node) = error_mark_node;
12452           error_found = 1;
12453           break;
12454         }
12455       prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12456       break;
12457
12458     /* 15.18 Shift Operators */
12459     case LSHIFT_EXPR:
12460     case RSHIFT_EXPR:
12461     case URSHIFT_EXPR:
12462       if (!JINTEGRAL_TYPE_P (op1_type) || !JINTEGRAL_TYPE_P (op2_type))
12463         {
12464           if (!JINTEGRAL_TYPE_P (op1_type))
12465             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
12466           else
12467             {
12468               if (JPRIMITIVE_TYPE_P (op2_type))
12469                 parse_error_context (wfl_operator,
12470                                      "Incompatible type for `%s'. Explicit cast needed to convert shift distance from `%s' to integral",
12471                                      operator_string (node),
12472                                      lang_printable_name (op2_type, 0));
12473               else
12474                 parse_error_context (wfl_operator,
12475                                      "Incompatible type for `%s'. Can't convert shift distance from `%s' to integral", 
12476                                      operator_string (node),
12477                                      lang_printable_name (op2_type, 0));
12478             }
12479           TREE_TYPE (node) = error_mark_node;
12480           error_found = 1;
12481           break;
12482         }
12483
12484       /* Unary numeric promotion (5.6.1) is performed on each operand
12485          separatly */
12486       op1 = do_unary_numeric_promotion (op1);
12487       op2 = do_unary_numeric_promotion (op2);
12488
12489       /* The type of the shift expression is the type of the promoted
12490          type of the left-hand operand */
12491       prom_type = TREE_TYPE (op1);
12492
12493       /* Shift int only up to 0x1f and long up to 0x3f */
12494       if (prom_type == int_type_node)
12495         op2 = fold (build (BIT_AND_EXPR, int_type_node, op2, 
12496                            build_int_2 (0x1f, 0)));
12497       else
12498         op2 = fold (build (BIT_AND_EXPR, int_type_node, op2, 
12499                            build_int_2 (0x3f, 0)));
12500
12501       /* The >>> operator is a >> operating on unsigned quantities */
12502       if (code == URSHIFT_EXPR && ! flag_emit_class_files)
12503         {
12504           tree to_return;
12505           tree utype = unsigned_type (prom_type);
12506           op1 = convert (utype, op1);
12507           TREE_SET_CODE (node, RSHIFT_EXPR);
12508           TREE_OPERAND (node, 0) = op1;
12509           TREE_OPERAND (node, 1) = op2;
12510           TREE_TYPE (node) = utype;
12511           to_return = convert (prom_type, node);
12512           /* Copy the original value of the COMPOUND_ASSIGN_P flag */
12513           COMPOUND_ASSIGN_P (to_return) = COMPOUND_ASSIGN_P (node);
12514           TREE_SIDE_EFFECTS (to_return)
12515             = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
12516           return to_return;
12517         }
12518       break;
12519
12520       /* 15.19.1 Type Comparison Operator instaceof */
12521     case INSTANCEOF_EXPR:
12522
12523       TREE_TYPE (node) = boolean_type_node;
12524
12525       if (!(op2_type = resolve_type_during_patch (op2)))
12526         return error_mark_node;
12527
12528       /* The first operand must be a reference type or the null type */
12529       if (!JREFERENCE_TYPE_P (op1_type) && op1 != null_pointer_node)
12530         error_found = 1;        /* Error reported further below */
12531
12532       /* The second operand must be a reference type */
12533       if (!JREFERENCE_TYPE_P (op2_type))
12534         {
12535           SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
12536           parse_error_context
12537             (wfl_operator, "Invalid argument `%s' for `instanceof'",
12538              lang_printable_name (op2_type, 0));
12539           error_found = 1;
12540         }
12541
12542       if (!error_found && valid_ref_assignconv_cast_p (op1_type, op2_type, 1))
12543         {
12544           /* If the first operand is null, the result is always false */
12545           if (op1 == null_pointer_node)
12546             return boolean_false_node;
12547           else if (flag_emit_class_files)
12548             {
12549               TREE_OPERAND (node, 1) = op2_type;
12550               TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1);
12551               return node;
12552             }
12553           /* Otherwise we have to invoke instance of to figure it out */
12554           else
12555             return build_instanceof (op1, op2_type);
12556         }
12557       /* There is no way the expression operand can be an instance of
12558          the type operand. This is a compile time error. */
12559       else
12560         {
12561           char *t1 = xstrdup (lang_printable_name (op1_type, 0));
12562           SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
12563           parse_error_context 
12564             (wfl_operator, "Impossible for `%s' to be instance of `%s'",
12565              t1, lang_printable_name (op2_type, 0));
12566           free (t1);
12567           error_found = 1;
12568         }
12569       
12570       break;
12571
12572       /* 15.21 Bitwise and Logical Operators */
12573     case BIT_AND_EXPR:
12574     case BIT_XOR_EXPR:
12575     case BIT_IOR_EXPR:
12576       if (JINTEGRAL_TYPE_P (op1_type) && JINTEGRAL_TYPE_P (op2_type))
12577         /* Binary numeric promotion is performed on both operand and the
12578            expression retain that type */
12579         prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12580
12581       else if (TREE_CODE (op1_type) == BOOLEAN_TYPE 
12582                && TREE_CODE (op1_type) == BOOLEAN_TYPE)
12583         /* The type of the bitwise operator expression is BOOLEAN */
12584         prom_type = boolean_type_node;
12585       else
12586         {
12587           if (!JINTEGRAL_TYPE_P (op1_type))
12588             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
12589           if (!JINTEGRAL_TYPE_P (op2_type) && (op1_type != op2_type))
12590             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op2_type);
12591           TREE_TYPE (node) = error_mark_node;
12592           error_found = 1;
12593           /* Insert a break here if adding thing before the switch's
12594              break for this case */
12595         }
12596       break;
12597
12598       /* 15.22 Conditional-And Operator */
12599     case TRUTH_ANDIF_EXPR:
12600       /* 15.23 Conditional-Or Operator */
12601     case TRUTH_ORIF_EXPR:
12602       /* Operands must be of BOOLEAN type */
12603       if (TREE_CODE (op1_type) != BOOLEAN_TYPE || 
12604           TREE_CODE (op2_type) != BOOLEAN_TYPE)
12605         {
12606           if (TREE_CODE (op1_type) != BOOLEAN_TYPE)
12607             ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op1_type);
12608           if (TREE_CODE (op2_type) != BOOLEAN_TYPE && (op1_type != op2_type))
12609             ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op2_type);
12610           TREE_TYPE (node) = boolean_type_node;
12611           error_found = 1;
12612           break;
12613         }
12614       /* The type of the conditional operators is BOOLEAN */
12615       prom_type = boolean_type_node;
12616       break;
12617
12618       /* 15.19.1 Numerical Comparison Operators <, <=, >, >= */
12619     case LT_EXPR:
12620     case GT_EXPR:
12621     case LE_EXPR:
12622     case GE_EXPR:
12623       /* The type of each of the operands must be a primitive numeric
12624          type */
12625       if (!JNUMERIC_TYPE_P (op1_type) || ! JNUMERIC_TYPE_P (op2_type))
12626         {
12627           if (!JNUMERIC_TYPE_P (op1_type))
12628             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
12629           if (!JNUMERIC_TYPE_P (op2_type) && (op1_type != op2_type))
12630             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
12631           TREE_TYPE (node) = boolean_type_node;
12632           error_found = 1;
12633           break;
12634         }
12635       /* Binary numeric promotion is performed on the operands */
12636       binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12637       /* The type of the relation expression is always BOOLEAN */
12638       prom_type = boolean_type_node;
12639       break;
12640
12641       /* 15.20 Equality Operator */
12642     case EQ_EXPR:
12643     case NE_EXPR:
12644       /* It's time for us to patch the strings. */
12645       if ((cn = patch_string (op1))) 
12646        {
12647          op1 = cn;
12648          op1_type = TREE_TYPE (op1);
12649        }
12650       if ((cn = patch_string (op2))) 
12651        {
12652          op2 = cn;
12653          op2_type = TREE_TYPE (op2);
12654        }
12655       
12656       /* 15.20.1 Numerical Equality Operators == and != */
12657       /* Binary numeric promotion is performed on the operands */
12658       if (JNUMERIC_TYPE_P (op1_type) && JNUMERIC_TYPE_P (op2_type))
12659         binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12660       
12661       /* 15.20.2 Boolean Equality Operators == and != */
12662       else if (TREE_CODE (op1_type) == BOOLEAN_TYPE &&
12663           TREE_CODE (op2_type) == BOOLEAN_TYPE)
12664         ;                       /* Nothing to do here */
12665       
12666       /* 15.20.3 Reference Equality Operators == and != */
12667       /* Types have to be either references or the null type. If
12668          they're references, it must be possible to convert either
12669          type to the other by casting conversion. */
12670       else if (op1 == null_pointer_node || op2 == null_pointer_node 
12671                || (JREFERENCE_TYPE_P (op1_type) && JREFERENCE_TYPE_P (op2_type)
12672                    && (valid_ref_assignconv_cast_p (op1_type, op2_type, 1)
12673                        || valid_ref_assignconv_cast_p (op2_type, 
12674                                                        op1_type, 1))))
12675         ;                       /* Nothing to do here */
12676           
12677       /* Else we have an error figure what can't be converted into
12678          what and report the error */
12679       else
12680         {
12681           char *t1;
12682           t1 = xstrdup (lang_printable_name (op1_type, 0));
12683           parse_error_context 
12684             (wfl_operator,
12685              "Incompatible type for `%s'. Can't convert `%s' to `%s'",
12686              operator_string (node), t1, 
12687              lang_printable_name (op2_type, 0));
12688           free (t1);
12689           TREE_TYPE (node) = boolean_type_node;
12690           error_found = 1;
12691           break;
12692         }
12693       prom_type = boolean_type_node;
12694       break;
12695     }
12696
12697   if (error_found)
12698     return error_mark_node;
12699
12700   TREE_OPERAND (node, 0) = op1;
12701   TREE_OPERAND (node, 1) = op2;
12702   TREE_TYPE (node) = prom_type;
12703   TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
12704   
12705   if (flag_emit_xref)
12706     return node;
12707
12708   /* fold does not respect side-effect order as required for Java but not C.
12709    * Also, it sometimes create SAVE_EXPRs which are bad when emitting
12710    * bytecode.
12711    */
12712   if (flag_emit_class_files ? (TREE_CONSTANT (op1) && TREE_CONSTANT (op2))
12713       : ! TREE_SIDE_EFFECTS (node))
12714     node = fold (node);
12715   return node;
12716 }
12717
12718 /* Concatenate the STRING_CST CSTE and STRING. When AFTER is a non
12719    zero value, the value of CSTE comes after the valude of STRING */
12720
12721 static tree
12722 do_merge_string_cste (cste, string, string_len, after)
12723      tree cste;
12724      const char *string;
12725      int string_len, after;
12726 {
12727   int len = TREE_STRING_LENGTH (cste) + string_len;
12728   const char *old = TREE_STRING_POINTER (cste);
12729   TREE_STRING_LENGTH (cste) = len;
12730   TREE_STRING_POINTER (cste) = obstack_alloc (expression_obstack, len+1);
12731   if (after)
12732     {
12733       strcpy (TREE_STRING_POINTER (cste), string);
12734       strcat (TREE_STRING_POINTER (cste), old);
12735     }
12736   else
12737     {
12738       strcpy (TREE_STRING_POINTER (cste), old);
12739       strcat (TREE_STRING_POINTER (cste), string);
12740     }
12741   return cste;
12742 }
12743
12744 /* Tries to merge OP1 (a STRING_CST) and OP2 (if suitable). Return a
12745    new STRING_CST on success, NULL_TREE on failure */
12746
12747 static tree
12748 merge_string_cste (op1, op2, after)
12749      tree op1, op2;
12750      int after;
12751 {
12752   /* Handle two string constants right away */
12753   if (TREE_CODE (op2) == STRING_CST)
12754     return do_merge_string_cste (op1, TREE_STRING_POINTER (op2), 
12755                                  TREE_STRING_LENGTH (op2), after);
12756   
12757   /* Reasonable integer constant can be treated right away */
12758   if (TREE_CODE (op2) == INTEGER_CST && !TREE_CONSTANT_OVERFLOW (op2))
12759     {
12760       static const char *boolean_true = "true";
12761       static const char *boolean_false = "false";
12762       static const char *null_pointer = "null";
12763       char ch[3];
12764       const char *string;
12765       
12766       if (op2 == boolean_true_node)
12767         string = boolean_true;
12768       else if (op2 == boolean_false_node)
12769         string = boolean_false;
12770       else if (op2 == null_pointer_node)
12771         string = null_pointer;
12772       else if (TREE_TYPE (op2) == char_type_node)
12773         {
12774           ch[0] = (char )TREE_INT_CST_LOW (op2);
12775           ch[1] = '\0';
12776           string = ch;
12777         }
12778       else
12779           string = print_int_node (op2);
12780       
12781       return do_merge_string_cste (op1, string, strlen (string), after);
12782     }
12783   return NULL_TREE;
12784 }
12785
12786 /* Tries to statically concatenate OP1 and OP2 if possible. Either one
12787    has to be a STRING_CST and the other part must be a STRING_CST or a
12788    INTEGRAL constant. Return a new STRING_CST if the operation
12789    succeed, NULL_TREE otherwise.
12790
12791    If the case we want to optimize for space, we might want to return
12792    NULL_TREE for each invocation of this routine. FIXME */
12793
12794 static tree
12795 string_constant_concatenation (op1, op2)
12796      tree op1, op2;
12797 {
12798   if (TREE_CODE (op1) == STRING_CST || (TREE_CODE (op2) == STRING_CST))
12799     {
12800       tree string, rest;
12801       int invert;
12802       
12803       string = (TREE_CODE (op1) == STRING_CST ? op1 : op2);
12804       rest   = (string == op1 ? op2 : op1);
12805       invert = (string == op1 ? 0 : 1 );
12806       
12807       /* Walk REST, only if it looks reasonable */
12808       if (TREE_CODE (rest) != STRING_CST
12809           && !IS_CRAFTED_STRING_BUFFER_P (rest)
12810           && !JSTRING_TYPE_P (TREE_TYPE (rest))
12811           && TREE_CODE (rest) == EXPR_WITH_FILE_LOCATION)
12812         {
12813           rest = java_complete_tree (rest);
12814           if (rest == error_mark_node)
12815             return error_mark_node;
12816           rest = fold (rest);
12817         }
12818       return merge_string_cste (string, rest, invert);
12819     }
12820   return NULL_TREE;
12821 }
12822
12823 /* Implement the `+' operator. Does static optimization if possible,
12824    otherwise create (if necessary) and append elements to a
12825    StringBuffer. The StringBuffer will be carried around until it is
12826    used for a function call or an assignment. Then toString() will be
12827    called on it to turn it into a String object. */
12828
12829 static tree
12830 build_string_concatenation (op1, op2)
12831      tree op1, op2;
12832 {
12833   tree result;
12834   int side_effects = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
12835
12836   if (flag_emit_xref)
12837     return build (PLUS_EXPR, string_type_node, op1, op2);
12838   
12839   /* Try to do some static optimization */
12840   if ((result = string_constant_concatenation (op1, op2)))
12841     return result;
12842
12843   /* Discard empty strings on either side of the expression */
12844   if (TREE_CODE (op1) == STRING_CST && TREE_STRING_LENGTH (op1) == 0)
12845     {
12846       op1 = op2;
12847       op2 = NULL_TREE;
12848     }
12849   else if (TREE_CODE (op2) == STRING_CST && TREE_STRING_LENGTH (op2) == 0)
12850     op2 = NULL_TREE;
12851
12852   /* If operands are string constant, turn then into object references */
12853   if (TREE_CODE (op1) == STRING_CST)
12854     op1 = patch_string_cst (op1);
12855   if (op2 && TREE_CODE (op2) == STRING_CST)
12856     op2 = patch_string_cst (op2);
12857
12858   /* If either one of the constant is null and the other non null
12859      operand is a String object, return it. */
12860   if (JSTRING_TYPE_P (TREE_TYPE (op1)) && !op2)
12861     return op1;
12862
12863   /* If OP1 isn't already a StringBuffer, create and
12864      initialize a new one */
12865   if (!IS_CRAFTED_STRING_BUFFER_P (op1))
12866     {
12867       /* Two solutions here: 
12868          1) OP1 is a constant string reference, we call new StringBuffer(OP1)
12869          2) OP1 is something else, we call new StringBuffer().append(OP1).  */
12870       if (TREE_CONSTANT (op1) && JSTRING_TYPE_P (TREE_TYPE (op1)))
12871         op1 = BUILD_STRING_BUFFER (op1);
12872       else
12873         {
12874           tree aNew = BUILD_STRING_BUFFER (NULL_TREE);
12875           op1 = make_qualified_primary (aNew, BUILD_APPEND (op1), 0);
12876         }
12877     }
12878
12879   if (op2)
12880     {
12881       /* OP1 is no longer the last node holding a crafted StringBuffer */
12882       IS_CRAFTED_STRING_BUFFER_P (op1) = 0;
12883       /* Create a node for `{new...,xxx}.append (op2)' */
12884       if (op2)
12885         op1 = make_qualified_primary (op1, BUILD_APPEND (op2), 0);
12886     }
12887
12888   /* Mark the last node holding a crafted StringBuffer */
12889   IS_CRAFTED_STRING_BUFFER_P (op1) = 1;
12890
12891   TREE_SIDE_EFFECTS (op1) = side_effects;
12892   return op1;
12893 }
12894
12895 /* Patch the string node NODE. NODE can be a STRING_CST of a crafted
12896    StringBuffer. If no string were found to be patched, return
12897    NULL. */
12898
12899 static tree
12900 patch_string (node)
12901     tree node;
12902 {
12903   if (node == error_mark_node)
12904     return error_mark_node;
12905   if (TREE_CODE (node) == STRING_CST)
12906     return patch_string_cst (node);
12907   else if (IS_CRAFTED_STRING_BUFFER_P (node))
12908     {
12909       int saved = ctxp->explicit_constructor_p;
12910       tree invoke = build_method_invocation (wfl_to_string, NULL_TREE);
12911       tree ret;
12912       /* Temporary disable forbid the use of `this'. */
12913       ctxp->explicit_constructor_p = 0;
12914       ret = java_complete_tree (make_qualified_primary (node, invoke, 0));
12915       /* String concatenation arguments must be evaluated in order too. */
12916       ret = force_evaluation_order (ret);
12917       /* Restore it at its previous value */
12918       ctxp->explicit_constructor_p = saved;
12919       return ret;
12920     }
12921   return NULL_TREE;
12922 }
12923
12924 /* Build the internal representation of a string constant.  */
12925
12926 static tree
12927 patch_string_cst (node)
12928      tree node;
12929 {
12930   int location;
12931   if (! flag_emit_class_files)
12932     {
12933       push_obstacks (&permanent_obstack, &permanent_obstack);
12934       node = get_identifier (TREE_STRING_POINTER (node));
12935       location = alloc_name_constant (CONSTANT_String, node);
12936       node = build_ref_from_constant_pool (location);
12937       pop_obstacks ();
12938     }
12939   TREE_TYPE (node) = string_ptr_type_node;
12940   TREE_CONSTANT (node) = 1;
12941   return node;
12942 }
12943
12944 /* Build an incomplete unary operator expression. */
12945
12946 static tree
12947 build_unaryop (op_token, op_location, op1)
12948      int op_token, op_location;
12949      tree op1;
12950 {
12951   enum tree_code op;
12952   tree unaryop;
12953   switch (op_token)
12954     {
12955     case PLUS_TK: op = UNARY_PLUS_EXPR; break;
12956     case MINUS_TK: op = NEGATE_EXPR; break;
12957     case NEG_TK: op = TRUTH_NOT_EXPR; break;
12958     case NOT_TK: op = BIT_NOT_EXPR; break;
12959     default: fatal ("Unknown token `%d' for unary operator - build_unaryop",
12960                     op_token);
12961     }
12962
12963   unaryop = build1 (op, NULL_TREE, op1);
12964   TREE_SIDE_EFFECTS (unaryop) = 1;
12965   /* Store the location of the operator, for better error report. The
12966      string of the operator will be rebuild based on the OP value. */
12967   EXPR_WFL_LINECOL (unaryop) = op_location;
12968   return unaryop;
12969 }
12970
12971 /* Special case for the ++/-- operators, since they require an extra
12972    argument to build, which is set to NULL and patched
12973    later. IS_POST_P is 1 if the operator, 0 otherwise.  */
12974
12975 static tree
12976 build_incdec (op_token, op_location, op1, is_post_p)
12977      int op_token, op_location;
12978      tree op1;
12979      int is_post_p;
12980 {
12981   static enum tree_code lookup [2][2] = 
12982     {
12983       { PREDECREMENT_EXPR, PREINCREMENT_EXPR, },
12984       { POSTDECREMENT_EXPR, POSTINCREMENT_EXPR, },
12985     };
12986   tree node = build (lookup [is_post_p][(op_token - DECR_TK)], 
12987                      NULL_TREE, op1, NULL_TREE);
12988   TREE_SIDE_EFFECTS (node) = 1;
12989   /* Store the location of the operator, for better error report. The
12990      string of the operator will be rebuild based on the OP value. */
12991   EXPR_WFL_LINECOL (node) = op_location;
12992   return node;
12993 }     
12994
12995 /* Build an incomplete cast operator, based on the use of the
12996    CONVERT_EXPR. Note that TREE_TYPE of the constructed node is
12997    set. java_complete_tree is trained to walk a CONVERT_EXPR even
12998    though its type is already set.  */
12999
13000 static tree
13001 build_cast (location, type, exp)
13002      int location;
13003      tree type, exp;
13004 {
13005   tree node = build1 (CONVERT_EXPR, type, exp);
13006   EXPR_WFL_LINECOL (node) = location;
13007   return node;
13008 }
13009
13010 /* Build an incomplete class reference operator.  */
13011 static tree
13012 build_incomplete_class_ref (location, class_name)
13013     int location;
13014     tree class_name;
13015 {
13016   tree node = build1 (CLASS_LITERAL, NULL_TREE, class_name);
13017   EXPR_WFL_LINECOL (node) = location;
13018   return node;
13019 }
13020
13021 /* Complete an incomplete class reference operator.  */
13022 static tree
13023 patch_incomplete_class_ref (node)
13024     tree node;
13025 {
13026   tree type = TREE_OPERAND (node, 0);
13027   tree ref_type;
13028
13029   if (!(ref_type = resolve_type_during_patch (type)))
13030     return error_mark_node;
13031
13032   if (!flag_emit_class_files || JPRIMITIVE_TYPE_P (ref_type))
13033     {
13034       /* A class referenced by `foo.class' is initialized.  */
13035       return build_class_init (ref_type, build_class_ref (ref_type));
13036     }
13037
13038   /* If we're emitting class files and we have to deal with non
13039      primitive types, we invoke (and consider generating) the
13040      synthetic static method `class$'. */
13041   if (!TYPE_DOT_CLASS (current_class))
13042       build_dot_class_method (current_class);
13043   ref_type = 
13044     build_dot_class_method_invocation (DECL_NAME (TYPE_NAME (ref_type)));
13045   return java_complete_tree (ref_type);
13046 }
13047
13048 /* 15.14 Unary operators. We return error_mark_node in case of error,
13049    but preserve the type of NODE if the type is fixed.  */
13050
13051 static tree
13052 patch_unaryop (node, wfl_op)
13053      tree node;
13054      tree wfl_op;
13055 {
13056   tree op = TREE_OPERAND (node, 0);
13057   tree op_type = TREE_TYPE (op);
13058   tree prom_type = NULL_TREE, value, decl;
13059   int outer_field_flag = 0;
13060   int code = TREE_CODE (node);
13061   int error_found = 0;
13062
13063   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13064
13065   switch (code)
13066     {
13067       /* 15.13.2 Postfix Increment Operator ++ */
13068     case POSTINCREMENT_EXPR:
13069       /* 15.13.3 Postfix Increment Operator -- */
13070     case POSTDECREMENT_EXPR:
13071       /* 15.14.1 Prefix Increment Operator ++ */
13072     case PREINCREMENT_EXPR:
13073       /* 15.14.2 Prefix Decrement Operator -- */
13074     case PREDECREMENT_EXPR:
13075       op = decl = strip_out_static_field_access_decl (op);
13076       outer_field_flag = outer_field_expanded_access_p (op, NULL, NULL, NULL);
13077       /* We might be trying to change an outer field accessed using
13078          access method. */
13079       if (outer_field_flag)
13080         {
13081           /* Retrieve the decl of the field we're trying to access. We
13082              do that by first retrieving the function we would call to
13083              access the field. It has been already verified that this
13084              field isn't final */
13085           if (flag_emit_class_files)
13086             decl = TREE_OPERAND (op, 0);
13087           else
13088             decl = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (op, 0), 0), 0);
13089           decl = DECL_FUNCTION_ACCESS_DECL (decl);
13090         }
13091       /* We really should have a JAVA_ARRAY_EXPR to avoid this */
13092       else if (!JDECL_P (decl) 
13093           && TREE_CODE (decl) != COMPONENT_REF
13094           && !(flag_emit_class_files && TREE_CODE (decl) == ARRAY_REF)
13095           && TREE_CODE (decl) != INDIRECT_REF
13096           && !(TREE_CODE (decl) == COMPOUND_EXPR
13097                && TREE_OPERAND (decl, 1)
13098                && (TREE_CODE (TREE_OPERAND (decl, 1)) == INDIRECT_REF)))
13099         {
13100           tree lvalue;
13101           /* Before screaming, check that we're not in fact trying to
13102              increment a optimized static final access, in which case
13103              we issue an different error message. */
13104           if (!(TREE_CODE (wfl_op) == EXPR_WITH_FILE_LOCATION
13105                 && resolve_expression_name (wfl_op, &lvalue)
13106                 && check_final_assignment (lvalue, wfl_op)))
13107             parse_error_context (wfl_operator, "Invalid argument to `%s'",
13108                                  operator_string (node));
13109           TREE_TYPE (node) = error_mark_node;
13110           error_found = 1;
13111         }
13112       
13113       if (check_final_assignment (op, wfl_op))
13114         error_found = 1;
13115
13116       /* From now on, we know that op if a variable and that it has a
13117          valid wfl. We use wfl_op to locate errors related to the
13118          ++/-- operand. */
13119       else if (!JNUMERIC_TYPE_P (op_type))
13120         {
13121           parse_error_context
13122             (wfl_op, "Invalid argument type `%s' to `%s'",
13123              lang_printable_name (op_type, 0), operator_string (node));
13124           TREE_TYPE (node) = error_mark_node;
13125           error_found = 1;
13126         }
13127       else
13128         {
13129           /* Before the addition, binary numeric promotion is performed on
13130              both operands, if really necessary */
13131           if (JINTEGRAL_TYPE_P (op_type))
13132             {
13133               value = build_int_2 (1, 0);
13134               TREE_TYPE (value) = TREE_TYPE (node) = op_type;
13135             }
13136           else
13137             {
13138               value = build_int_2 (1, 0);
13139               TREE_TYPE (node) = 
13140                 binary_numeric_promotion (op_type, 
13141                                           TREE_TYPE (value), &op, &value);
13142             }
13143
13144           /* We remember we might be accessing an outer field */
13145           if (outer_field_flag)
13146             {
13147               /* We re-generate an access to the field */
13148               value = build (PLUS_EXPR, TREE_TYPE (op), 
13149                              build_outer_field_access (wfl_op, decl), value);
13150                                                     
13151               /* And we patch the original access$() into a write 
13152                  with plus_op as a rhs */
13153               return outer_field_access_fix (node, op, value);
13154             }
13155
13156           /* And write back into the node. */
13157           TREE_OPERAND (node, 0) = op;
13158           TREE_OPERAND (node, 1) = value;
13159           /* Convert the overall back into its original type, if
13160              necessary, and return */
13161           if (JINTEGRAL_TYPE_P (op_type))
13162             return fold (node);
13163           else
13164             return fold (convert (op_type, node));
13165         }
13166       break;
13167
13168       /* 15.14.3 Unary Plus Operator + */
13169     case UNARY_PLUS_EXPR:
13170       /* 15.14.4 Unary Minus Operator - */
13171     case NEGATE_EXPR:
13172       if (!JNUMERIC_TYPE_P (op_type))
13173         {
13174           ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op_type);
13175           TREE_TYPE (node) = error_mark_node;
13176           error_found = 1;
13177         }
13178       /* Unary numeric promotion is performed on operand */
13179       else
13180         {
13181           op = do_unary_numeric_promotion (op);
13182           prom_type = TREE_TYPE (op);
13183           if (code == UNARY_PLUS_EXPR)
13184             return fold (op);
13185         }
13186       break;
13187
13188       /* 15.14.5 Bitwise Complement Operator ~ */
13189     case BIT_NOT_EXPR:
13190       if (!JINTEGRAL_TYPE_P (op_type))
13191         {
13192           ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op_type);
13193           TREE_TYPE (node) = error_mark_node;
13194           error_found = 1;
13195         }
13196       else
13197         {
13198           op = do_unary_numeric_promotion (op);
13199           prom_type = TREE_TYPE (op);
13200         }
13201       break;
13202
13203       /* 15.14.6 Logical Complement Operator ! */
13204     case TRUTH_NOT_EXPR:
13205       if (TREE_CODE (op_type) != BOOLEAN_TYPE)
13206         {
13207           ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op_type);
13208           /* But the type is known. We will report an error if further
13209              attempt of a assignment is made with this rhs */
13210           TREE_TYPE (node) = boolean_type_node;
13211           error_found = 1;
13212         }
13213       else
13214         prom_type = boolean_type_node;
13215       break;
13216
13217       /* 15.15 Cast Expression */
13218     case CONVERT_EXPR:
13219       value = patch_cast (node, wfl_operator);
13220       if (value == error_mark_node)
13221         {
13222           /* If this cast is part of an assignment, we tell the code
13223              that deals with it not to complain about a mismatch,
13224              because things have been cast, anyways */
13225           TREE_TYPE (node) = error_mark_node;
13226           error_found = 1;
13227         }
13228       else
13229         {
13230           value = fold (value);
13231           TREE_SIDE_EFFECTS (value) = TREE_SIDE_EFFECTS (op);
13232           return value;
13233         }
13234       break;
13235     }
13236   
13237   if (error_found)
13238     return error_mark_node;
13239
13240   /* There are cases where node has been replaced by something else
13241      and we don't end up returning here: UNARY_PLUS_EXPR,
13242      CONVERT_EXPR, {POST,PRE}{INCR,DECR}EMENT_EXPR. */
13243   TREE_OPERAND (node, 0) = fold (op);
13244   TREE_TYPE (node) = prom_type;
13245   TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op);
13246   return fold (node);
13247 }
13248
13249 /* Generic type resolution that sometimes takes place during node
13250    patching. Returned the resolved type or generate an error
13251    message. Return the resolved type or NULL_TREE.  */
13252
13253 static tree
13254 resolve_type_during_patch (type)
13255      tree type;
13256 {
13257   if (unresolved_type_p (type, NULL))
13258     {
13259       tree type_decl = resolve_no_layout (EXPR_WFL_NODE (type), NULL_TREE);
13260       if (!type_decl)
13261         {
13262           parse_error_context (type, 
13263                                "Class `%s' not found in type declaration",
13264                                IDENTIFIER_POINTER (EXPR_WFL_NODE (type)));
13265           return NULL_TREE;
13266         }
13267       else
13268         {
13269           CLASS_LOADED_P (TREE_TYPE (type_decl)) = 1;
13270           return TREE_TYPE (type_decl);
13271         }
13272     }
13273   return type;
13274 }
13275 /* 5.5 Casting Conversion. error_mark_node is returned if an error is
13276    found. Otherwise NODE or something meant to replace it is returned.  */
13277
13278 static tree
13279 patch_cast (node, wfl_operator)
13280      tree node;
13281      tree wfl_operator;
13282 {
13283   tree op = TREE_OPERAND (node, 0);
13284   tree op_type = TREE_TYPE (op);
13285   tree cast_type = TREE_TYPE (node);
13286   char *t1;
13287
13288   /* First resolve OP_TYPE if unresolved */
13289   if (!(cast_type = resolve_type_during_patch (cast_type)))
13290     return error_mark_node;
13291
13292   /* Check on cast that are proven correct at compile time */
13293   if (JNUMERIC_TYPE_P (cast_type) && JNUMERIC_TYPE_P (op_type))
13294     {
13295       /* Same type */
13296       if (cast_type == op_type)
13297         return node;
13298
13299       /* float and double type are converted to the original type main
13300          variant and then to the target type. */
13301       if (JFLOAT_TYPE_P (op_type) && TREE_CODE (cast_type) == CHAR_TYPE)
13302         op = convert (integer_type_node, op);
13303
13304       /* Try widening/narowwing convertion. Potentially, things need
13305          to be worked out in gcc so we implement the extreme cases
13306          correctly. fold_convert() needs to be fixed. */
13307       return convert (cast_type, op);
13308     }
13309
13310   /* It's also valid to cast a boolean into a boolean */
13311   if (op_type == boolean_type_node && cast_type == boolean_type_node)
13312     return node;
13313
13314   /* null can be casted to references */
13315   if (op == null_pointer_node && JREFERENCE_TYPE_P (cast_type))
13316     return build_null_of_type (cast_type);
13317
13318   /* The remaining legal casts involve conversion between reference
13319      types. Check for their compile time correctness. */
13320   if (JREFERENCE_TYPE_P (op_type) && JREFERENCE_TYPE_P (cast_type) 
13321       && valid_ref_assignconv_cast_p (op_type, cast_type, 1))
13322     {
13323       TREE_TYPE (node) = promote_type (cast_type);
13324       /* Now, the case can be determined correct at compile time if
13325          OP_TYPE can be converted into CAST_TYPE by assignment
13326          conversion (5.2) */
13327
13328       if (valid_ref_assignconv_cast_p (op_type, cast_type, 0))
13329         {
13330           TREE_SET_CODE (node, NOP_EXPR);
13331           return node;
13332         }
13333
13334       if (flag_emit_class_files)
13335         {
13336           TREE_SET_CODE (node, CONVERT_EXPR);
13337           return node;
13338         }
13339
13340       /* The cast requires a run-time check */
13341       return build (CALL_EXPR, promote_type (cast_type),
13342                     build_address_of (soft_checkcast_node),
13343                     tree_cons (NULL_TREE, build_class_ref (cast_type),
13344                                build_tree_list (NULL_TREE, op)),
13345                     NULL_TREE);
13346     }
13347
13348   /* Any other casts are proven incorrect at compile time */
13349   t1 = xstrdup (lang_printable_name (op_type, 0));
13350   parse_error_context (wfl_operator, "Invalid cast from `%s' to `%s'",
13351                        t1, lang_printable_name (cast_type, 0));
13352   free (t1);
13353   return error_mark_node;
13354 }
13355
13356 /* Build a null constant and give it the type TYPE.  */
13357
13358 static tree
13359 build_null_of_type (type)
13360      tree type;
13361 {
13362   tree node = build_int_2 (0, 0);
13363   TREE_TYPE (node) = promote_type (type);
13364   return node;
13365 }
13366
13367 /* Build an ARRAY_REF incomplete tree node. Note that operand 1 isn't
13368    a list of indices. */
13369 static tree
13370 build_array_ref (location, array, index)
13371      int location;
13372      tree array, index;
13373 {
13374   tree node = build (ARRAY_REF, NULL_TREE, array, index);
13375   EXPR_WFL_LINECOL (node) = location;
13376   return node;
13377 }
13378
13379 /* 15.12 Array Access Expression */
13380
13381 static tree
13382 patch_array_ref (node)
13383      tree node;
13384 {
13385   tree array = TREE_OPERAND (node, 0);
13386   tree array_type  = TREE_TYPE (array);
13387   tree index = TREE_OPERAND (node, 1);
13388   tree index_type = TREE_TYPE (index);
13389   int error_found = 0;
13390
13391   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13392
13393   if (TREE_CODE (array_type) == POINTER_TYPE)
13394     array_type = TREE_TYPE (array_type);
13395
13396   /* The array reference must be an array */
13397   if (!TYPE_ARRAY_P (array_type))
13398     {
13399       parse_error_context 
13400         (wfl_operator,
13401          "`[]' can only be applied to arrays. It can't be applied to `%s'",
13402          lang_printable_name (array_type, 0));
13403       TREE_TYPE (node) = error_mark_node;
13404       error_found = 1;
13405     }
13406
13407   /* The array index undergoes unary numeric promotion. The promoted
13408      type must be int */
13409   index = do_unary_numeric_promotion (index);
13410   if (TREE_TYPE (index) != int_type_node)
13411     {
13412       if (valid_cast_to_p (index_type, int_type_node))
13413         parse_error_context (wfl_operator,
13414    "Incompatible type for `[]'. Explicit cast needed to convert `%s' to `int'",
13415                              lang_printable_name (index_type, 0));
13416       else
13417         parse_error_context (wfl_operator,
13418           "Incompatible type for `[]'. Can't convert `%s' to `int'",
13419                              lang_printable_name (index_type, 0));
13420       TREE_TYPE (node) = error_mark_node;
13421       error_found = 1;
13422     }
13423
13424   if (error_found)
13425     return error_mark_node;
13426
13427   array_type = TYPE_ARRAY_ELEMENT (array_type);
13428
13429   if (flag_emit_class_files || flag_emit_xref)
13430     {
13431       TREE_OPERAND (node, 0) = array;
13432       TREE_OPERAND (node, 1) = index;
13433     }
13434   else
13435     {
13436       /* The save_expr is for correct evaluation order.  It would be cleaner
13437          to use force_evaluation_order (see comment there), but that is
13438          difficult when we also have to deal with bounds checking. */
13439       if (TREE_SIDE_EFFECTS (index))
13440         array = save_expr (array);
13441       node = build_java_arrayaccess (array, array_type, index);
13442       if (TREE_SIDE_EFFECTS (index))
13443         node = build (COMPOUND_EXPR, array_type, array, node);
13444     }
13445   TREE_TYPE (node) = array_type;
13446   return node;
13447 }
13448
13449 /* 15.9 Array Creation Expressions */
13450
13451 static tree
13452 build_newarray_node (type, dims, extra_dims)
13453      tree type;
13454      tree dims;
13455      int extra_dims;
13456 {
13457   tree node =
13458     build (NEW_ARRAY_EXPR, NULL_TREE, type, nreverse (dims), 
13459            build_int_2 (extra_dims, 0));
13460   return node;
13461 }
13462
13463 static tree
13464 patch_newarray (node)
13465      tree node;
13466 {
13467   tree type = TREE_OPERAND (node, 0);
13468   tree dims = TREE_OPERAND (node, 1);
13469   tree cdim, array_type;
13470   int error_found = 0;
13471   int ndims = 0;
13472   int xdims = TREE_INT_CST_LOW (TREE_OPERAND (node, 2));
13473
13474   /* Dimension types are verified. It's better for the types to be
13475      verified in order. */
13476   for (cdim = dims, ndims = 0; cdim; cdim = TREE_CHAIN (cdim), ndims++ )
13477     {
13478       int dim_error = 0;
13479       tree dim = TREE_VALUE (cdim);
13480
13481       /* Dim might have been saved during its evaluation */
13482       dim = (TREE_CODE (dim) == SAVE_EXPR ? dim = TREE_OPERAND (dim, 0) : dim);
13483
13484       /* The type of each specified dimension must be an integral type. */
13485       if (!JINTEGRAL_TYPE_P (TREE_TYPE (dim)))
13486         dim_error = 1;
13487
13488       /* Each expression undergoes an unary numeric promotion (5.6.1) and the
13489          promoted type must be int. */
13490       else
13491         {
13492           dim = do_unary_numeric_promotion (dim);
13493           if (TREE_TYPE (dim) != int_type_node)
13494             dim_error = 1;
13495         }
13496
13497       /* Report errors on types here */
13498       if (dim_error)
13499         {
13500           parse_error_context 
13501             (TREE_PURPOSE (cdim), 
13502              "Incompatible type for dimension in array creation expression. %s convert `%s' to `int'", 
13503              (valid_cast_to_p (TREE_TYPE (dim), int_type_node) ?
13504               "Explicit cast needed to" : "Can't"),
13505              lang_printable_name (TREE_TYPE (dim), 0));
13506           error_found = 1;
13507         }
13508
13509       TREE_PURPOSE (cdim) = NULL_TREE;
13510     }
13511
13512   /* Resolve array base type if unresolved */
13513   if (!(type = resolve_type_during_patch (type)))
13514     error_found = 1;
13515
13516   if (error_found)
13517     {
13518       /* We don't want further evaluation of this bogus array creation
13519          operation */
13520       TREE_TYPE (node) = error_mark_node;
13521       return error_mark_node;
13522     }
13523
13524   /* Set array_type to the actual (promoted) array type of the result. */
13525   if (TREE_CODE (type) == RECORD_TYPE)
13526     type = build_pointer_type (type);
13527   while (--xdims >= 0)
13528     {
13529       type = promote_type (build_java_array_type (type, -1));
13530     }
13531   dims = nreverse (dims);
13532   array_type = type;
13533   for (cdim = dims; cdim; cdim = TREE_CHAIN (cdim))
13534     {
13535       type = array_type;
13536       array_type
13537         = build_java_array_type (type,
13538                                  TREE_CODE (cdim) == INTEGER_CST
13539                                  ? (HOST_WIDE_INT) TREE_INT_CST_LOW (cdim)
13540                                  : -1);
13541       array_type = promote_type (array_type);
13542     }
13543   dims = nreverse (dims);
13544
13545   /* The node is transformed into a function call. Things are done
13546      differently according to the number of dimensions. If the number
13547      of dimension is equal to 1, then the nature of the base type
13548      (primitive or not) matters. */
13549   if (ndims == 1)
13550     return build_new_array (type, TREE_VALUE (dims));
13551   
13552   /* Can't reuse what's already written in expr.c because it uses the
13553      JVM stack representation. Provide a build_multianewarray. FIXME */
13554   return build (CALL_EXPR, array_type,
13555                 build_address_of (soft_multianewarray_node),
13556                 tree_cons (NULL_TREE, build_class_ref (TREE_TYPE (array_type)),
13557                            tree_cons (NULL_TREE, 
13558                                       build_int_2 (ndims, 0), dims )),
13559                 NULL_TREE);
13560 }
13561
13562 /* 10.6 Array initializer.  */
13563
13564 /* Build a wfl for array element that don't have one, so we can
13565    pin-point errors.  */
13566
13567 static tree
13568 maybe_build_array_element_wfl (node)
13569      tree node;
13570 {
13571   if (TREE_CODE (node) != EXPR_WITH_FILE_LOCATION)
13572     return build_expr_wfl (NULL_TREE, ctxp->filename,
13573                            ctxp->elc.line, ctxp->elc.prev_col);
13574   else
13575     return NULL_TREE;
13576 }
13577
13578 /* Build a NEW_ARRAY_INIT that features a CONSTRUCTOR node. This makes
13579    identification of initialized arrays easier to detect during walk
13580    and expansion.  */
13581
13582 static tree
13583 build_new_array_init (location, values)
13584      int location;
13585      tree values;
13586 {
13587   tree constructor = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, values);
13588   tree to_return = build1 (NEW_ARRAY_INIT, NULL_TREE, constructor);
13589   EXPR_WFL_LINECOL (to_return) = location;
13590   return to_return;
13591 }
13592
13593 /* Expand a NEW_ARRAY_INIT node. Return error_mark_node if an error
13594    occurred.  Otherwise return NODE after having set its type
13595    appropriately.  */
13596
13597 static tree
13598 patch_new_array_init (type, node)
13599      tree type, node;
13600 {
13601   int error_seen = 0;
13602   tree current, element_type;
13603   HOST_WIDE_INT length;
13604   int all_constant = 1;
13605   tree init = TREE_OPERAND (node, 0);
13606
13607   if (TREE_CODE (type) != POINTER_TYPE || ! TYPE_ARRAY_P (TREE_TYPE (type)))
13608     {
13609       parse_error_context (node,
13610                            "Invalid array initializer for non-array type `%s'",
13611                            lang_printable_name (type, 1));
13612       return error_mark_node;
13613     }
13614   type = TREE_TYPE (type);
13615   element_type = TYPE_ARRAY_ELEMENT (type);
13616
13617   CONSTRUCTOR_ELTS (init) = nreverse (CONSTRUCTOR_ELTS (init));
13618
13619   for (length = 0, current = CONSTRUCTOR_ELTS (init);
13620        current;  length++, current = TREE_CHAIN (current))
13621     {
13622       tree elt = TREE_VALUE (current);
13623       if (elt == NULL_TREE || TREE_CODE (elt) != NEW_ARRAY_INIT)
13624         {
13625           error_seen |= array_constructor_check_entry (element_type, current);
13626           elt = TREE_VALUE (current);
13627           /* When compiling to native code, STRING_CST is converted to
13628              INDIRECT_REF, but still with a TREE_CONSTANT flag. */
13629           if (! TREE_CONSTANT (elt) || TREE_CODE (elt) == INDIRECT_REF)
13630             all_constant = 0;
13631         }
13632       else
13633         {
13634           TREE_VALUE (current) = patch_new_array_init (element_type, elt);
13635           TREE_PURPOSE (current) = NULL_TREE;
13636           all_constant = 0;
13637         }
13638       if (elt && TREE_CODE (elt) == TREE_LIST 
13639           && TREE_VALUE (elt) == error_mark_node)
13640         error_seen = 1;
13641     }
13642
13643   if (error_seen)
13644     return error_mark_node;
13645
13646   /* Create a new type. We can't reuse the one we have here by
13647      patching its dimension because it originally is of dimension -1
13648      hence reused by gcc. This would prevent triangular arrays. */
13649   type = build_java_array_type (element_type, length);
13650   TREE_TYPE (init) = TREE_TYPE (TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (type))));
13651   TREE_TYPE (node) = promote_type (type);
13652   TREE_CONSTANT (init) = all_constant;
13653   TREE_CONSTANT (node) = all_constant;
13654   return node;
13655 }
13656
13657 /* Verify that one entry of the initializer element list can be
13658    assigned to the array base type. Report 1 if an error occurred, 0
13659    otherwise.  */
13660
13661 static int
13662 array_constructor_check_entry (type, entry)
13663      tree type, entry;
13664 {
13665   char *array_type_string = NULL;       /* For error reports */
13666   tree value, type_value, new_value, wfl_value, patched;
13667   int error_seen = 0;
13668
13669   new_value = NULL_TREE;
13670   wfl_value = TREE_VALUE (entry);
13671
13672   push_obstacks (&permanent_obstack, &permanent_obstack);
13673   value = java_complete_tree (TREE_VALUE (entry));
13674   /* patch_string return error_mark_node if arg is error_mark_node */
13675   if ((patched = patch_string (value)))
13676     value = patched;
13677   if (value == error_mark_node)
13678     return 1;
13679   
13680   type_value = TREE_TYPE (value);
13681   
13682   /* At anytime, try_builtin_assignconv can report a warning on
13683      constant overflow during narrowing. */
13684   SET_WFL_OPERATOR (wfl_operator, TREE_PURPOSE (entry), wfl_value);
13685   new_value = try_builtin_assignconv (wfl_operator, type, value);
13686   if (!new_value && (new_value = try_reference_assignconv (type, value)))
13687     type_value = promote_type (type);
13688
13689   pop_obstacks ();
13690   /* Check and report errors */
13691   if (!new_value)
13692     {
13693       const char *msg = (!valid_cast_to_p (type_value, type) ?
13694                    "Can't" : "Explicit cast needed to");
13695       if (!array_type_string)
13696         array_type_string = xstrdup (lang_printable_name (type, 1));
13697       parse_error_context 
13698         (wfl_operator, "Incompatible type for array. %s convert `%s' to `%s'",
13699          msg, lang_printable_name (type_value, 1), array_type_string);
13700       error_seen = 1;
13701     }
13702   
13703   if (new_value)
13704     {
13705       new_value = maybe_build_primttype_type_ref (new_value, wfl_value);
13706       TREE_VALUE (entry) = new_value;
13707     }
13708
13709   if (array_type_string)
13710     free (array_type_string);
13711
13712   TREE_PURPOSE (entry) = NULL_TREE;
13713   return error_seen;
13714 }
13715
13716 static tree
13717 build_this (location)
13718      int location;
13719 {
13720   tree node = build_wfl_node (this_identifier_node);
13721   TREE_SET_CODE (node, THIS_EXPR);
13722   EXPR_WFL_LINECOL (node) = location;
13723   return node;
13724 }
13725
13726 /* 14.15 The return statement. It builds a modify expression that
13727    assigns the returned value to the RESULT_DECL that hold the value
13728    to be returned. */
13729
13730 static tree
13731 build_return (location, op)
13732      int location;
13733      tree op;
13734 {
13735   tree node = build1 (RETURN_EXPR, NULL_TREE, op);
13736   EXPR_WFL_LINECOL (node) = location;
13737   node = build_debugable_stmt (location, node);
13738   return node;
13739 }
13740
13741 static tree
13742 patch_return (node)
13743      tree node;
13744 {
13745   tree return_exp = TREE_OPERAND (node, 0);
13746   tree meth = current_function_decl;
13747   tree mtype = TREE_TYPE (TREE_TYPE (current_function_decl));
13748   int error_found = 0;
13749
13750   TREE_TYPE (node) = error_mark_node;
13751   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13752
13753   /* It's invalid to have a return value within a function that is
13754      declared with the keyword void or that is a constructor */
13755   if (return_exp && (mtype == void_type_node || DECL_CONSTRUCTOR_P (meth)))
13756     error_found = 1;
13757
13758   /* It's invalid to use a return statement in a static block */
13759   if (DECL_CLINIT_P (current_function_decl))
13760     error_found = 1;
13761
13762   /* It's invalid to have a no return value within a function that
13763      isn't declared with the keyword `void' */
13764   if (!return_exp && (mtype != void_type_node && !DECL_CONSTRUCTOR_P (meth)))
13765     error_found = 2;
13766   
13767   if (in_instance_initializer)
13768     error_found = 1;
13769
13770   if (error_found)
13771     {
13772       if (in_instance_initializer)
13773         parse_error_context (wfl_operator,
13774                              "`return' inside instance initializer");
13775         
13776       else if (DECL_CLINIT_P (current_function_decl))
13777         parse_error_context (wfl_operator,
13778                              "`return' inside static initializer");
13779
13780       else if (!DECL_CONSTRUCTOR_P (meth))
13781         {
13782           char *t = xstrdup (lang_printable_name (mtype, 0));
13783           parse_error_context (wfl_operator, 
13784                                "`return' with%s value from `%s %s'",
13785                                (error_found == 1 ? "" : "out"), 
13786                                t, lang_printable_name (meth, 0));
13787           free (t);
13788         }
13789       else
13790         parse_error_context (wfl_operator, 
13791                              "`return' with value from constructor `%s'",
13792                              lang_printable_name (meth, 0));
13793       return error_mark_node;
13794     }
13795
13796   /* If we have a return_exp, build a modify expression and expand
13797      it. Note: at that point, the assignment is declared valid, but we
13798      may want to carry some more hacks */
13799   if (return_exp)
13800     {
13801       tree exp = java_complete_tree (return_exp);
13802       tree modify, patched;
13803
13804       /* If the function returned value and EXP are booleans, EXP has
13805       to be converted into the type of DECL_RESULT, which is integer
13806       (see complete_start_java_method) */
13807       if (TREE_TYPE (exp) == boolean_type_node &&
13808           TREE_TYPE (TREE_TYPE (meth)) == boolean_type_node)
13809         exp = convert_to_integer (TREE_TYPE (DECL_RESULT (meth)), exp);
13810
13811       /* `null' can be assigned to a function returning a reference */
13812       if (JREFERENCE_TYPE_P (TREE_TYPE (TREE_TYPE (meth))) &&
13813           exp == null_pointer_node)
13814         exp = build_null_of_type (TREE_TYPE (TREE_TYPE (meth)));
13815
13816       if ((patched = patch_string (exp)))
13817         exp = patched;
13818       
13819       modify = build (MODIFY_EXPR, NULL_TREE, DECL_RESULT (meth), exp);
13820       EXPR_WFL_LINECOL (modify) = EXPR_WFL_LINECOL (node);
13821       modify = java_complete_tree (modify);
13822
13823       if (modify != error_mark_node)
13824         {
13825           TREE_SIDE_EFFECTS (modify) = 1;
13826           TREE_OPERAND (node, 0) = modify;
13827         }
13828       else
13829         return error_mark_node;
13830     }
13831   TREE_TYPE (node) = void_type_node;
13832   TREE_SIDE_EFFECTS (node) = 1;
13833   return node;
13834 }
13835
13836 /* 14.8 The if Statement */
13837
13838 static tree
13839 build_if_else_statement (location, expression, if_body, else_body)
13840      int location;
13841      tree expression, if_body, else_body;
13842 {
13843   tree node;
13844   if (!else_body)
13845     else_body = empty_stmt_node;
13846   node = build (COND_EXPR, NULL_TREE, expression, if_body, else_body);
13847   EXPR_WFL_LINECOL (node) = location;
13848   node = build_debugable_stmt (location, node);
13849   return node;
13850 }
13851
13852 static tree
13853 patch_if_else_statement (node)
13854      tree node;
13855 {
13856   tree expression = TREE_OPERAND (node, 0);
13857
13858   TREE_TYPE (node) = error_mark_node;
13859   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13860
13861   /* The type of expression must be boolean */
13862   if (TREE_TYPE (expression) != boolean_type_node
13863       && TREE_TYPE (expression) != promoted_boolean_type_node)
13864     {
13865       parse_error_context 
13866         (wfl_operator, 
13867          "Incompatible type for `if'. Can't convert `%s' to `boolean'", 
13868          lang_printable_name (TREE_TYPE (expression), 0));
13869       return error_mark_node;
13870     }
13871   
13872   TREE_TYPE (node) = void_type_node;
13873   TREE_SIDE_EFFECTS (node) = 1;
13874   CAN_COMPLETE_NORMALLY (node)
13875     = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1))
13876     | CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 2));
13877   return node;
13878 }
13879
13880 /* 14.6 Labeled Statements */
13881
13882 /* Action taken when a lableled statement is parsed. a new
13883    LABELED_BLOCK_EXPR is created. No statement is attached to the
13884    label, yet.  LABEL can be NULL_TREE for artificially-generated blocks. */
13885
13886 static tree
13887 build_labeled_block (location, label)
13888      int location;
13889      tree label;
13890 {
13891   tree label_name ;
13892   tree label_decl, node;
13893   if (label == NULL_TREE || label == continue_identifier_node)
13894     label_name = label;
13895   else
13896     {
13897       label_name = merge_qualified_name (label_id, label);
13898       /* Issue an error if we try to reuse a label that was previously
13899          declared */
13900       if (IDENTIFIER_LOCAL_VALUE (label_name))
13901         {
13902           EXPR_WFL_LINECOL (wfl_operator) = location;
13903           parse_error_context (wfl_operator,
13904             "Declaration of `%s' shadows a previous label declaration",
13905                                IDENTIFIER_POINTER (label));
13906           EXPR_WFL_LINECOL (wfl_operator) = 
13907             EXPR_WFL_LINECOL (IDENTIFIER_LOCAL_VALUE (label_name));
13908           parse_error_context (wfl_operator,
13909             "This is the location of the previous declaration of label `%s'",
13910                                IDENTIFIER_POINTER (label));
13911           java_error_count--;
13912         }
13913     }
13914
13915   label_decl = create_label_decl (label_name);
13916   node = build (LABELED_BLOCK_EXPR, NULL_TREE, label_decl, NULL_TREE);
13917   EXPR_WFL_LINECOL (node) = location;
13918   TREE_SIDE_EFFECTS (node) = 1;
13919   return node;
13920 }
13921
13922 /* A labeled statement LBE is attached a statement.  */
13923
13924 static tree
13925 finish_labeled_statement (lbe, statement)
13926      tree lbe;                  /* Labeled block expr */
13927      tree statement;
13928 {
13929   /* In anyways, tie the loop to its statement */
13930   LABELED_BLOCK_BODY (lbe) = statement;
13931   pop_labeled_block ();
13932   POP_LABELED_BLOCK ();
13933   return lbe;
13934 }
13935
13936 /* 14.10, 14.11, 14.12 Loop Statements */
13937
13938 /* Create an empty LOOP_EXPR and make it the last in the nested loop
13939    list. */
13940
13941 static tree
13942 build_new_loop (loop_body)
13943      tree loop_body;
13944 {
13945   tree loop =  build (LOOP_EXPR, NULL_TREE, loop_body);
13946   TREE_SIDE_EFFECTS (loop) = 1;
13947   PUSH_LOOP (loop);
13948   return loop;
13949 }
13950
13951 /* Create a loop body according to the following structure:
13952      COMPOUND_EXPR
13953        COMPOUND_EXPR            (loop main body)
13954          EXIT_EXPR              (this order is for while/for loops.
13955          LABELED_BLOCK_EXPR      the order is reversed for do loops)
13956            LABEL_DECL           (a continue occuring here branches at the 
13957            BODY                  end of this labeled block)
13958        INCREMENT                (if any)
13959
13960   REVERSED, if non zero, tells that the loop condition expr comes
13961   after the body, like in the do-while loop.
13962
13963   To obtain a loop, the loop body structure described above is
13964   encapsulated within a LOOP_EXPR surrounded by a LABELED_BLOCK_EXPR:
13965
13966    LABELED_BLOCK_EXPR
13967      LABEL_DECL                   (use this label to exit the loop)
13968      LOOP_EXPR
13969        <structure described above> */
13970
13971 static tree
13972 build_loop_body (location, condition, reversed)
13973      int location;
13974      tree condition;
13975      int reversed;
13976 {
13977   tree first, second, body;
13978
13979   condition = build (EXIT_EXPR, NULL_TREE, condition); /* Force walk */
13980   EXPR_WFL_LINECOL (condition) = location; /* For accurate error report */
13981   condition = build_debugable_stmt (location, condition);
13982   TREE_SIDE_EFFECTS (condition) = 1;
13983
13984   body = build_labeled_block (0, continue_identifier_node);
13985   first = (reversed ? body : condition);
13986   second = (reversed ? condition : body);
13987   return 
13988     build (COMPOUND_EXPR, NULL_TREE, 
13989            build (COMPOUND_EXPR, NULL_TREE, first, second), empty_stmt_node);
13990 }
13991
13992 /* Install CONDITION (if any) and loop BODY (using REVERSED to tell
13993    their order) on the current loop. Unlink the current loop from the
13994    loop list.  */
13995
13996 static tree
13997 finish_loop_body (location, condition, body, reversed)
13998      int location;
13999      tree condition, body;
14000      int reversed;
14001 {
14002   tree to_return = ctxp->current_loop;
14003   tree loop_body = LOOP_EXPR_BODY (to_return);
14004   if (condition)
14005     {
14006       tree cnode = LOOP_EXPR_BODY_CONDITION_EXPR (loop_body, reversed);
14007       /* We wrapped the EXIT_EXPR around a WFL so we can debug it.
14008          The real EXIT_EXPR is one operand further. */
14009       EXPR_WFL_LINECOL (cnode) = location;
14010       /* This one is for accurate error reports */
14011       EXPR_WFL_LINECOL (TREE_OPERAND (cnode, 0)) = location;
14012       TREE_OPERAND (TREE_OPERAND (cnode, 0), 0) = condition;
14013     }
14014   LOOP_EXPR_BODY_BODY_EXPR (loop_body, reversed) = body;
14015   POP_LOOP ();
14016   return to_return;
14017 }
14018
14019 /* Tailored version of finish_loop_body for FOR loops, when FOR
14020    loops feature the condition part */
14021
14022 static tree
14023 finish_for_loop (location, condition, update, body)
14024     int location;
14025     tree condition, update, body;
14026 {
14027   /* Put the condition and the loop body in place */
14028   tree loop = finish_loop_body (location, condition, body, 0);
14029   /* LOOP is the current loop which has been now popped of the loop
14030      stack. Install the update block */
14031   LOOP_EXPR_BODY_UPDATE_BLOCK (LOOP_EXPR_BODY (loop)) = update;
14032   return loop;
14033 }
14034
14035 /* Try to find the loop a block might be related to. This comprises
14036    the case where the LOOP_EXPR is found as the second operand of a
14037    COMPOUND_EXPR, because the loop happens to have an initialization
14038    part, then expressed as the first operand of the COMPOUND_EXPR. If
14039    the search finds something, 1 is returned. Otherwise, 0 is
14040    returned. The search is assumed to start from a
14041    LABELED_BLOCK_EXPR's block.  */
14042
14043 static tree
14044 search_loop (statement)
14045     tree statement;
14046 {
14047   if (TREE_CODE (statement) == LOOP_EXPR)
14048     return statement;
14049
14050   if (TREE_CODE (statement) == BLOCK)
14051     statement = BLOCK_SUBBLOCKS (statement);
14052   else
14053     return NULL_TREE;
14054
14055   if (statement && TREE_CODE (statement) == COMPOUND_EXPR)
14056     while (statement && TREE_CODE (statement) == COMPOUND_EXPR)
14057       statement = TREE_OPERAND (statement, 1);
14058
14059   return (TREE_CODE (statement) == LOOP_EXPR
14060           && FOR_LOOP_P (statement) ? statement : NULL_TREE);
14061 }
14062
14063 /* Return 1 if LOOP can be found in the labeled block BLOCK. 0 is
14064    returned otherwise.  */
14065
14066 static int
14067 labeled_block_contains_loop_p (block, loop)
14068     tree block, loop;
14069 {
14070   if (!block)
14071     return 0;
14072
14073   if (LABELED_BLOCK_BODY (block) == loop)
14074     return 1;
14075
14076   if (FOR_LOOP_P (loop) && search_loop (LABELED_BLOCK_BODY (block)) == loop)
14077     return 1;
14078
14079   return 0;
14080 }
14081
14082 /* If the loop isn't surrounded by a labeled statement, create one and
14083    insert LOOP as its body.  */
14084
14085 static tree
14086 patch_loop_statement (loop)
14087      tree loop;
14088 {
14089   tree loop_label;
14090
14091   TREE_TYPE (loop) = void_type_node;
14092   if (labeled_block_contains_loop_p (ctxp->current_labeled_block, loop))
14093     return loop;
14094
14095   loop_label = build_labeled_block (0, NULL_TREE);
14096   /* LOOP is an EXPR node, so it should have a valid EXPR_WFL_LINECOL
14097      that LOOP_LABEL could enquire about, for a better accuracy. FIXME */
14098   LABELED_BLOCK_BODY (loop_label) = loop;
14099   PUSH_LABELED_BLOCK (loop_label);
14100   return loop_label;
14101 }
14102
14103 /* 14.13, 14.14: break and continue Statements */
14104
14105 /* Build a break or a continue statement. a null NAME indicates an
14106    unlabeled break/continue statement.  */
14107
14108 static tree
14109 build_bc_statement (location, is_break, name)
14110      int location, is_break;
14111      tree name;
14112 {
14113   tree break_continue, label_block_expr = NULL_TREE;
14114
14115   if (name)
14116     {
14117       if (!(label_block_expr = IDENTIFIER_LOCAL_VALUE 
14118             (merge_qualified_name (label_id, EXPR_WFL_NODE (name)))))
14119         /* Null means that we don't have a target for this named
14120            break/continue. In this case, we make the target to be the
14121            label name, so that the error can be reported accuratly in
14122            patch_bc_statement. */
14123         label_block_expr = EXPR_WFL_NODE (name);
14124     }
14125   /* Unlabeled break/continue will be handled during the
14126      break/continue patch operation */
14127   break_continue 
14128     = build (EXIT_BLOCK_EXPR, NULL_TREE, label_block_expr, NULL_TREE);
14129
14130   IS_BREAK_STMT_P (break_continue) = is_break;
14131   TREE_SIDE_EFFECTS (break_continue) = 1;
14132   EXPR_WFL_LINECOL (break_continue) = location;
14133   break_continue = build_debugable_stmt (location, break_continue);
14134   return break_continue;
14135 }
14136
14137 /* Verification of a break/continue statement. */
14138
14139 static tree
14140 patch_bc_statement (node)
14141      tree node;
14142 {
14143   tree bc_label = EXIT_BLOCK_LABELED_BLOCK (node), target_stmt;
14144   tree labeled_block = ctxp->current_labeled_block;
14145   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14146  
14147   /* Having an identifier here means that the target is unknown. */
14148   if (bc_label != NULL_TREE && TREE_CODE (bc_label) == IDENTIFIER_NODE)
14149     {
14150       parse_error_context (wfl_operator, "No label definition found for `%s'",
14151                            IDENTIFIER_POINTER (bc_label));
14152       return error_mark_node;
14153     }
14154   if (! IS_BREAK_STMT_P (node))
14155     {
14156       /* It's a continue statement. */
14157       for (;; labeled_block = TREE_CHAIN (labeled_block))
14158         {
14159           if (labeled_block == NULL_TREE)
14160             {
14161               if (bc_label == NULL_TREE)
14162                 parse_error_context (wfl_operator,
14163                                      "`continue' must be in loop");
14164               else
14165                 parse_error_context 
14166                   (wfl_operator, "continue label `%s' does not name a loop",
14167                    IDENTIFIER_POINTER (bc_label));
14168               return error_mark_node;
14169             }
14170           if ((DECL_NAME (LABELED_BLOCK_LABEL (labeled_block))
14171                == continue_identifier_node)
14172               && (bc_label == NULL_TREE
14173                   || TREE_CHAIN (labeled_block) == bc_label))
14174             {
14175               bc_label = labeled_block;
14176               break;
14177             }
14178         }
14179     }
14180   else if (!bc_label)
14181     { 
14182       for (;; labeled_block = TREE_CHAIN (labeled_block))
14183         {
14184           if (labeled_block == NULL_TREE)
14185             {
14186               parse_error_context (wfl_operator,
14187                                      "`break' must be in loop or switch");
14188               return error_mark_node;
14189             }
14190           target_stmt = LABELED_BLOCK_BODY (labeled_block);
14191           if (TREE_CODE (target_stmt) == SWITCH_EXPR
14192               || search_loop (target_stmt))
14193             {
14194               bc_label = labeled_block;
14195               break;
14196             }
14197         }
14198     }
14199
14200   EXIT_BLOCK_LABELED_BLOCK (node) = bc_label;
14201   CAN_COMPLETE_NORMALLY (bc_label) = 1;
14202
14203   /* Our break/continue don't return values. */
14204   TREE_TYPE (node) = void_type_node;
14205   /* Encapsulate the break within a compound statement so that it's
14206      expanded all the times by expand_expr (and not clobbered
14207      sometimes, like after a if statement) */
14208   node = add_stmt_to_compound (NULL_TREE, void_type_node, node);
14209   TREE_SIDE_EFFECTS (node) = 1;
14210   return node;
14211 }
14212
14213 /* Process the exit expression belonging to a loop. Its type must be
14214    boolean.  */
14215
14216 static tree
14217 patch_exit_expr (node)
14218      tree node;
14219 {
14220   tree expression = TREE_OPERAND (node, 0);
14221   TREE_TYPE (node) = error_mark_node;
14222   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14223
14224   /* The type of expression must be boolean */
14225   if (TREE_TYPE (expression) != boolean_type_node)
14226     {
14227       parse_error_context 
14228         (wfl_operator, 
14229     "Incompatible type for loop conditional. Can't convert `%s' to `boolean'", 
14230          lang_printable_name (TREE_TYPE (expression), 0));
14231       return error_mark_node;
14232     }
14233   /* Now we know things are allright, invert the condition, fold and
14234      return */
14235   TREE_OPERAND (node, 0) = 
14236     fold (build1 (TRUTH_NOT_EXPR, boolean_type_node, expression));
14237
14238   if (! integer_zerop (TREE_OPERAND (node, 0))
14239       && ctxp->current_loop != NULL_TREE
14240       && TREE_CODE (ctxp->current_loop) == LOOP_EXPR)
14241     CAN_COMPLETE_NORMALLY (ctxp->current_loop) = 1;
14242   if (! integer_onep (TREE_OPERAND (node, 0)))
14243     CAN_COMPLETE_NORMALLY (node) = 1;
14244
14245
14246   TREE_TYPE (node) = void_type_node;
14247   return node;
14248 }
14249
14250 /* 14.9 Switch statement */
14251
14252 static tree
14253 patch_switch_statement (node)
14254      tree node;
14255 {
14256   tree se = TREE_OPERAND (node, 0), se_type;
14257
14258   /* Complete the switch expression */
14259   se = TREE_OPERAND (node, 0) = java_complete_tree (se);
14260   se_type = TREE_TYPE (se);
14261   /* The type of the switch expression must be char, byte, short or
14262      int */
14263   if (!JINTEGRAL_TYPE_P (se_type))
14264     {
14265       EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14266       parse_error_context (wfl_operator,
14267           "Incompatible type for `switch'. Can't convert `%s' to `int'",
14268                            lang_printable_name (se_type, 0));
14269       /* This is what java_complete_tree will check */
14270       TREE_OPERAND (node, 0) = error_mark_node;
14271       return error_mark_node;
14272     }
14273
14274   TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
14275
14276   /* Ready to return */
14277   if (TREE_CODE (TREE_OPERAND (node, 1)) == ERROR_MARK)
14278     {
14279       TREE_TYPE (node) = error_mark_node;
14280       return error_mark_node;
14281     }
14282   TREE_TYPE (node) = void_type_node;
14283   TREE_SIDE_EFFECTS (node) = 1;
14284   CAN_COMPLETE_NORMALLY (node)
14285     = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)) 
14286       || ! SWITCH_HAS_DEFAULT (node);
14287   return node;
14288 }
14289
14290 /* 14.18 The try/catch statements */
14291
14292 static tree
14293 build_try_statement (location, try_block, catches)
14294      int location;
14295      tree try_block, catches;
14296 {
14297   tree node = build (TRY_EXPR, NULL_TREE, try_block, catches);
14298   EXPR_WFL_LINECOL (node) = location;
14299   return node;
14300 }
14301
14302 static tree
14303 build_try_finally_statement (location, try_block, finally)
14304      int location;
14305      tree try_block, finally;
14306 {
14307   tree node = build (TRY_FINALLY_EXPR, NULL_TREE, try_block, finally);
14308   EXPR_WFL_LINECOL (node) = location;
14309   return node;
14310 }
14311
14312 static tree
14313 patch_try_statement (node)
14314      tree node;
14315 {
14316   int error_found = 0;
14317   tree try = TREE_OPERAND (node, 0);
14318   /* Exception handlers are considered in left to right order */
14319   tree catch = nreverse (TREE_OPERAND (node, 1));
14320   tree current, caught_type_list = NULL_TREE;
14321
14322   /* Check catch clauses, if any. Every time we find an error, we try
14323      to process the next catch clause. We process the catch clause before
14324      the try block so that when processing the try block we can check thrown
14325      exceptions againts the caught type list. */
14326   for (current = catch; current; current = TREE_CHAIN (current))
14327     {
14328       tree carg_decl, carg_type;
14329       tree sub_current, catch_block, catch_clause;
14330       int unreachable;
14331
14332       /* At this point, the structure of the catch clause is
14333            CATCH_EXPR           (catch node)
14334              BLOCK              (with the decl of the parameter)
14335                COMPOUND_EXPR
14336                  MODIFY_EXPR   (assignment of the catch parameter)
14337                  BLOCK          (catch clause block)
14338        */
14339       catch_clause = TREE_OPERAND (current, 0);
14340       carg_decl = BLOCK_EXPR_DECLS (catch_clause);
14341       carg_type = TREE_TYPE (TREE_TYPE (carg_decl));
14342
14343       /* Catch clauses can't have more than one parameter declared,
14344          but it's already enforced by the grammar. Make sure that the
14345          only parameter of the clause statement in of class Throwable
14346          or a subclass of Throwable, but that was done earlier. The
14347          catch clause parameter type has also been resolved. */
14348       
14349       /* Just make sure that the catch clause parameter type inherits
14350          from java.lang.Throwable */
14351       if (!inherits_from_p (carg_type, throwable_type_node))
14352         {
14353           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
14354           parse_error_context (wfl_operator,
14355                                "Can't catch class `%s'. Catch clause parameter type must be a subclass of class `java.lang.Throwable'",
14356                                lang_printable_name (carg_type, 0));
14357           error_found = 1;
14358           continue;
14359         }
14360       
14361       /* Partial check for unreachable catch statement: The catch
14362          clause is reachable iff is no earlier catch block A in
14363          the try statement such that the type of the catch
14364          clause's parameter is the same as or a subclass of the
14365          type of A's parameter */
14366       unreachable = 0;
14367       for (sub_current = catch;
14368            sub_current != current; sub_current = TREE_CHAIN (sub_current))
14369         {
14370           tree sub_catch_clause, decl;
14371           sub_catch_clause = TREE_OPERAND (sub_current, 0);
14372           decl = BLOCK_EXPR_DECLS (sub_catch_clause);
14373
14374           if (inherits_from_p (carg_type, TREE_TYPE (TREE_TYPE (decl))))
14375             {
14376               EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
14377               parse_error_context 
14378                 (wfl_operator,
14379                  "`catch' not reached because of the catch clause at line %d",
14380                  EXPR_WFL_LINENO (sub_current));
14381               unreachable = error_found = 1;
14382               break;
14383             }
14384         }
14385       /* Complete the catch clause block */
14386       catch_block = java_complete_tree (TREE_OPERAND (current, 0));
14387       if (catch_block == error_mark_node)
14388         {
14389           error_found = 1;
14390           continue;
14391         }
14392       if (CAN_COMPLETE_NORMALLY (catch_block))
14393         CAN_COMPLETE_NORMALLY (node) = 1;
14394       TREE_OPERAND (current, 0) = catch_block;
14395
14396       if (unreachable)
14397         continue;
14398
14399       /* Things to do here: the exception must be thrown */
14400
14401       /* Link this type to the caught type list */
14402       caught_type_list = tree_cons (NULL_TREE, carg_type, caught_type_list);
14403     }
14404
14405   PUSH_EXCEPTIONS (caught_type_list);
14406   if ((try = java_complete_tree (try)) == error_mark_node)
14407     error_found = 1;
14408   if (CAN_COMPLETE_NORMALLY (try))
14409     CAN_COMPLETE_NORMALLY (node) = 1;
14410   POP_EXCEPTIONS ();
14411
14412   /* Verification ends here */
14413   if (error_found) 
14414     return error_mark_node;
14415
14416   TREE_OPERAND (node, 0) = try;
14417   TREE_OPERAND (node, 1) = catch;
14418   TREE_TYPE (node) = void_type_node;
14419   return node;
14420 }
14421
14422 /* 14.17 The synchronized Statement */
14423
14424 static tree
14425 patch_synchronized_statement (node, wfl_op1)
14426     tree node, wfl_op1;
14427 {
14428   tree expr = java_complete_tree (TREE_OPERAND (node, 0));
14429   tree block = TREE_OPERAND (node, 1);
14430
14431   tree enter, exit, expr_decl, assignment;
14432
14433   if (expr == error_mark_node)
14434     {
14435       block = java_complete_tree (block);
14436       return expr;
14437     }
14438
14439   /* The TYPE of expr must be a reference type */
14440   if (!JREFERENCE_TYPE_P (TREE_TYPE (expr)))
14441     {
14442       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
14443       parse_error_context (wfl_operator, "Incompatible type for `synchronized'. Can't convert `%s' to `java.lang.Object'",
14444                            lang_printable_name (TREE_TYPE (expr), 0));
14445       return error_mark_node;
14446     }
14447
14448   if (flag_emit_xref)
14449     {
14450       TREE_OPERAND (node, 0) = expr;
14451       TREE_OPERAND (node, 1) = java_complete_tree (block);
14452       CAN_COMPLETE_NORMALLY (node) = 1;
14453       return node;
14454     }
14455
14456   /* Generate a try-finally for the synchronized statement, except
14457      that the handler that catches all throw exception calls
14458      _Jv_MonitorExit and then rethrow the exception.
14459      The synchronized statement is then implemented as:
14460      TRY 
14461        {
14462          _Jv_MonitorEnter (expression)
14463          synchronized_block
14464          _Jv_MonitorExit (expression)
14465        }
14466      CATCH_ALL
14467        {
14468          e = _Jv_exception_info ();
14469          _Jv_MonitorExit (expression)
14470          Throw (e);
14471        } */
14472
14473   expr_decl = build_decl (VAR_DECL, generate_name (), TREE_TYPE (expr));
14474   BUILD_MONITOR_ENTER (enter, expr_decl);
14475   BUILD_MONITOR_EXIT (exit, expr_decl);
14476   CAN_COMPLETE_NORMALLY (enter) = 1;
14477   CAN_COMPLETE_NORMALLY (exit) = 1;
14478   assignment = build (MODIFY_EXPR, NULL_TREE, expr_decl, expr);
14479   TREE_SIDE_EFFECTS (assignment) = 1;
14480   node = build1 (CLEANUP_POINT_EXPR, NULL_TREE,
14481                  build (COMPOUND_EXPR, NULL_TREE,
14482                         build (WITH_CLEANUP_EXPR, NULL_TREE,
14483                                build (COMPOUND_EXPR, NULL_TREE,
14484                                       assignment, enter),
14485                                NULL_TREE, exit),
14486                         block));
14487   node = build_expr_block (node, expr_decl);
14488
14489   return java_complete_tree (node);
14490 }
14491
14492 /* 14.16 The throw Statement */
14493
14494 static tree
14495 patch_throw_statement (node, wfl_op1)
14496     tree node, wfl_op1;
14497 {
14498   tree expr = TREE_OPERAND (node, 0);
14499   tree type = TREE_TYPE (expr);
14500   int unchecked_ok = 0, tryblock_throws_ok = 0;
14501
14502   /* Thrown expression must be assignable to java.lang.Throwable */
14503   if (!try_reference_assignconv (throwable_type_node, expr))
14504     {
14505       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
14506       parse_error_context (wfl_operator,
14507     "Can't throw `%s'; it must be a subclass of class `java.lang.Throwable'",
14508                            lang_printable_name (type, 0));
14509       /* If the thrown expression was a reference, we further the
14510          compile-time check. */
14511       if (!JREFERENCE_TYPE_P (type))
14512         return error_mark_node;
14513     }
14514
14515   /* At least one of the following must be true */
14516
14517   /* The type of the throw expression is a not checked exception,
14518      i.e. is a unchecked expression. */
14519   unchecked_ok = IS_UNCHECKED_EXCEPTION_P (TREE_TYPE (type));
14520
14521   SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
14522   /* An instance can't throw a checked excetion unless that exception
14523      is explicitely declared in the `throws' clause of each
14524      constructor. This doesn't apply to anonymous classes, since they
14525      don't have declared constructors. */
14526   if (!unchecked_ok 
14527       && in_instance_initializer && !ANONYMOUS_CLASS_P (current_class))
14528     {
14529       tree current;
14530       for (current = TYPE_METHODS (current_class); current; 
14531            current = TREE_CHAIN (current))
14532         if (DECL_CONSTRUCTOR_P (current) 
14533             && !check_thrown_exceptions_do (TREE_TYPE (expr)))
14534           {
14535             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)", 
14536                                  lang_printable_name (TREE_TYPE (expr), 0));
14537             return error_mark_node;
14538           }
14539     }
14540
14541   /* Throw is contained in a try statement and at least one catch
14542      clause can receive the thrown expression or the current method is
14543      declared to throw such an exception. Or, the throw statement is
14544      contained in a method or constructor declaration and the type of
14545      the Expression is assignable to at least one type listed in the
14546      throws clause the declaration. */
14547   if (!unchecked_ok)
14548     tryblock_throws_ok = check_thrown_exceptions_do (TREE_TYPE (expr));
14549   if (!(unchecked_ok || tryblock_throws_ok))
14550     {
14551       /* If there is a surrounding try block that has no matching
14552          clatch clause, report it first. A surrounding try block exits
14553          only if there is something after the list of checked
14554          exception thrown by the current function (if any). */
14555       if (IN_TRY_BLOCK_P ())
14556         parse_error_context (wfl_operator, "Checked exception `%s' can't be caught by any of the catch clause(s) of the surrounding `try' block",
14557                              lang_printable_name (type, 0));
14558       /* If we have no surrounding try statement and the method doesn't have
14559          any throws, report it now. FIXME */
14560
14561       /* We report that the exception can't be throw from a try block
14562          in all circumstances but when the `throw' is inside a static
14563          block. */
14564       else if (!EXCEPTIONS_P (currently_caught_type_list) 
14565                && !tryblock_throws_ok)
14566         {
14567           if (DECL_CLINIT_P (current_function_decl))
14568             parse_error_context (wfl_operator,
14569                    "Checked exception `%s' can't be thrown in initializer",
14570                                  lang_printable_name (type, 0));
14571           else
14572             parse_error_context (wfl_operator,
14573                    "Checked exception `%s' isn't thrown from a `try' block", 
14574                                  lang_printable_name (type, 0));
14575         }
14576       /* Otherwise, the current method doesn't have the appropriate
14577          throws declaration */
14578       else
14579         parse_error_context (wfl_operator, "Checked exception `%s' doesn't match any of current method's `throws' declaration(s)", 
14580                              lang_printable_name (type, 0));
14581       return error_mark_node;
14582     }
14583
14584   if (! flag_emit_class_files && ! flag_emit_xref)
14585     BUILD_THROW (node, expr);
14586
14587   /* If doing xrefs, keep the location where the `throw' was seen. */
14588   if (flag_emit_xref)
14589     EXPR_WFL_LINECOL (node) = EXPR_WFL_LINECOL (wfl_op1);
14590   return node;
14591 }
14592
14593 /* Check that exception said to be thrown by method DECL can be
14594    effectively caught from where DECL is invoked.  */
14595
14596 static void
14597 check_thrown_exceptions (location, decl)
14598      int location;
14599      tree decl;
14600 {
14601   tree throws;
14602   /* For all the unchecked exceptions thrown by DECL */
14603   for (throws = DECL_FUNCTION_THROWS (decl); throws; 
14604        throws = TREE_CHAIN (throws)) 
14605     if (!check_thrown_exceptions_do (TREE_VALUE (throws)))
14606       {
14607 #if 1
14608         /* Temporary hack to suppresses errors about cloning arrays. FIXME */
14609         if (DECL_NAME (decl) == get_identifier ("clone"))
14610           continue;
14611 #endif
14612         EXPR_WFL_LINECOL (wfl_operator) = location;
14613         if (DECL_FINIT_P (current_function_decl))
14614           parse_error_context
14615             (wfl_operator, "Exception `%s' can't be thrown in initializer",
14616              lang_printable_name (TREE_VALUE (throws), 0));
14617         else 
14618           {
14619             parse_error_context 
14620               (wfl_operator, "Exception `%s' must be caught, or it must be declared in the `throws' clause of `%s'", 
14621                lang_printable_name (TREE_VALUE (throws), 0),
14622                (DECL_INIT_P (current_function_decl) ?
14623                 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))) :
14624                 IDENTIFIER_POINTER (DECL_NAME (current_function_decl))));
14625           }
14626       }
14627 }
14628
14629 /* Return 1 if checked EXCEPTION is caught at the current nesting level of
14630    try-catch blocks, OR is listed in the `throws' clause of the
14631    current method.  */
14632
14633 static int
14634 check_thrown_exceptions_do (exception)
14635      tree exception;
14636 {
14637   tree list = currently_caught_type_list;
14638   resolve_and_layout (exception, NULL_TREE);
14639   /* First, all the nested try-catch-finally at that stage. The
14640      last element contains `throws' clause exceptions, if any. */
14641   if (IS_UNCHECKED_EXCEPTION_P (exception))
14642     return 1;
14643   while (list)
14644     {
14645       tree caught;
14646       for (caught = TREE_VALUE (list); caught; caught = TREE_CHAIN (caught))
14647         if (valid_ref_assignconv_cast_p (exception, TREE_VALUE (caught), 0))
14648           return 1;
14649       list = TREE_CHAIN (list);
14650     }
14651   return 0;
14652 }
14653
14654 static void
14655 purge_unchecked_exceptions (mdecl)
14656      tree mdecl;
14657 {
14658   tree throws = DECL_FUNCTION_THROWS (mdecl);
14659   tree new = NULL_TREE;
14660
14661   while (throws)
14662     {
14663       tree next = TREE_CHAIN (throws);
14664       if (!IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (throws)))
14665         {
14666           TREE_CHAIN (throws) = new;
14667           new = throws;
14668         }
14669       throws = next;
14670     }
14671   /* List is inverted here, but it doesn't matter */
14672   DECL_FUNCTION_THROWS (mdecl) = new;
14673 }
14674
14675 /* 15.24 Conditional Operator ?: */
14676
14677 static tree
14678 patch_conditional_expr (node, wfl_cond, wfl_op1)
14679      tree node, wfl_cond, wfl_op1;
14680 {
14681   tree cond = TREE_OPERAND (node, 0);
14682   tree op1 = TREE_OPERAND (node, 1);
14683   tree op2 = TREE_OPERAND (node, 2);
14684   tree resulting_type = NULL_TREE;
14685   tree t1, t2, patched;
14686   int error_found = 0;
14687
14688   /* Operands of ?: might be StringBuffers crafted as a result of a
14689      string concatenation. Obtain a descent operand here.  */
14690   if ((patched = patch_string (op1)))
14691     TREE_OPERAND (node, 1) = op1 = patched;
14692   if ((patched = patch_string (op2)))
14693     TREE_OPERAND (node, 2) = op2 = patched;
14694
14695   t1 = TREE_TYPE (op1);
14696   t2 = TREE_TYPE (op2);
14697
14698   /* The first expression must be a boolean */
14699   if (TREE_TYPE (cond) != boolean_type_node)
14700     {
14701       SET_WFL_OPERATOR (wfl_operator, node, wfl_cond);
14702       parse_error_context (wfl_operator,
14703                "Incompatible type for `?:'. Can't convert `%s' to `boolean'",
14704                            lang_printable_name (TREE_TYPE (cond), 0));
14705       error_found = 1;
14706     }
14707
14708   /* Second and third can be numeric, boolean (i.e. primitive),
14709      references or null. Anything else results in an error */
14710   if (!((JNUMERIC_TYPE_P (t1) && JNUMERIC_TYPE_P (t2))
14711         || ((JREFERENCE_TYPE_P (t1) || op1 == null_pointer_node) 
14712             && (JREFERENCE_TYPE_P (t2) || op2 == null_pointer_node))
14713         || (t1 == boolean_type_node && t2 == boolean_type_node)))
14714     error_found = 1;
14715
14716   /* Determine the type of the conditional expression. Same types are
14717      easy to deal with */
14718   else if (t1 == t2)
14719     resulting_type = t1;
14720
14721   /* There are different rules for numeric types */
14722   else if (JNUMERIC_TYPE_P (t1))
14723     {
14724       /* if byte/short found, the resulting type is short */
14725       if ((t1 == byte_type_node && t2 == short_type_node)
14726           || (t1 == short_type_node && t2 == byte_type_node))
14727         resulting_type = short_type_node;
14728
14729       /* If t1 is a constant int and t2 is of type byte, short or char
14730          and t1's value fits in t2, then the resulting type is t2 */
14731       else if ((t1 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 1)))
14732           && JBSC_TYPE_P (t2) && int_fits_type_p (TREE_OPERAND (node, 1), t2))
14733         resulting_type = t2;
14734
14735       /* If t2 is a constant int and t1 is of type byte, short or char
14736          and t2's value fits in t1, then the resulting type is t1 */
14737       else if ((t2 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 2)))
14738           && JBSC_TYPE_P (t1) && int_fits_type_p (TREE_OPERAND (node, 2), t1))
14739         resulting_type = t1;
14740
14741       /* Otherwise, binary numeric promotion is applied and the
14742          resulting type is the promoted type of operand 1 and 2 */
14743       else 
14744         resulting_type = binary_numeric_promotion (t1, t2, 
14745                                                    &TREE_OPERAND (node, 1), 
14746                                                    &TREE_OPERAND (node, 2));
14747     }
14748
14749   /* Cases of a reference and a null type */
14750   else if (JREFERENCE_TYPE_P (t1) && op2 == null_pointer_node)
14751     resulting_type = t1;
14752
14753   else if (JREFERENCE_TYPE_P (t2) && op1 == null_pointer_node)
14754     resulting_type = t2;
14755
14756   /* Last case: different reference types. If a type can be converted
14757      into the other one by assignment conversion, the latter
14758      determines the type of the expression */
14759   else if ((resulting_type = try_reference_assignconv (t1, op2)))
14760     resulting_type = promote_type (t1);
14761
14762   else if ((resulting_type = try_reference_assignconv (t2, op1)))
14763     resulting_type = promote_type (t2);
14764
14765   /* If we don't have any resulting type, we're in trouble */
14766   if (!resulting_type)
14767     {
14768       char *t = xstrdup (lang_printable_name (t1, 0));
14769       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
14770       parse_error_context (wfl_operator,
14771                  "Incompatible type for `?:'. Can't convert `%s' to `%s'",
14772                            t, lang_printable_name (t2, 0));
14773       free (t);
14774       error_found = 1;
14775     }
14776
14777   if (error_found)
14778     {
14779       TREE_TYPE (node) = error_mark_node;
14780       return error_mark_node;
14781     }
14782
14783   TREE_TYPE (node) = resulting_type;
14784   TREE_SET_CODE (node, COND_EXPR);
14785   CAN_COMPLETE_NORMALLY (node) = 1;
14786   return node;
14787 }
14788
14789 /* Try to constant fold NODE.
14790    If NODE is not a constant expression, return NULL_EXPR.
14791    CONTEXT is a static final VAR_DECL whose initializer we are folding. */
14792
14793 static tree
14794 fold_constant_for_init (node, context)
14795      tree node;
14796      tree context;
14797 {
14798   tree op0, op1, val;
14799   enum tree_code code = TREE_CODE (node);
14800
14801   if (code == STRING_CST)
14802     return node;
14803
14804   if (code == INTEGER_CST || code == REAL_CST)
14805     return convert (TREE_TYPE (context), node);
14806
14807   switch (code)
14808     {
14809     case PLUS_EXPR:
14810     case MINUS_EXPR:
14811     case MULT_EXPR:
14812     case TRUNC_MOD_EXPR:
14813     case RDIV_EXPR:
14814     case LSHIFT_EXPR:
14815     case RSHIFT_EXPR:
14816     case URSHIFT_EXPR:
14817     case BIT_AND_EXPR:
14818     case BIT_XOR_EXPR:
14819     case BIT_IOR_EXPR:
14820     case TRUTH_ANDIF_EXPR:
14821     case TRUTH_ORIF_EXPR:
14822     case EQ_EXPR: 
14823     case NE_EXPR:
14824     case GT_EXPR:
14825     case GE_EXPR:
14826     case LT_EXPR:
14827     case LE_EXPR:
14828       op0 = TREE_OPERAND (node, 0);
14829       op1 = TREE_OPERAND (node, 1);
14830       val = fold_constant_for_init (op0, context);
14831       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14832         return NULL_TREE;
14833       TREE_OPERAND (node, 0) = val;
14834       val = fold_constant_for_init (op1, context);
14835       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14836         return NULL_TREE;
14837       TREE_OPERAND (node, 1) = val;
14838       return patch_binop (node, op0, op1);
14839
14840     case UNARY_PLUS_EXPR:
14841     case NEGATE_EXPR:
14842     case TRUTH_NOT_EXPR:
14843     case BIT_NOT_EXPR:
14844     case CONVERT_EXPR:
14845       op0 = TREE_OPERAND (node, 0);
14846       val = fold_constant_for_init (op0, context);
14847       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14848         return NULL_TREE;
14849       TREE_OPERAND (node, 0) = val;
14850       return patch_unaryop (node, op0);
14851       break;
14852
14853     case COND_EXPR:
14854       val = fold_constant_for_init (TREE_OPERAND (node, 0), context);
14855       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14856         return NULL_TREE;
14857       TREE_OPERAND (node, 0) = val;
14858       val = fold_constant_for_init (TREE_OPERAND (node, 1), context);
14859       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14860         return NULL_TREE;
14861       TREE_OPERAND (node, 1) = val;
14862       val = fold_constant_for_init (TREE_OPERAND (node, 2), context);
14863       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14864         return NULL_TREE;
14865       TREE_OPERAND (node, 2) = val;
14866       return integer_zerop (TREE_OPERAND (node, 0)) ? TREE_OPERAND (node, 1)
14867         : TREE_OPERAND (node, 2);
14868
14869     case VAR_DECL:
14870     case FIELD_DECL:
14871       if (! FIELD_FINAL (node)
14872           || DECL_INITIAL (node) == NULL_TREE)
14873         return NULL_TREE;
14874       val = DECL_INITIAL (node);
14875       /* Guard against infinite recursion. */
14876       DECL_INITIAL (node) = NULL_TREE;
14877       val = fold_constant_for_init (val, node);
14878       DECL_INITIAL (node) = val;
14879       return val;
14880
14881     case EXPR_WITH_FILE_LOCATION:
14882       /* Compare java_complete_tree and resolve_expression_name. */
14883       if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
14884           || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
14885         {
14886           tree name = EXPR_WFL_NODE (node);
14887           tree decl;
14888           if (PRIMARY_P (node))
14889             return NULL_TREE;
14890           else if (! QUALIFIED_P (name))
14891             {
14892               decl = lookup_field_wrapper (DECL_CONTEXT (context), name);
14893               if (decl == NULL_TREE 
14894                   || (! FIELD_STATIC (decl) && ! FIELD_FINAL (decl)))
14895                 return NULL_TREE;
14896               return fold_constant_for_init (decl, decl);
14897             }
14898           else
14899             {
14900               /* Wait until the USE_COMPONENT_REF re-write.  FIXME. */
14901               qualify_ambiguous_name (node);
14902               if (resolve_field_access (node, &decl, NULL)
14903                   && decl != NULL_TREE)
14904                 return fold_constant_for_init (decl, decl);
14905               return NULL_TREE;
14906             }
14907         }
14908       else
14909         {
14910           op0 = TREE_OPERAND (node, 0);
14911           val = fold_constant_for_init (op0, context);
14912           if (val == NULL_TREE || ! TREE_CONSTANT (val))
14913             return NULL_TREE;
14914           TREE_OPERAND (node, 0) = val;
14915           return val;
14916         }
14917
14918 #ifdef USE_COMPONENT_REF
14919     case IDENTIFIER:
14920     case COMPONENT_REF:
14921       ?;
14922 #endif
14923
14924     default:
14925       return NULL_TREE;
14926     }
14927 }
14928
14929 #ifdef USE_COMPONENT_REF
14930 /* Context is 'T' for TypeName, 'P' for PackageName,
14931    'M' for MethodName, 'E' for ExpressionName, and 'A' for AmbiguousName. */
14932
14933 tree
14934 resolve_simple_name (name, context)
14935      tree name;
14936      int context;
14937 {
14938 }
14939
14940 tree
14941 resolve_qualified_name (name, context)
14942      tree name;
14943      int context;
14944 {
14945 }
14946 #endif