OSDN Git Service

* parse.y (patch_incomplete_class_ref): Initialize the returned
[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 int check_pkg_class_access PARAMS ((tree, tree));
104 static void register_package PARAMS ((tree));
105 static tree resolve_package PARAMS ((tree, tree *));
106 static tree lookup_package_type PARAMS ((const char *, int));
107 static tree lookup_package_type_and_set_next PARAMS ((const char *, int, tree *));
108 static tree resolve_class PARAMS ((tree, tree, tree, tree));
109 static void declare_local_variables PARAMS ((int, tree, tree));
110 static void source_start_java_method PARAMS ((tree));
111 static void source_end_java_method PARAMS ((void));
112 static void expand_start_java_method PARAMS ((tree));
113 static tree find_name_in_single_imports PARAMS ((tree));
114 static void check_abstract_method_header PARAMS ((tree));
115 static tree lookup_java_interface_method2 PARAMS ((tree, tree));
116 static tree resolve_expression_name PARAMS ((tree, tree *));
117 static tree maybe_create_class_interface_decl PARAMS ((tree, tree, tree, tree));
118 static int check_class_interface_creation PARAMS ((int, int, tree, 
119                                                   tree, tree, tree));
120 static tree patch_method_invocation PARAMS ((tree, tree, tree, 
121                                             int *, tree *));
122 static int breakdown_qualified PARAMS ((tree *, tree *, tree));
123 static tree resolve_and_layout PARAMS ((tree, tree));
124 static tree qualify_and_find PARAMS ((tree, tree, tree));
125 static tree resolve_no_layout PARAMS ((tree, tree));
126 static int invocation_mode PARAMS ((tree, int));
127 static tree find_applicable_accessible_methods_list PARAMS ((int, tree, 
128                                                             tree, tree));
129 static void search_applicable_methods_list PARAMS ((int, tree, tree, tree, 
130                                                    tree *, tree *));
131 static tree find_most_specific_methods_list PARAMS ((tree));
132 static int argument_types_convertible PARAMS ((tree, tree));
133 static tree patch_invoke PARAMS ((tree, tree, tree));
134 static int maybe_use_access_method PARAMS ((int, tree *, tree *));
135 static tree lookup_method_invoke PARAMS ((int, tree, tree, tree, tree));
136 static tree register_incomplete_type PARAMS ((int, tree, tree, tree));
137 static tree obtain_incomplete_type PARAMS ((tree));
138 static tree java_complete_lhs PARAMS ((tree));
139 static tree java_complete_tree PARAMS ((tree));
140 static tree maybe_generate_pre_expand_clinit PARAMS ((tree));
141 static int maybe_yank_clinit PARAMS ((tree));
142 static void java_complete_expand_method PARAMS ((tree));
143 static int  unresolved_type_p PARAMS ((tree, tree *));
144 static void create_jdep_list PARAMS ((struct parser_ctxt *));
145 static tree build_expr_block PARAMS ((tree, tree));
146 static tree enter_block PARAMS ((void));
147 static tree enter_a_block PARAMS ((tree));
148 static tree exit_block PARAMS ((void));
149 static tree lookup_name_in_blocks PARAMS ((tree));
150 static void maybe_absorb_scoping_blocks PARAMS ((void));
151 static tree build_method_invocation PARAMS ((tree, tree));
152 static tree build_new_invocation PARAMS ((tree, tree));
153 static tree build_assignment PARAMS ((int, int, tree, tree));
154 static tree build_binop PARAMS ((enum tree_code, int, tree, tree));
155 static int check_final_assignment PARAMS ((tree ,tree));
156 static tree patch_assignment PARAMS ((tree, tree, tree ));
157 static tree patch_binop PARAMS ((tree, tree, tree));
158 static tree build_unaryop PARAMS ((int, int, tree));
159 static tree build_incdec PARAMS ((int, int, tree, int));
160 static tree patch_unaryop PARAMS ((tree, tree));
161 static tree build_cast PARAMS ((int, tree, tree));
162 static tree build_null_of_type PARAMS ((tree));
163 static tree patch_cast PARAMS ((tree, tree));
164 static int valid_ref_assignconv_cast_p PARAMS ((tree, tree, int));
165 static int valid_builtin_assignconv_identity_widening_p PARAMS ((tree, tree));
166 static int valid_cast_to_p PARAMS ((tree, tree));
167 static int valid_method_invocation_conversion_p PARAMS ((tree, tree));
168 static tree try_builtin_assignconv PARAMS ((tree, tree, tree));
169 static tree try_reference_assignconv PARAMS ((tree, tree));
170 static tree build_unresolved_array_type PARAMS ((tree));
171 static tree build_array_from_name PARAMS ((tree, tree, tree, tree *));
172 static tree build_array_ref PARAMS ((int, tree, tree));
173 static tree patch_array_ref PARAMS ((tree));
174 static tree make_qualified_name PARAMS ((tree, tree, int));
175 static tree merge_qualified_name PARAMS ((tree, tree));
176 static tree make_qualified_primary PARAMS ((tree, tree, int));
177 static int resolve_qualified_expression_name PARAMS ((tree, tree *, 
178                                                      tree *, tree *));
179 static void qualify_ambiguous_name PARAMS ((tree));
180 static tree resolve_field_access PARAMS ((tree, tree *, tree *));
181 static tree build_newarray_node PARAMS ((tree, tree, int));
182 static tree patch_newarray PARAMS ((tree));
183 static tree resolve_type_during_patch PARAMS ((tree));
184 static tree build_this PARAMS ((int));
185 static tree build_wfl_wrap PARAMS ((tree, int));
186 static tree build_return PARAMS ((int, tree));
187 static tree patch_return PARAMS ((tree));
188 static tree maybe_access_field PARAMS ((tree, tree, tree));
189 static int complete_function_arguments PARAMS ((tree));
190 static int check_for_static_method_reference PARAMS ((tree, tree, tree, 
191                                                       tree, tree));
192 static int not_accessible_p PARAMS ((tree, tree, int));
193 static void check_deprecation PARAMS ((tree, tree));
194 static int class_in_current_package PARAMS ((tree));
195 static tree build_if_else_statement PARAMS ((int, tree, tree, tree));
196 static tree patch_if_else_statement PARAMS ((tree));
197 static tree add_stmt_to_compound PARAMS ((tree, tree, tree));
198 static tree add_stmt_to_block PARAMS ((tree, tree, tree));
199 static tree patch_exit_expr PARAMS ((tree));
200 static tree build_labeled_block PARAMS ((int, tree));
201 static tree finish_labeled_statement PARAMS ((tree, tree));
202 static tree build_bc_statement PARAMS ((int, int, tree));
203 static tree patch_bc_statement PARAMS ((tree));
204 static tree patch_loop_statement PARAMS ((tree));
205 static tree build_new_loop PARAMS ((tree));
206 static tree build_loop_body PARAMS ((int, tree, int));
207 static tree finish_loop_body PARAMS ((int, tree, tree, int));
208 static tree build_debugable_stmt PARAMS ((int, tree));
209 static tree finish_for_loop PARAMS ((int, tree, tree, tree));
210 static tree patch_switch_statement PARAMS ((tree));
211 static tree string_constant_concatenation PARAMS ((tree, tree));
212 static tree build_string_concatenation PARAMS ((tree, tree));
213 static tree patch_string_cst PARAMS ((tree));
214 static tree patch_string PARAMS ((tree));
215 static tree build_try_statement PARAMS ((int, tree, tree));
216 static tree build_try_finally_statement PARAMS ((int, tree, tree));
217 static tree patch_try_statement PARAMS ((tree));
218 static tree patch_synchronized_statement PARAMS ((tree, tree));
219 static tree patch_throw_statement PARAMS ((tree, tree));
220 static void check_thrown_exceptions PARAMS ((int, tree));
221 static int check_thrown_exceptions_do PARAMS ((tree));
222 static void purge_unchecked_exceptions PARAMS ((tree));
223 static void check_throws_clauses PARAMS ((tree, tree, tree));
224 static void finish_method_declaration PARAMS ((tree));
225 static tree build_super_invocation PARAMS ((tree));
226 static int verify_constructor_circularity PARAMS ((tree, tree));
227 static char *constructor_circularity_msg PARAMS ((tree, tree));
228 static tree build_this_super_qualified_invocation PARAMS ((int, tree, tree,
229                                                           int, int));
230 static const char *get_printable_method_name PARAMS ((tree));
231 static tree patch_conditional_expr PARAMS ((tree, tree, tree));
232 static tree generate_finit PARAMS ((tree));
233 static void add_instance_initializer PARAMS ((tree));
234 static void fix_constructors PARAMS ((tree));
235 static tree build_alias_initializer_parameter_list PARAMS ((int, tree,
236                                                             tree, int *));
237 static void craft_constructor PARAMS ((tree, tree));
238 static int verify_constructor_super PARAMS ((tree));
239 static tree create_artificial_method PARAMS ((tree, int, tree, tree, tree));
240 static void start_artificial_method_body PARAMS ((tree));
241 static void end_artificial_method_body PARAMS ((tree));
242 static int check_method_redefinition PARAMS ((tree, tree));
243 static int reset_method_name PARAMS ((tree));
244 static int check_method_types_complete PARAMS ((tree));
245 static void java_check_regular_methods PARAMS ((tree));
246 static void java_check_abstract_methods PARAMS ((tree));
247 static tree maybe_build_primttype_type_ref PARAMS ((tree, tree));
248 static void unreachable_stmt_error PARAMS ((tree));
249 static tree find_expr_with_wfl PARAMS ((tree));
250 static void missing_return_error PARAMS ((tree));
251 static tree build_new_array_init PARAMS ((int, tree));
252 static tree patch_new_array_init PARAMS ((tree, tree));
253 static tree maybe_build_array_element_wfl PARAMS ((tree));
254 static int array_constructor_check_entry PARAMS ((tree, tree));
255 static const char *purify_type_name PARAMS ((const char *));
256 static tree fold_constant_for_init PARAMS ((tree, tree));
257 static tree strip_out_static_field_access_decl PARAMS ((tree));
258 static jdeplist *reverse_jdep_list PARAMS ((struct parser_ctxt *));
259 static void static_ref_err PARAMS ((tree, tree, tree));
260 static void parser_add_interface PARAMS ((tree, tree, tree));
261 static void add_superinterfaces PARAMS ((tree, tree));
262 static tree jdep_resolve_class PARAMS ((jdep *));
263 static int note_possible_classname PARAMS ((const char *, int));
264 static void java_complete_expand_classes PARAMS ((void));
265 static void java_complete_expand_class PARAMS ((tree));
266 static void java_complete_expand_methods PARAMS ((tree));
267 static tree cut_identifier_in_qualified PARAMS ((tree));
268 static tree java_stabilize_reference PARAMS ((tree));
269 static tree do_unary_numeric_promotion PARAMS ((tree));
270 static char * operator_string PARAMS ((tree));
271 static tree do_merge_string_cste PARAMS ((tree, const char *, int, int));
272 static tree merge_string_cste PARAMS ((tree, tree, int));
273 static tree java_refold PARAMS ((tree));
274 static int java_decl_equiv PARAMS ((tree, tree));
275 static int binop_compound_p PARAMS ((enum tree_code));
276 static tree search_loop PARAMS ((tree));
277 static int labeled_block_contains_loop_p PARAMS ((tree, tree));
278 static void check_abstract_method_definitions PARAMS ((int, tree, tree));
279 static void java_check_abstract_method_definitions PARAMS ((tree));
280 static void java_debug_context_do PARAMS ((int));
281 static void java_parser_context_push_initialized_field PARAMS ((void));
282 static void java_parser_context_pop_initialized_field PARAMS ((void));
283 static tree reorder_static_initialized PARAMS ((tree));
284 static void java_parser_context_suspend PARAMS ((void));
285 static void java_parser_context_resume PARAMS ((void));
286
287 /* JDK 1.1 work. FIXME */
288
289 static tree maybe_make_nested_class_name PARAMS ((tree));
290 static void make_nested_class_name PARAMS ((tree));
291 static void set_nested_class_simple_name_value PARAMS ((tree, int));
292 static void link_nested_class_to_enclosing PARAMS ((void));
293 static tree find_as_inner_class PARAMS ((tree, tree, tree));
294 static tree find_as_inner_class_do PARAMS ((tree, tree));
295 static int check_inner_class_redefinition PARAMS ((tree, tree));
296
297 static tree build_thisn_assign PARAMS ((void));
298 static tree build_current_thisn PARAMS ((tree));
299 static tree build_access_to_thisn PARAMS ((tree, tree, int));
300 static tree maybe_build_thisn_access_method PARAMS ((tree));
301
302 static tree build_outer_field_access PARAMS ((tree, tree));
303 static tree build_outer_field_access_methods PARAMS ((tree));
304 static tree build_outer_field_access_expr PARAMS ((int, tree, tree, 
305                                                   tree, tree));
306 static tree build_outer_method_access_method PARAMS ((tree));
307 static tree build_new_access_id PARAMS ((void));
308 static tree build_outer_field_access_method PARAMS ((tree, tree, tree,
309                                                     tree, tree));
310
311 static int outer_field_access_p PARAMS ((tree, tree));
312 static int outer_field_expanded_access_p PARAMS ((tree, tree *, 
313                                                  tree *, tree *));
314 static tree outer_field_access_fix PARAMS ((tree, tree, tree));
315 static tree build_incomplete_class_ref PARAMS ((int, tree));
316 static tree patch_incomplete_class_ref PARAMS ((tree));
317 static tree create_anonymous_class PARAMS ((int, tree));
318 static void patch_anonymous_class PARAMS ((tree, tree, tree));
319 static void add_inner_class_fields PARAMS ((tree, tree));
320
321 static tree build_dot_class_method PARAMS ((tree));
322 static tree build_dot_class_method_invocation PARAMS ((tree));
323 static void create_new_parser_context PARAMS ((int));
324
325 /* Number of error found so far. */
326 int java_error_count; 
327 /* Number of warning found so far. */
328 int java_warning_count;
329 /* Tell when not to fold, when doing xrefs */
330 int do_not_fold;
331 /* Cyclic inheritance report, as it can be set by layout_class */
332 char *cyclic_inheritance_report;
333
334 /* Tell when we're within an instance initializer */
335 static int in_instance_initializer;
336
337 /* The current parser context */
338 struct parser_ctxt *ctxp;
339
340 /* List of things that were analyzed for which code will be generated */
341 static struct parser_ctxt *ctxp_for_generation = NULL;
342
343 /* binop_lookup maps token to tree_code. It is used where binary
344    operations are involved and required by the parser. RDIV_EXPR
345    covers both integral/floating point division. The code is changed
346    once the type of both operator is worked out.  */
347
348 static enum tree_code binop_lookup[19] = 
349   { 
350     PLUS_EXPR, MINUS_EXPR, MULT_EXPR, RDIV_EXPR, TRUNC_MOD_EXPR,
351     LSHIFT_EXPR, RSHIFT_EXPR, URSHIFT_EXPR, 
352     BIT_AND_EXPR, BIT_XOR_EXPR, BIT_IOR_EXPR,
353     TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR,
354     EQ_EXPR, NE_EXPR, GT_EXPR, GE_EXPR, LT_EXPR, LE_EXPR,
355    };
356 #define BINOP_LOOKUP(VALUE)                                             \
357   binop_lookup [((VALUE) - PLUS_TK)%                                    \
358                 (sizeof (binop_lookup) / sizeof (binop_lookup[0]))]
359
360 /* This is the end index for binary operators that can also be used
361    in compound assignements. */
362 #define BINOP_COMPOUND_CANDIDATES 11
363
364 /* Fake WFL used to report error message. It is initialized once if
365    needed and reused with it's location information is overriden.  */
366 tree wfl_operator = NULL_TREE;
367
368 /* The "$L" identifier we use to create labels.  */
369 static tree label_id = NULL_TREE;
370
371 /* The "StringBuffer" identifier used for the String `+' operator. */
372 static tree wfl_string_buffer = NULL_TREE; 
373
374 /* The "append" identifier used for String `+' operator.  */
375 static tree wfl_append = NULL_TREE;
376
377 /* The "toString" identifier used for String `+' operator. */
378 static tree wfl_to_string = NULL_TREE;
379
380 /* The "java.lang" import qualified name.  */
381 static tree java_lang_id = NULL_TREE;
382
383 /* The generated `inst$' identifier used for generated enclosing
384    instance/field access functions.  */
385 static tree inst_id = NULL_TREE;
386
387 /* The "java.lang.Cloneable" qualified name.  */
388 static tree java_lang_cloneable = NULL_TREE;
389
390 /* Context and flag for static blocks */
391 static tree current_static_block = NULL_TREE;
392
393 /* The generated `write_parm_value$' identifier.  */
394 static tree wpv_id;
395
396 /* The list of all packages we've seen so far */
397 static tree package_list = NULL_TREE;
398  
399 /* Check modifiers. If one doesn't fit, retrieve it in its declaration
400    line and point it out.  */
401 /* Should point out the one that don't fit. ASCII/unicode, going
402    backward. FIXME */
403
404 #define check_modifiers(__message, __value, __mask) do {        \
405   if ((__value) & ~(__mask))                                    \
406     {                                                           \
407       int i, remainder = (__value) & ~(__mask);                 \
408       for (i = 0; i <= 10; i++)                                 \
409         if ((1 << i) & remainder)                               \
410           parse_error_context (ctxp->modifier_ctx [i], (__message), \
411                                java_accstring_lookup (1 << i)); \
412     }                                                           \
413 } while (0)
414
415 %}
416
417 %union {
418   tree node;
419   int sub_token;
420   struct {
421     int token;
422     int location;
423   } operator;
424   int value;
425 }
426
427 %{
428 #include "lex.c"
429 %}
430
431 %pure_parser
432
433 /* Things defined here have to match the order of what's in the
434    binop_lookup table.  */
435
436 %token   PLUS_TK         MINUS_TK        MULT_TK         DIV_TK    REM_TK
437 %token   LS_TK           SRS_TK          ZRS_TK
438 %token   AND_TK          XOR_TK          OR_TK
439 %token   BOOL_AND_TK BOOL_OR_TK 
440 %token   EQ_TK NEQ_TK GT_TK GTE_TK LT_TK LTE_TK
441
442 /* This maps to the same binop_lookup entry than the token above */
443
444 %token   PLUS_ASSIGN_TK  MINUS_ASSIGN_TK MULT_ASSIGN_TK DIV_ASSIGN_TK
445 %token   REM_ASSIGN_TK   
446 %token   LS_ASSIGN_TK    SRS_ASSIGN_TK   ZRS_ASSIGN_TK
447 %token   AND_ASSIGN_TK   XOR_ASSIGN_TK   OR_ASSIGN_TK
448
449
450 /* Modifier TOKEN have to be kept in this order. Don't scramble it */
451
452 %token   PUBLIC_TK       PRIVATE_TK         PROTECTED_TK
453 %token   STATIC_TK       FINAL_TK           SYNCHRONIZED_TK
454 %token   VOLATILE_TK     TRANSIENT_TK       NATIVE_TK
455 %token   PAD_TK          ABSTRACT_TK        MODIFIER_TK
456
457 /* Keep those two in order, too */
458 %token   DECR_TK INCR_TK
459
460 /* From now one, things can be in any order */
461
462 %token   DEFAULT_TK      IF_TK              THROW_TK
463 %token   BOOLEAN_TK      DO_TK              IMPLEMENTS_TK
464 %token   THROWS_TK       BREAK_TK           IMPORT_TK       
465 %token   ELSE_TK         INSTANCEOF_TK      RETURN_TK
466 %token   VOID_TK         CATCH_TK           INTERFACE_TK
467 %token   CASE_TK         EXTENDS_TK         FINALLY_TK
468 %token   SUPER_TK        WHILE_TK           CLASS_TK
469 %token   SWITCH_TK       CONST_TK           TRY_TK
470 %token   FOR_TK          NEW_TK             CONTINUE_TK
471 %token   GOTO_TK         PACKAGE_TK         THIS_TK
472
473 %token   BYTE_TK         SHORT_TK           INT_TK            LONG_TK
474 %token   CHAR_TK         INTEGRAL_TK
475
476 %token   FLOAT_TK        DOUBLE_TK          FP_TK
477
478 %token   ID_TK
479
480 %token   REL_QM_TK         REL_CL_TK NOT_TK  NEG_TK
481
482 %token   ASSIGN_ANY_TK   ASSIGN_TK
483 %token   OP_TK  CP_TK  OCB_TK  CCB_TK  OSB_TK  CSB_TK  SC_TK  C_TK DOT_TK
484
485 %token   STRING_LIT_TK   CHAR_LIT_TK        INT_LIT_TK        FP_LIT_TK
486 %token   TRUE_TK         FALSE_TK           BOOL_LIT_TK       NULL_TK
487
488 %type    <value>        modifiers MODIFIER_TK final synchronized
489
490 %type    <node>         super ID_TK identifier
491 %type    <node>         name simple_name qualified_name
492 %type    <node>         type_declaration compilation_unit
493                         field_declaration method_declaration extends_interfaces
494                         interfaces interface_type_list
495                         class_member_declaration
496                         import_declarations package_declaration 
497                         type_declarations interface_body
498                         interface_member_declaration constant_declaration
499                         interface_member_declarations interface_type
500                         abstract_method_declaration interface_type_list
501 %type    <node>         class_body_declaration class_member_declaration
502                         static_initializer constructor_declaration block
503 %type    <node>         class_body_declarations constructor_header
504 %type    <node>         class_or_interface_type class_type class_type_list
505                         constructor_declarator explicit_constructor_invocation
506 %type    <node>         dim_expr dim_exprs this_or_super throws
507
508 %type    <node>         variable_declarator_id variable_declarator
509                         variable_declarators variable_initializer
510                         variable_initializers constructor_body
511                         array_initializer
512
513 %type    <node>         class_body block_end constructor_block_end
514 %type    <node>         statement statement_without_trailing_substatement
515                         labeled_statement if_then_statement label_decl
516                         if_then_else_statement while_statement for_statement
517                         statement_nsi labeled_statement_nsi do_statement
518                         if_then_else_statement_nsi while_statement_nsi
519                         for_statement_nsi statement_expression_list for_init
520                         for_update statement_expression expression_statement
521                         primary_no_new_array expression primary
522                         array_creation_expression array_type
523                         class_instance_creation_expression field_access
524                         method_invocation array_access something_dot_new
525                         argument_list postfix_expression while_expression 
526                         post_increment_expression post_decrement_expression
527                         unary_expression_not_plus_minus unary_expression
528                         pre_increment_expression pre_decrement_expression
529                         unary_expression_not_plus_minus cast_expression
530                         multiplicative_expression additive_expression
531                         shift_expression relational_expression 
532                         equality_expression and_expression 
533                         exclusive_or_expression inclusive_or_expression
534                         conditional_and_expression conditional_or_expression
535                         conditional_expression assignment_expression
536                         left_hand_side assignment for_header for_begin
537                         constant_expression do_statement_begin empty_statement
538                         switch_statement synchronized_statement throw_statement
539                         try_statement switch_expression switch_block
540                         catches catch_clause catch_clause_parameter finally
541                         anonymous_class_creation
542 %type    <node>         return_statement break_statement continue_statement
543
544 %type    <operator>     ASSIGN_TK      MULT_ASSIGN_TK  DIV_ASSIGN_TK  
545 %type    <operator>     REM_ASSIGN_TK  PLUS_ASSIGN_TK  MINUS_ASSIGN_TK
546 %type    <operator>     LS_ASSIGN_TK   SRS_ASSIGN_TK   ZRS_ASSIGN_TK
547 %type    <operator>     AND_ASSIGN_TK  XOR_ASSIGN_TK   OR_ASSIGN_TK
548 %type    <operator>     ASSIGN_ANY_TK  assignment_operator
549 %token   <operator>     EQ_TK GTE_TK ZRS_TK SRS_TK GT_TK LTE_TK LS_TK 
550 %token   <operator>     BOOL_AND_TK AND_TK BOOL_OR_TK OR_TK INCR_TK PLUS_TK
551 %token   <operator>     DECR_TK MINUS_TK MULT_TK DIV_TK XOR_TK REM_TK NEQ_TK
552 %token   <operator>     NEG_TK REL_QM_TK REL_CL_TK NOT_TK LT_TK OCB_TK CCB_TK
553 %token   <operator>     OP_TK OSB_TK DOT_TK THROW_TK INSTANCEOF_TK
554 %type    <operator>     THIS_TK SUPER_TK RETURN_TK BREAK_TK CONTINUE_TK 
555 %type    <operator>     CASE_TK DEFAULT_TK TRY_TK CATCH_TK SYNCHRONIZED_TK
556 %type    <operator>     NEW_TK
557
558 %type    <node>         method_body 
559         
560 %type    <node>         literal INT_LIT_TK FP_LIT_TK BOOL_LIT_TK CHAR_LIT_TK
561                         STRING_LIT_TK NULL_TK VOID_TK
562
563 %type    <node>         IF_TK WHILE_TK FOR_TK
564
565 %type    <node>         formal_parameter_list formal_parameter
566                         method_declarator method_header
567
568 %type    <node>         primitive_type reference_type type 
569                         BOOLEAN_TK INTEGRAL_TK FP_TK
570
571 /* Added or modified JDK 1.1 rule types  */
572 %type    <node>         type_literals array_type_literal
573
574 %%
575 /* 19.2 Production from 2.3: The Syntactic Grammar  */
576 goal:
577         compilation_unit
578                 {}
579 ;
580
581 /* 19.3 Productions from 3: Lexical structure  */
582 literal:
583         INT_LIT_TK
584 |       FP_LIT_TK
585 |       BOOL_LIT_TK
586 |       CHAR_LIT_TK
587 |       STRING_LIT_TK
588 |       NULL_TK
589 ;
590
591 /* 19.4 Productions from 4: Types, Values and Variables  */
592 type:
593         primitive_type
594 |       reference_type
595 ;
596
597 primitive_type:
598         INTEGRAL_TK
599 |       FP_TK
600 |       BOOLEAN_TK
601 ;
602
603 reference_type:
604         class_or_interface_type
605 |       array_type
606 ;
607
608 class_or_interface_type:
609         name
610 ;
611
612 class_type:
613         class_or_interface_type /* Default rule */
614 ;
615
616 interface_type:
617          class_or_interface_type
618 ;
619
620 array_type:
621         primitive_type OSB_TK CSB_TK
622                 { 
623                   $$ = build_java_array_type ($1, -1);
624                   CLASS_LOADED_P ($$) = 1;
625                 }
626 |       name OSB_TK CSB_TK
627                 { $$ = build_unresolved_array_type ($1); }
628 |       array_type OSB_TK CSB_TK
629                 { $$ = build_unresolved_array_type ($1); }
630 |       primitive_type OSB_TK error
631                 {RULE ("']' expected"); RECOVER;}
632 |       array_type OSB_TK error
633                 {RULE ("']' expected"); RECOVER;}
634 ;
635
636 /* 19.5 Productions from 6: Names  */
637 name:
638         simple_name             /* Default rule */
639 |       qualified_name          /* Default rule */
640 ;
641
642 simple_name:
643         identifier              /* Default rule */
644 ;
645
646 qualified_name:
647         name DOT_TK identifier
648                 { $$ = make_qualified_name ($1, $3, $2.location); }
649 ;
650
651 identifier:
652         ID_TK
653 ;
654
655 /* 19.6: Production from 7: Packages  */
656 compilation_unit:
657                 {$$ = NULL;}
658 |       package_declaration
659 |       import_declarations
660 |       type_declarations
661 |       package_declaration import_declarations
662 |       package_declaration type_declarations
663 |       import_declarations type_declarations
664 |       package_declaration import_declarations type_declarations
665 ;
666
667 import_declarations:
668         import_declaration
669                 {
670                   $$ = NULL;
671                 }
672 |       import_declarations import_declaration
673                 {
674                   $$ = NULL;
675                 }
676 ;
677
678 type_declarations:
679         type_declaration
680 |       type_declarations type_declaration
681 ;
682
683 package_declaration:
684         PACKAGE_TK name SC_TK
685                 { 
686                   ctxp->package = EXPR_WFL_NODE ($2);
687                   register_package (ctxp->package);
688                 }
689 |       PACKAGE_TK error
690                 {yyerror ("Missing name"); RECOVER;}
691 |       PACKAGE_TK name error
692                 {yyerror ("';' expected"); RECOVER;}
693 ;
694
695 import_declaration:
696         single_type_import_declaration
697 |       type_import_on_demand_declaration
698 ;
699
700 single_type_import_declaration:
701         IMPORT_TK name SC_TK
702                 {
703                   tree name = EXPR_WFL_NODE ($2), last_name;
704                   int   i = IDENTIFIER_LENGTH (name)-1;
705                   const char *last = &IDENTIFIER_POINTER (name)[i];
706                   while (last != IDENTIFIER_POINTER (name))
707                     {
708                       if (last [0] == '.')
709                         break;
710                       last--;
711                     }
712                   last_name = get_identifier (++last);
713                   if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (last_name))
714                     {
715                       tree err = find_name_in_single_imports (last_name);
716                       if (err && err != name)
717                         parse_error_context
718                           ($2, "Ambiguous class: `%s' and `%s'",
719                            IDENTIFIER_POINTER (name), 
720                            IDENTIFIER_POINTER (err));
721                       else
722                         REGISTER_IMPORT ($2, last_name);
723                     }
724                   else
725                     REGISTER_IMPORT ($2, last_name);
726                 }
727 |       IMPORT_TK error
728                 {yyerror ("Missing name"); RECOVER;}
729 |       IMPORT_TK name error
730                 {yyerror ("';' expected"); RECOVER;}
731 ;
732
733 type_import_on_demand_declaration:
734         IMPORT_TK name DOT_TK MULT_TK SC_TK
735                 {
736                   tree name = EXPR_WFL_NODE ($2);
737                   /* Don't import java.lang.* twice. */
738                   if (name != java_lang_id)
739                     {
740                       read_import_dir ($2);
741                       ctxp->import_demand_list = 
742                         chainon (ctxp->import_demand_list,
743                                  build_tree_list ($2, NULL_TREE));
744                     }
745                 }
746 |       IMPORT_TK name DOT_TK error
747                 {yyerror ("'*' expected"); RECOVER;}
748 |       IMPORT_TK name DOT_TK MULT_TK error
749                 {yyerror ("';' expected"); RECOVER;}
750 ;
751
752 type_declaration:
753         class_declaration
754                 { end_class_declaration (0); }
755 |       interface_declaration
756                 { end_class_declaration (0); }
757 |       SC_TK
758                 { $$ = NULL; }
759 |       error
760                 {
761                   YYERROR_NOW;
762                   yyerror ("Class or interface declaration expected");
763                 }
764 ;
765
766 /* 19.7 Shortened from the original:
767    modifiers: modifier | modifiers modifier
768    modifier: any of public...  */
769 modifiers:
770         MODIFIER_TK
771                 {
772                   $$ = (1 << $1);
773                 }
774 |       modifiers MODIFIER_TK
775                 {
776                   int acc = (1 << $2);
777                   if ($$ & acc)
778                     parse_error_context 
779                       (ctxp->modifier_ctx [$2], "Modifier `%s' declared twice",
780                        java_accstring_lookup (acc));
781                   else
782                     {
783                       $$ |= acc;
784                     }
785                 }
786 ;
787
788 /* 19.8.1 Production from $8.1: Class Declaration */
789 class_declaration:
790         modifiers CLASS_TK identifier super interfaces
791                 { create_class ($1, $3, $4, $5); }
792         class_body
793 |       CLASS_TK identifier super interfaces 
794                 { create_class (0, $2, $3, $4); }
795         class_body
796 |       modifiers CLASS_TK error
797                 {yyerror ("Missing class name"); RECOVER;}
798 |       CLASS_TK error
799                 {yyerror ("Missing class name"); RECOVER;}
800 |       CLASS_TK identifier error
801                 {
802                   if (!ctxp->class_err) yyerror ("'{' expected"); 
803                   DRECOVER(class1);
804                 }
805 |       modifiers CLASS_TK identifier error
806                 {if (!ctxp->class_err) yyerror ("'{' expected"); RECOVER;}
807 ;
808
809 super:
810                 { $$ = NULL; }
811 |       EXTENDS_TK class_type
812                 { $$ = $2; }
813 |       EXTENDS_TK class_type error
814                 {yyerror ("'{' expected"); ctxp->class_err=1;}
815 |       EXTENDS_TK error
816                 {yyerror ("Missing super class name"); ctxp->class_err=1;}
817 ;
818
819 interfaces:
820                 { $$ = NULL_TREE; }
821 |       IMPLEMENTS_TK interface_type_list
822                 { $$ = $2; }
823 |       IMPLEMENTS_TK error
824                 {
825                   ctxp->class_err=1;
826                   yyerror ("Missing interface name"); 
827                 }
828 ;
829
830 interface_type_list:
831         interface_type
832                 { 
833                   ctxp->interface_number = 1;
834                   $$ = build_tree_list ($1, NULL_TREE);
835                 }
836 |       interface_type_list C_TK interface_type
837                 { 
838                   ctxp->interface_number++;
839                   $$ = chainon ($1, build_tree_list ($3, NULL_TREE));
840                 }
841 |       interface_type_list C_TK error
842                 {yyerror ("Missing interface name"); RECOVER;}
843 ;
844
845 class_body:
846         OCB_TK CCB_TK
847                 { 
848                   /* Store the location of the `}' when doing xrefs */
849                   if (flag_emit_xref)
850                     DECL_END_SOURCE_LINE (GET_CPC ()) = 
851                       EXPR_WFL_ADD_COL ($2.location, 1);
852                   $$ = GET_CPC ();
853                 }
854 |       OCB_TK class_body_declarations CCB_TK
855                 { 
856                   /* Store the location of the `}' when doing xrefs */
857                   if (flag_emit_xref)
858                     DECL_END_SOURCE_LINE (GET_CPC ()) = 
859                       EXPR_WFL_ADD_COL ($3.location, 1);
860                   $$ = GET_CPC ();
861                 }
862 ;
863
864 class_body_declarations:
865         class_body_declaration
866 |       class_body_declarations class_body_declaration
867 ;
868
869 class_body_declaration:
870         class_member_declaration
871 |       static_initializer
872 |       constructor_declaration
873 |       block                   /* Added, JDK1.1, instance initializer */
874                 {
875                   TREE_CHAIN ($1) = CPC_INSTANCE_INITIALIZER_STMT (ctxp);
876                   SET_CPC_INSTANCE_INITIALIZER_STMT (ctxp, $1);
877                 }
878 ;
879
880 class_member_declaration:
881         field_declaration
882 |       field_declaration SC_TK
883                 { $$ = $1; }
884 |       method_declaration
885 |       class_declaration       /* Added, JDK1.1 inner classes */
886                 { end_class_declaration (1); }
887 |       interface_declaration   /* Added, JDK1.1 inner interfaces */
888                 { end_class_declaration (1); }
889 ;
890
891 /* 19.8.2 Productions from 8.3: Field Declarations  */
892 field_declaration:
893         type variable_declarators SC_TK
894                 { register_fields (0, $1, $2); }
895 |       modifiers type variable_declarators SC_TK
896                 {
897                   check_modifiers 
898                     ("Illegal modifier `%s' for field declaration",
899                      $1, FIELD_MODIFIERS);
900                   check_modifiers_consistency ($1);
901                   register_fields ($1, $2, $3);
902                 }
903 ;
904
905 variable_declarators:
906         /* Should we use build_decl_list () instead ? FIXME */
907         variable_declarator     /* Default rule */
908 |       variable_declarators C_TK variable_declarator
909                 { $$ = chainon ($1, $3); }
910 |       variable_declarators C_TK error
911                 {yyerror ("Missing term"); RECOVER;}
912 ;
913
914 variable_declarator:
915         variable_declarator_id
916                 { $$ = build_tree_list ($1, NULL_TREE); }
917 |       variable_declarator_id ASSIGN_TK variable_initializer
918                 { 
919                   if (java_error_count)
920                     $3 = NULL_TREE;
921                   $$ = build_tree_list 
922                     ($1, build_assignment ($2.token, $2.location, $1, $3));
923                 }
924 |       variable_declarator_id ASSIGN_TK error
925                 {
926                   yyerror ("Missing variable initializer");
927                   $$ = build_tree_list ($1, NULL_TREE);
928                   RECOVER;
929                 }
930 |       variable_declarator_id ASSIGN_TK variable_initializer error
931                 {
932                   yyerror ("';' expected");
933                   $$ = build_tree_list ($1, NULL_TREE);
934                   RECOVER;
935                 }
936 ;
937
938 variable_declarator_id:
939         identifier
940 |       variable_declarator_id OSB_TK CSB_TK
941                 { $$ = build_unresolved_array_type ($1); }
942 |       identifier error
943                 {yyerror ("Invalid declaration"); DRECOVER(vdi);}
944 |       variable_declarator_id OSB_TK error
945                 {yyerror ("']' expected"); DRECOVER(vdi);}
946 |       variable_declarator_id CSB_TK error
947                 {yyerror ("Unbalanced ']'"); DRECOVER(vdi);}
948 ;
949
950 variable_initializer:
951         expression
952 |       array_initializer
953 ;
954
955 /* 19.8.3 Productions from 8.4: Method Declarations  */
956 method_declaration:
957         method_header 
958                 {
959                   current_function_decl = $1;
960                   if (current_function_decl
961                       && TREE_CODE (current_function_decl) == FUNCTION_DECL)
962                     source_start_java_method (current_function_decl);
963                   else
964                     current_function_decl = NULL_TREE;
965                 }
966         method_body
967                 { finish_method_declaration ($3); }
968 |       method_header error
969                 {YYNOT_TWICE yyerror ("'{' expected"); RECOVER;}
970 ;
971
972 method_header:  
973         type method_declarator throws
974                 { $$ = method_header (0, $1, $2, $3); }
975 |       VOID_TK method_declarator throws
976                 { $$ = method_header (0, void_type_node, $2, $3); }
977 |       modifiers type method_declarator throws
978                 { $$ = method_header ($1, $2, $3, $4); }
979 |       modifiers VOID_TK method_declarator throws
980                 { $$ = method_header ($1, void_type_node, $3, $4); }
981 |       type error
982                 {
983                   yyerror ("Invalid method declaration, method name required");
984                   RECOVER;
985                 }
986 |       modifiers type error
987                 {RECOVER;}
988 |       VOID_TK error
989                 {yyerror ("Identifier expected"); RECOVER;}
990 |       modifiers VOID_TK error
991                 {yyerror ("Identifier expected"); RECOVER;}
992 |       modifiers error
993                 {
994                   yyerror ("Invalid method declaration, return type required");
995                   RECOVER;
996                 }
997 ;
998
999 method_declarator:
1000         identifier OP_TK CP_TK
1001                 { 
1002                   ctxp->formal_parameter_number = 0;
1003                   $$ = method_declarator ($1, NULL_TREE);
1004                 }
1005 |       identifier OP_TK formal_parameter_list CP_TK
1006                 { $$ = method_declarator ($1, $3); }
1007 |       method_declarator OSB_TK CSB_TK
1008                 {
1009                   EXPR_WFL_LINECOL (wfl_operator) = $2.location;
1010                   TREE_PURPOSE ($1) = 
1011                     build_unresolved_array_type (TREE_PURPOSE ($1));
1012                   parse_warning_context 
1013                     (wfl_operator, 
1014                      "Discouraged form of returned type specification");
1015                 }
1016 |       identifier OP_TK error
1017                 {yyerror ("')' expected"); DRECOVER(method_declarator);}
1018 |       method_declarator OSB_TK error
1019                 {yyerror ("']' expected"); RECOVER;}
1020 ;
1021
1022 formal_parameter_list:
1023         formal_parameter
1024                 {
1025                   ctxp->formal_parameter_number = 1;
1026                 }
1027 |       formal_parameter_list C_TK formal_parameter
1028                 {
1029                   ctxp->formal_parameter_number += 1;
1030                   $$ = chainon ($1, $3);
1031                 }
1032 |       formal_parameter_list C_TK error
1033                 { yyerror ("Missing formal parameter term"); RECOVER; }
1034 ;
1035
1036 formal_parameter:
1037         type variable_declarator_id
1038                 {
1039                   $$ = build_tree_list ($2, $1);
1040                 }
1041 |       final type variable_declarator_id /* Added, JDK1.1 final parms */
1042                 { 
1043                   $$ = build_tree_list ($3, $2);
1044                   ARG_FINAL_P ($$) = 1;
1045                 }
1046 |       type error
1047                 {
1048                   yyerror ("Missing identifier"); RECOVER;
1049                   $$ = NULL_TREE;
1050                 }
1051 |       final type error
1052                 {
1053                   yyerror ("Missing identifier"); RECOVER;
1054                   $$ = NULL_TREE;
1055                 }
1056 ;
1057
1058 final:
1059         modifiers
1060                 {
1061                   check_modifiers ("Illegal modifier `%s'. Only `final' was expected here",
1062                                    $1, ACC_FINAL);
1063                   if ($1 != ACC_FINAL)
1064                     MODIFIER_WFL (FINAL_TK) = build_wfl_node (NULL_TREE);
1065                 }
1066 ;
1067
1068 throws:
1069                 { $$ = NULL_TREE; }
1070 |       THROWS_TK class_type_list
1071                 { $$ = $2; }
1072 |       THROWS_TK error
1073                 {yyerror ("Missing class type term"); RECOVER;}
1074 ;
1075
1076 class_type_list:
1077         class_type
1078                 { $$ = build_tree_list ($1, $1); }
1079 |       class_type_list C_TK class_type
1080                 { $$ = tree_cons ($3, $3, $1); }
1081 |       class_type_list C_TK error
1082                 {yyerror ("Missing class type term"); RECOVER;}
1083 ;
1084
1085 method_body:
1086         block
1087 |       block SC_TK
1088 |       SC_TK
1089                 { $$ = NULL_TREE; } /* Probably not the right thing to do. */
1090 ;
1091
1092 /* 19.8.4 Productions from 8.5: Static Initializers  */
1093 static_initializer:
1094         static block
1095                 {
1096                   TREE_CHAIN ($2) = CPC_STATIC_INITIALIZER_STMT (ctxp);
1097                   SET_CPC_STATIC_INITIALIZER_STMT (ctxp, $2);
1098                 }
1099 |       static block SC_TK      /* Shouldn't be here. FIXME */
1100                 {
1101                   TREE_CHAIN ($2) = CPC_STATIC_INITIALIZER_STMT (ctxp);
1102                   SET_CPC_STATIC_INITIALIZER_STMT (ctxp, $2);
1103                 }
1104 ;
1105
1106 static:                         /* Test lval.sub_token here */
1107         modifiers
1108                 {
1109                   check_modifiers ("Illegal modifier `%s' for static initializer", $1, ACC_STATIC);
1110                   /* Can't have a static initializer in an innerclass */
1111                   if ($1 | ACC_STATIC &&
1112                       GET_CPC_LIST () && !TOPLEVEL_CLASS_DECL_P (GET_CPC ()))
1113                     parse_error_context 
1114                       (MODIFIER_WFL (STATIC_TK),
1115                        "Can't define static initializer in class `%s'. Static initializer can only be defined in top-level classes",
1116                        IDENTIFIER_POINTER (DECL_NAME (GET_CPC ())));
1117                   SOURCE_FRONTEND_DEBUG (("Modifiers: %d", $1));
1118                 }
1119 ;
1120
1121 /* 19.8.5 Productions from 8.6: Constructor Declarations  */
1122 constructor_declaration:
1123         constructor_header
1124                 {
1125                   current_function_decl = $1;
1126                   source_start_java_method (current_function_decl);
1127                 }
1128         constructor_body
1129                 { finish_method_declaration ($3); }
1130 ;
1131
1132 constructor_header:
1133         constructor_declarator throws
1134                 { $$ = method_header (0, NULL_TREE, $1, $2); }
1135 |       modifiers constructor_declarator throws
1136                 { $$ = method_header ($1, NULL_TREE, $2, $3); }
1137 ;
1138
1139 constructor_declarator:
1140         simple_name OP_TK CP_TK
1141                 { 
1142                   ctxp->formal_parameter_number = 0;  
1143                   $$ = method_declarator ($1, NULL_TREE);
1144                 }
1145 |       simple_name OP_TK formal_parameter_list CP_TK
1146                 { $$ = method_declarator ($1, $3); }
1147 ;
1148
1149 constructor_body:
1150         /* Unlike regular method, we always need a complete (empty)
1151            body so we can safely perform all the required code
1152            addition (super invocation and field initialization) */
1153         block_begin constructor_block_end
1154                 { 
1155                   BLOCK_EXPR_BODY ($2) = empty_stmt_node;
1156                   $$ = $2;
1157                 }
1158 |       block_begin explicit_constructor_invocation constructor_block_end
1159                 { $$ = $3; }
1160 |       block_begin block_statements constructor_block_end
1161                 { $$ = $3; }
1162 |       block_begin explicit_constructor_invocation block_statements constructor_block_end
1163                 { $$ = $4; }
1164 ;
1165
1166 constructor_block_end:
1167         block_end
1168 |       block_end SC_TK
1169
1170 /* Error recovery for that rule moved down expression_statement: rule.  */
1171 explicit_constructor_invocation:
1172         this_or_super OP_TK CP_TK SC_TK
1173                 { 
1174                   $$ = build_method_invocation ($1, NULL_TREE); 
1175                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $$);
1176                   $$ = java_method_add_stmt (current_function_decl, $$);
1177                 }
1178 |       this_or_super OP_TK argument_list CP_TK SC_TK
1179                 { 
1180                   $$ = build_method_invocation ($1, $3); 
1181                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $$);
1182                   $$ = java_method_add_stmt (current_function_decl, $$);
1183                 }
1184         /* Added, JDK1.1 inner classes. Modified because the rule
1185            'primary' couldn't work.  */
1186 |       name DOT_TK SUPER_TK OP_TK argument_list CP_TK SC_TK
1187                 {$$ = parse_jdk1_1_error ("explicit constructor invocation"); }
1188 |       name DOT_TK SUPER_TK OP_TK CP_TK SC_TK
1189                 {$$ = parse_jdk1_1_error ("explicit constructor invocation"); }
1190 ;
1191
1192 this_or_super:                  /* Added, simplifies error diagnostics */
1193         THIS_TK
1194                 {
1195                   tree wfl = build_wfl_node (this_identifier_node);
1196                   EXPR_WFL_LINECOL (wfl) = $1.location;
1197                   $$ = wfl;
1198                 }
1199 |       SUPER_TK
1200                 {
1201                   tree wfl = build_wfl_node (super_identifier_node);
1202                   EXPR_WFL_LINECOL (wfl) = $1.location;
1203                   $$ = wfl;
1204                 }
1205 ;
1206
1207 /* 19.9 Productions from 9: Interfaces  */
1208 /* 19.9.1 Productions from 9.1: Interfaces Declarations  */
1209 interface_declaration:
1210         INTERFACE_TK identifier
1211                 { create_interface (0, $2, NULL_TREE); }
1212         interface_body
1213 |       modifiers INTERFACE_TK identifier
1214                 { create_interface ($1, $3, NULL_TREE); }
1215         interface_body
1216 |       INTERFACE_TK identifier extends_interfaces
1217                 { create_interface (0, $2, $3); }
1218         interface_body
1219 |       modifiers INTERFACE_TK identifier extends_interfaces
1220                 { create_interface ($1, $3, $4); }
1221         interface_body
1222 |       INTERFACE_TK identifier error
1223                 {yyerror ("'{' expected"); RECOVER;}
1224 |       modifiers INTERFACE_TK identifier error
1225                 {yyerror ("'{' expected"); RECOVER;}
1226 ;
1227
1228 extends_interfaces:
1229         EXTENDS_TK interface_type
1230                 { 
1231                   ctxp->interface_number = 1;
1232                   $$ = build_tree_list ($2, NULL_TREE);
1233                 }
1234 |       extends_interfaces C_TK interface_type
1235                 { 
1236                   ctxp->interface_number++;
1237                   $$ = chainon ($1, build_tree_list ($3, NULL_TREE));
1238                 }
1239 |       EXTENDS_TK error
1240                 {yyerror ("Invalid interface type"); RECOVER;}
1241 |       extends_interfaces C_TK error
1242                 {yyerror ("Missing term"); RECOVER;}
1243 ;
1244
1245 interface_body:
1246         OCB_TK CCB_TK
1247                 { $$ = NULL_TREE; }
1248 |       OCB_TK interface_member_declarations CCB_TK
1249                 { $$ = NULL_TREE; }
1250 ;
1251
1252 interface_member_declarations:
1253         interface_member_declaration
1254 |       interface_member_declarations interface_member_declaration
1255 ;
1256
1257 interface_member_declaration:
1258         constant_declaration
1259 |       abstract_method_declaration
1260 |       class_declaration       /* Added, JDK1.1 inner classes */
1261                 { end_class_declaration (1); }
1262 |       interface_declaration   /* Added, JDK1.1 inner interfaces */
1263                 { end_class_declaration (1); }
1264 ;
1265
1266 constant_declaration:
1267         field_declaration
1268 ;
1269
1270 abstract_method_declaration:
1271         method_header SC_TK
1272                 { 
1273                   check_abstract_method_header ($1);
1274                   current_function_decl = NULL_TREE; /* FIXME ? */
1275                 }
1276 |       method_header error
1277                 {yyerror ("';' expected"); RECOVER;}
1278 ;
1279
1280 /* 19.10 Productions from 10: Arrays  */
1281 array_initializer:
1282         OCB_TK CCB_TK
1283                 { $$ = build_new_array_init ($1.location, NULL_TREE); }
1284 |       OCB_TK variable_initializers CCB_TK
1285                 { $$ = build_new_array_init ($1.location, $2); }
1286 |       OCB_TK variable_initializers C_TK CCB_TK
1287                 { $$ = build_new_array_init ($1.location, $2); }
1288 ;
1289
1290 variable_initializers:
1291         variable_initializer
1292                 { 
1293                   $$ = tree_cons (maybe_build_array_element_wfl ($1), 
1294                                   $1, NULL_TREE);
1295                 }
1296 |       variable_initializers C_TK variable_initializer
1297                 {
1298                   $$ = tree_cons (maybe_build_array_element_wfl ($3), $3, $1);
1299                 }
1300 |       variable_initializers C_TK error
1301                 {yyerror ("Missing term"); RECOVER;}
1302 ;
1303
1304 /* 19.11 Production from 14: Blocks and Statements  */
1305 block:
1306         OCB_TK CCB_TK
1307                 { 
1308                   /* Store the location of the `}' when doing xrefs */
1309                   if (current_function_decl && flag_emit_xref)
1310                     DECL_END_SOURCE_LINE (current_function_decl) = 
1311                       EXPR_WFL_ADD_COL ($2.location, 1);
1312                   $$ = empty_stmt_node; 
1313                 }
1314 |       block_begin block_statements block_end
1315                 { $$ = $3; }
1316 ;
1317
1318 block_begin:
1319         OCB_TK
1320                 { enter_block (); }
1321 ;
1322
1323 block_end:
1324         CCB_TK
1325                 { 
1326                   maybe_absorb_scoping_blocks ();
1327                   /* Store the location of the `}' when doing xrefs */
1328                   if (current_function_decl && flag_emit_xref)
1329                     DECL_END_SOURCE_LINE (current_function_decl) = 
1330                       EXPR_WFL_ADD_COL ($1.location, 1);                  
1331                   $$ = exit_block ();
1332                   if (!BLOCK_SUBBLOCKS ($$))
1333                     BLOCK_SUBBLOCKS ($$) = empty_stmt_node;
1334                 }
1335 ;
1336
1337 block_statements:
1338         block_statement
1339 |       block_statements block_statement
1340 ;
1341
1342 block_statement:
1343         local_variable_declaration_statement
1344 |       statement
1345                 { java_method_add_stmt (current_function_decl, $1); }
1346 |       class_declaration       /* Added, JDK1.1 local classes */
1347                 { 
1348                   LOCAL_CLASS_P (TREE_TYPE (GET_CPC ())) = 1;
1349                   end_class_declaration (1);
1350                 }
1351 ;
1352
1353 local_variable_declaration_statement:
1354         local_variable_declaration SC_TK /* Can't catch missing ';' here */
1355 ;
1356
1357 local_variable_declaration:
1358         type variable_declarators
1359                 { declare_local_variables (0, $1, $2); }
1360 |       final type variable_declarators /* Added, JDK1.1 final locals */
1361                 { declare_local_variables ($1, $2, $3); }
1362 ;
1363
1364 statement:
1365         statement_without_trailing_substatement
1366 |       labeled_statement
1367 |       if_then_statement
1368 |       if_then_else_statement
1369 |       while_statement
1370 |       for_statement
1371                 { $$ = exit_block (); }
1372 ;
1373
1374 statement_nsi:
1375         statement_without_trailing_substatement
1376 |       labeled_statement_nsi
1377 |       if_then_else_statement_nsi
1378 |       while_statement_nsi
1379 |       for_statement_nsi
1380                 { $$ = exit_block (); }
1381 ;
1382
1383 statement_without_trailing_substatement:
1384         block
1385 |       empty_statement
1386 |       expression_statement
1387 |       switch_statement
1388 |       do_statement
1389 |       break_statement
1390 |       continue_statement
1391 |       return_statement
1392 |       synchronized_statement
1393 |       throw_statement
1394 |       try_statement
1395 ;
1396
1397 empty_statement:
1398         SC_TK
1399                 { $$ = empty_stmt_node; }
1400 ;
1401
1402 label_decl:
1403         identifier REL_CL_TK
1404                 {
1405                   $$ = build_labeled_block (EXPR_WFL_LINECOL ($1), 
1406                                             EXPR_WFL_NODE ($1));
1407                   pushlevel (2);
1408                   push_labeled_block ($$);
1409                   PUSH_LABELED_BLOCK ($$);
1410                 }
1411 ;
1412
1413 labeled_statement:
1414         label_decl statement
1415                 { $$ = finish_labeled_statement ($1, $2); }
1416 |       identifier error
1417                 {yyerror ("':' expected"); RECOVER;}
1418 ;
1419
1420 labeled_statement_nsi:
1421         label_decl statement_nsi
1422                 { $$ = finish_labeled_statement ($1, $2); }
1423 ;
1424
1425 /* We concentrate here a bunch of error handling rules that we couldn't write
1426    earlier, because expression_statement catches a missing ';'.  */
1427 expression_statement:
1428         statement_expression SC_TK
1429                 {
1430                   /* We have a statement. Generate a WFL around it so
1431                      we can debug it */
1432                   $$ = build_expr_wfl ($1, input_filename, lineno, 0);
1433                   /* We know we have a statement, so set the debug
1434                      info to be eventually generate here. */
1435                   $$ = JAVA_MAYBE_GENERATE_DEBUG_INFO ($$);
1436                 }
1437 |       error SC_TK 
1438                 {
1439                   if (ctxp->prevent_ese != lineno)
1440                     yyerror ("Invalid expression statement");
1441                   DRECOVER (expr_stmt);
1442                 }
1443 |       error OCB_TK
1444                 {
1445                   if (ctxp->prevent_ese != lineno)
1446                     yyerror ("Invalid expression statement");
1447                   DRECOVER (expr_stmt);
1448                 }
1449 |       error CCB_TK
1450                 {
1451                   if (ctxp->prevent_ese != lineno)
1452                     yyerror ("Invalid expression statement");
1453                   DRECOVER (expr_stmt);
1454                 }
1455 |       this_or_super OP_TK error
1456                 {yyerror ("')' expected"); RECOVER;}
1457 |       this_or_super OP_TK CP_TK error
1458                 {
1459                   parse_ctor_invocation_error ();
1460                   RECOVER;
1461                 }
1462 |       this_or_super OP_TK argument_list error
1463                 {yyerror ("')' expected"); RECOVER;}
1464 |       this_or_super OP_TK argument_list CP_TK error
1465                 {
1466                   parse_ctor_invocation_error ();
1467                   RECOVER;
1468                 }
1469 |       name DOT_TK SUPER_TK error
1470                 {yyerror ("'(' expected"); RECOVER;}
1471 |       name DOT_TK SUPER_TK OP_TK error
1472                 {yyerror ("')' expected"); RECOVER;}
1473 |       name DOT_TK SUPER_TK OP_TK argument_list error
1474                 {yyerror ("')' expected"); RECOVER;}
1475 |       name DOT_TK SUPER_TK OP_TK argument_list CP_TK error
1476                 {yyerror ("';' expected"); RECOVER;}
1477 |       name DOT_TK SUPER_TK OP_TK CP_TK error
1478                 {yyerror ("';' expected"); RECOVER;}
1479 ;
1480
1481 statement_expression: 
1482         assignment
1483 |       pre_increment_expression
1484 |       pre_decrement_expression
1485 |       post_increment_expression
1486 |       post_decrement_expression
1487 |       method_invocation
1488 |       class_instance_creation_expression
1489 ;
1490
1491 if_then_statement:
1492         IF_TK OP_TK expression CP_TK statement
1493                 { 
1494                   $$ = build_if_else_statement ($2.location, $3, 
1495                                                 $5, NULL_TREE);
1496                 }
1497 |       IF_TK error
1498                 {yyerror ("'(' expected"); RECOVER;}
1499 |       IF_TK OP_TK error
1500                 {yyerror ("Missing term"); RECOVER;}
1501 |       IF_TK OP_TK expression error
1502                 {yyerror ("')' expected"); RECOVER;}
1503 ;
1504
1505 if_then_else_statement:
1506         IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement
1507                 { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
1508 ;
1509
1510 if_then_else_statement_nsi:
1511         IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement_nsi
1512                 { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
1513 ;
1514
1515 switch_statement:
1516         switch_expression
1517                 {
1518                   enter_block ();
1519                 }
1520         switch_block
1521                 { 
1522                   /* Make into "proper list" of COMPOUND_EXPRs.
1523                      I.e. make the last statment also have its own
1524                      COMPOUND_EXPR. */
1525                   maybe_absorb_scoping_blocks ();
1526                   TREE_OPERAND ($1, 1) = exit_block ();
1527                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $1);
1528                 }
1529 ;
1530
1531 switch_expression:
1532         SWITCH_TK OP_TK expression CP_TK
1533                 { 
1534                   $$ = build (SWITCH_EXPR, NULL_TREE, $3, NULL_TREE);
1535                   EXPR_WFL_LINECOL ($$) = $2.location;
1536                 }
1537 |       SWITCH_TK error
1538                 {yyerror ("'(' expected"); RECOVER;}
1539 |       SWITCH_TK OP_TK error
1540                 {yyerror ("Missing term or ')'"); DRECOVER(switch_statement);}
1541 |       SWITCH_TK OP_TK expression CP_TK error
1542                 {yyerror ("'{' expected"); RECOVER;}
1543 ;
1544
1545 /* Default assignment is there to avoid type node on switch_block
1546    node. */
1547
1548 switch_block:
1549         OCB_TK CCB_TK
1550                 { $$ = NULL_TREE; }
1551 |       OCB_TK switch_labels CCB_TK
1552                 { $$ = NULL_TREE; }
1553 |       OCB_TK switch_block_statement_groups CCB_TK
1554                 { $$ = NULL_TREE; }
1555 |       OCB_TK switch_block_statement_groups switch_labels CCB_TK
1556                 { $$ = NULL_TREE; }
1557 ;
1558
1559 switch_block_statement_groups: 
1560         switch_block_statement_group
1561 |       switch_block_statement_groups switch_block_statement_group
1562 ;
1563
1564 switch_block_statement_group:
1565         switch_labels block_statements
1566 ;
1567
1568 switch_labels:
1569         switch_label
1570 |       switch_labels switch_label
1571 ;
1572
1573 switch_label:
1574         CASE_TK constant_expression REL_CL_TK
1575                 { 
1576                   tree lab = build1 (CASE_EXPR, NULL_TREE, $2);
1577                   EXPR_WFL_LINECOL (lab) = $1.location;
1578                   java_method_add_stmt (current_function_decl, lab);
1579                 }
1580 |       DEFAULT_TK REL_CL_TK
1581                 { 
1582                   tree lab = build1 (DEFAULT_EXPR, NULL_TREE, NULL_TREE);
1583                   EXPR_WFL_LINECOL (lab) = $1.location;
1584                   java_method_add_stmt (current_function_decl, lab);
1585                 }
1586 |       CASE_TK error
1587                 {yyerror ("Missing or invalid constant expression"); RECOVER;}
1588 |       CASE_TK constant_expression error
1589                 {yyerror ("':' expected"); RECOVER;}
1590 |       DEFAULT_TK error
1591                 {yyerror ("':' expected"); RECOVER;}
1592 ;
1593
1594 while_expression:
1595         WHILE_TK OP_TK expression CP_TK
1596                 { 
1597                   tree body = build_loop_body ($2.location, $3, 0);
1598                   $$ = build_new_loop (body);
1599                 }
1600 ;
1601
1602 while_statement:
1603         while_expression statement
1604                 { $$ = finish_loop_body (0, NULL_TREE, $2, 0); }
1605 |       WHILE_TK error
1606                 {YYERROR_NOW; yyerror ("'(' expected"); RECOVER;}
1607 |       WHILE_TK OP_TK error
1608                 {yyerror ("Missing term and ')' expected"); RECOVER;}
1609 |       WHILE_TK OP_TK expression error
1610                 {yyerror ("')' expected"); RECOVER;}
1611 ;
1612
1613 while_statement_nsi:
1614         while_expression statement_nsi
1615                 { $$ = finish_loop_body (0, NULL_TREE, $2, 0); }
1616 ;
1617
1618 do_statement_begin:
1619         DO_TK
1620                 { 
1621                   tree body = build_loop_body (0, NULL_TREE, 1);
1622                   $$ = build_new_loop (body);
1623                 }
1624         /* Need error handing here. FIXME */
1625 ;
1626
1627 do_statement: 
1628         do_statement_begin statement WHILE_TK OP_TK expression CP_TK SC_TK
1629                 { $$ = finish_loop_body ($4.location, $5, $2, 1); }
1630 ;
1631
1632 for_statement:
1633         for_begin SC_TK expression SC_TK for_update CP_TK statement
1634                 { $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7); }
1635 |       for_begin SC_TK SC_TK for_update CP_TK statement
1636                 { 
1637                   $$ = finish_for_loop (0, NULL_TREE, $4, $6);
1638                   /* We have not condition, so we get rid of the EXIT_EXPR */
1639                   LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) = 
1640                     empty_stmt_node;
1641                 }
1642 |       for_begin SC_TK error
1643                 {yyerror ("Invalid control expression"); RECOVER;}
1644 |       for_begin SC_TK expression SC_TK error
1645                 {yyerror ("Invalid update expression"); RECOVER;}
1646 |       for_begin SC_TK SC_TK error
1647                 {yyerror ("Invalid update expression"); RECOVER;}
1648 ;
1649
1650 for_statement_nsi:
1651         for_begin SC_TK expression SC_TK for_update CP_TK statement_nsi
1652                 { $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7);}
1653 |       for_begin SC_TK SC_TK for_update CP_TK statement_nsi
1654                 { 
1655                   $$ = finish_for_loop (0, NULL_TREE, $4, $6);
1656                   /* We have not condition, so we get rid of the EXIT_EXPR */
1657                   LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) = 
1658                     empty_stmt_node;
1659                 }
1660 ;
1661
1662 for_header:
1663         FOR_TK OP_TK
1664                 { 
1665                   /* This scope defined for local variable that may be
1666                      defined within the scope of the for loop */
1667                   enter_block (); 
1668                 }
1669 |       FOR_TK error
1670                 {yyerror ("'(' expected"); DRECOVER(for_1);}
1671 |       FOR_TK OP_TK error
1672                 {yyerror ("Invalid init statement"); RECOVER;}
1673 ;
1674
1675 for_begin:
1676         for_header for_init
1677                 { 
1678                   /* We now declare the loop body. The loop is
1679                      declared as a for loop. */
1680                   tree body = build_loop_body (0, NULL_TREE, 0);
1681                   $$ =  build_new_loop (body);
1682                   FOR_LOOP_P ($$) = 1;
1683                   /* The loop is added to the current block the for
1684                      statement is defined within */
1685                   java_method_add_stmt (current_function_decl, $$);
1686                 }
1687 ;
1688 for_init:                       /* Can be empty */
1689                 { $$ = empty_stmt_node; }
1690 |       statement_expression_list
1691                 { 
1692                   /* Init statement recorded within the previously
1693                      defined block scope */
1694                   $$ = java_method_add_stmt (current_function_decl, $1);
1695                 }
1696 |       local_variable_declaration
1697                 { 
1698                   /* Local variable are recorded within the previously
1699                      defined block scope */
1700                   $$ = NULL_TREE;
1701                 }
1702 |       statement_expression_list error
1703                 {yyerror ("';' expected"); DRECOVER(for_init_1);}
1704 ;
1705
1706 for_update:                     /* Can be empty */
1707                 {$$ = empty_stmt_node;}
1708 |       statement_expression_list
1709                 { $$ = build_debugable_stmt (BUILD_LOCATION (), $1); }
1710 ;
1711
1712 statement_expression_list:
1713         statement_expression
1714                 { $$ = add_stmt_to_compound (NULL_TREE, NULL_TREE, $1); }
1715 |       statement_expression_list C_TK statement_expression
1716                 { $$ = add_stmt_to_compound ($1, NULL_TREE, $3); }
1717 |       statement_expression_list C_TK error
1718                 {yyerror ("Missing term"); RECOVER;}
1719 ;
1720
1721 break_statement:
1722         BREAK_TK SC_TK
1723                 { $$ = build_bc_statement ($1.location, 1, NULL_TREE); }
1724 |       BREAK_TK identifier SC_TK
1725                 { $$ = build_bc_statement ($1.location, 1, $2); }
1726 |       BREAK_TK error
1727                 {yyerror ("Missing term"); RECOVER;}
1728 |       BREAK_TK identifier error
1729                 {yyerror ("';' expected"); RECOVER;}
1730 ;
1731
1732 continue_statement:
1733         CONTINUE_TK SC_TK
1734                 { $$ = build_bc_statement ($1.location, 0, NULL_TREE); }
1735 |       CONTINUE_TK identifier SC_TK
1736                 { $$ = build_bc_statement ($1.location, 0, $2); }
1737 |       CONTINUE_TK error
1738                 {yyerror ("Missing term"); RECOVER;}
1739 |       CONTINUE_TK identifier error
1740                 {yyerror ("';' expected"); RECOVER;}
1741 ;
1742
1743 return_statement:
1744         RETURN_TK SC_TK
1745                 { $$ = build_return ($1.location, NULL_TREE); }
1746 |       RETURN_TK expression SC_TK
1747                 { $$ = build_return ($1.location, $2); }
1748 |       RETURN_TK error
1749                 {yyerror ("Missing term"); RECOVER;}
1750 |       RETURN_TK expression error
1751                 {yyerror ("';' expected"); RECOVER;}
1752 ;
1753
1754 throw_statement:
1755         THROW_TK expression SC_TK
1756                 { 
1757                   $$ = build1 (THROW_EXPR, NULL_TREE, $2);
1758                   EXPR_WFL_LINECOL ($$) = $1.location;
1759                 }
1760 |       THROW_TK error
1761                 {yyerror ("Missing term"); RECOVER;}
1762 |       THROW_TK expression error
1763                 {yyerror ("';' expected"); RECOVER;}
1764 ;
1765
1766 synchronized_statement:
1767         synchronized OP_TK expression CP_TK block
1768                 { 
1769                   $$ = build (SYNCHRONIZED_EXPR, NULL_TREE, $3, $5);
1770                   EXPR_WFL_LINECOL ($$) = 
1771                     EXPR_WFL_LINECOL (MODIFIER_WFL (SYNCHRONIZED_TK));
1772                 }
1773 |       synchronized OP_TK expression CP_TK error
1774                 {yyerror ("'{' expected"); RECOVER;}
1775 |       synchronized error
1776                 {yyerror ("'(' expected"); RECOVER;}
1777 |       synchronized OP_TK error CP_TK
1778                 {yyerror ("Missing term"); RECOVER;}
1779 |       synchronized OP_TK error
1780                 {yyerror ("Missing term"); RECOVER;}
1781 ;
1782
1783 synchronized:
1784         modifiers
1785                 {
1786                   check_modifiers (
1787              "Illegal modifier `%s'. Only `synchronized' was expected here",
1788                                    $1, ACC_SYNCHRONIZED);
1789                   if ($1 != ACC_SYNCHRONIZED)
1790                     MODIFIER_WFL (SYNCHRONIZED_TK) = 
1791                       build_wfl_node (NULL_TREE);
1792                 }
1793 ;
1794
1795 try_statement:
1796         TRY_TK block catches
1797                 { $$ = build_try_statement ($1.location, $2, $3); }
1798 |       TRY_TK block finally
1799                 { $$ = build_try_finally_statement ($1.location, $2, $3); }
1800 |       TRY_TK block catches finally
1801                 { $$ = build_try_finally_statement 
1802                     ($1.location, build_try_statement ($1.location,
1803                                                        $2, $3), $4);
1804                 }
1805 |       TRY_TK error
1806                 {yyerror ("'{' expected"); DRECOVER (try_statement);}
1807 ;
1808
1809 catches:
1810         catch_clause
1811 |       catches catch_clause
1812                 { 
1813                   TREE_CHAIN ($2) = $1;
1814                   $$ = $2;
1815                 }
1816 ;
1817
1818 catch_clause:
1819         catch_clause_parameter block
1820                 { 
1821                   java_method_add_stmt (current_function_decl, $2);
1822                   exit_block ();
1823                   $$ = $1;
1824                 }
1825
1826 catch_clause_parameter:
1827         CATCH_TK OP_TK formal_parameter CP_TK
1828                 { 
1829                   /* We add a block to define a scope for
1830                      formal_parameter (CCBP). The formal parameter is
1831                      declared initialized by the appropriate function
1832                      call */
1833                   tree ccpb = enter_block ();
1834                   tree init = build_assignment (ASSIGN_TK, $2.location, 
1835                                                 TREE_PURPOSE ($3), 
1836                                                 soft_exceptioninfo_call_node);
1837                   declare_local_variables (0, TREE_VALUE ($3),
1838                                            build_tree_list (TREE_PURPOSE ($3),
1839                                                             init));
1840                   $$ = build1 (CATCH_EXPR, NULL_TREE, ccpb);
1841                   EXPR_WFL_LINECOL ($$) = $1.location;
1842                 }
1843 |       CATCH_TK error
1844                 {yyerror ("'(' expected"); RECOVER; $$ = NULL_TREE;}
1845 |       CATCH_TK OP_TK error 
1846                 {
1847                   yyerror ("Missing term or ')' expected"); 
1848                   RECOVER; $$ = NULL_TREE;
1849                 }
1850 |       CATCH_TK OP_TK error CP_TK /* That's for () */
1851                 {yyerror ("Missing term"); RECOVER; $$ = NULL_TREE;}
1852 ;
1853
1854 finally:
1855         FINALLY_TK block
1856                 { $$ = $2; }
1857 |       FINALLY_TK error
1858                 {yyerror ("'{' expected"); RECOVER; }
1859 ;
1860
1861 /* 19.12 Production from 15: Expressions  */
1862 primary:
1863         primary_no_new_array
1864 |       array_creation_expression
1865 ;
1866
1867 primary_no_new_array:
1868         literal
1869 |       THIS_TK
1870                 { $$ = build_this ($1.location); }
1871 |       OP_TK expression CP_TK
1872                 {$$ = $2;}
1873 |       class_instance_creation_expression
1874 |       field_access
1875 |       method_invocation
1876 |       array_access
1877 |       type_literals
1878         /* Added, JDK1.1 inner classes. Documentation is wrong
1879            refering to a 'ClassName' (class_name) rule that doesn't
1880            exist. Used name: instead.  */
1881 |       name DOT_TK THIS_TK
1882                 { 
1883                   tree wfl = build_wfl_node (this_identifier_node);
1884                   $$ = make_qualified_primary ($1, wfl, EXPR_WFL_LINECOL ($1));
1885                 }
1886 |       OP_TK expression error 
1887                 {yyerror ("')' expected"); RECOVER;}
1888 |       name DOT_TK error
1889                 {yyerror ("'class' or 'this' expected" ); RECOVER;}
1890 |       primitive_type DOT_TK error
1891                 {yyerror ("'class' expected" ); RECOVER;}
1892 |       VOID_TK DOT_TK error
1893                 {yyerror ("'class' expected" ); RECOVER;}
1894 ;
1895
1896 /* Added, JDK1.1 type literals. We can't use `type' directly, so we
1897    broke the rule down a bit. */
1898
1899 array_type_literal:
1900         primitive_type OSB_TK CSB_TK
1901                 { 
1902                   $$ = build_java_array_type ($1, -1);
1903                   CLASS_LOADED_P ($$) = 1;
1904                 }
1905 |       name OSB_TK CSB_TK
1906                 { $$ = build_unresolved_array_type ($1); }
1907 /* This triggers two reduce/reduce conflict between array_type_literal and
1908    dims. FIXME.
1909 |       array_type OSB_TK CSB_TK
1910                 { $$ = build_unresolved_array_type ($1); }
1911 */
1912 ;
1913
1914 type_literals:
1915         name DOT_TK CLASS_TK
1916                 { $$ = build_incomplete_class_ref ($2.location, $1); }
1917 |       array_type_literal DOT_TK CLASS_TK
1918                 { $$ = build_incomplete_class_ref ($2.location, $1); }
1919 |       primitive_type DOT_TK CLASS_TK
1920                 { $$ = build_class_ref ($1); }
1921 |       VOID_TK DOT_TK CLASS_TK
1922                 { $$ = build_class_ref (void_type_node); }
1923 ;
1924
1925 class_instance_creation_expression:
1926         NEW_TK class_type OP_TK argument_list CP_TK
1927                 { $$ = build_new_invocation ($2, $4); }
1928 |       NEW_TK class_type OP_TK CP_TK
1929                 { $$ = build_new_invocation ($2, NULL_TREE); }
1930 |       anonymous_class_creation
1931         /* Added, JDK1.1 inner classes, modified to use name or
1932            primary instead of primary solely which couldn't work in
1933            all situations.  */
1934 |       something_dot_new identifier OP_TK CP_TK
1935                 { 
1936                   tree ctor = build_new_invocation ($2, NULL_TREE);
1937                   $$ = make_qualified_primary ($1, ctor, 
1938                                                EXPR_WFL_LINECOL ($1));
1939                 }
1940 |       something_dot_new identifier OP_TK CP_TK class_body
1941 |       something_dot_new identifier OP_TK argument_list CP_TK
1942                 { 
1943                   tree ctor = build_new_invocation ($2, $4);
1944                   $$ = make_qualified_primary ($1, ctor, 
1945                                                EXPR_WFL_LINECOL ($1));
1946                 }
1947 |       something_dot_new identifier OP_TK argument_list CP_TK class_body
1948 |       NEW_TK error SC_TK 
1949                 {yyerror ("'(' expected"); DRECOVER(new_1);}
1950 |       NEW_TK class_type error
1951                 {yyerror ("'(' expected"); RECOVER;}
1952 |       NEW_TK class_type OP_TK error
1953                 {yyerror ("')' or term expected"); RECOVER;}
1954 |       NEW_TK class_type OP_TK argument_list error
1955                 {yyerror ("')' expected"); RECOVER;}
1956 |       something_dot_new error
1957                 {YYERROR_NOW; yyerror ("Identifier expected"); RECOVER;}
1958 |       something_dot_new identifier error
1959                 {yyerror ("'(' expected"); RECOVER;}
1960 ;
1961
1962 /* Created after JDK1.1 rules originally added to
1963    class_instance_creation_expression, but modified to use
1964    'class_type' instead of 'TypeName' (type_name) which is mentionned
1965    in the documentation but doesn't exist. */
1966
1967 anonymous_class_creation:
1968         NEW_TK class_type OP_TK argument_list CP_TK 
1969                 { create_anonymous_class ($1.location, $2); }
1970         class_body
1971                 { 
1972                   tree id = build_wfl_node (DECL_NAME (GET_CPC ()));
1973                   EXPR_WFL_LINECOL (id) = EXPR_WFL_LINECOL ($2);
1974
1975                   end_class_declaration (1);
1976
1977                   /* Now we can craft the new expression */
1978                   $$ = build_new_invocation (id, $4);
1979
1980                   /* Note that we can't possibly be here if
1981                      `class_type' is an interface (in which case the
1982                      anonymous class extends Object and implements
1983                      `class_type', hence its constructor can't have
1984                      arguments.) */
1985
1986                   /* Otherwise, the innerclass must feature a
1987                      constructor matching `argument_list'. Anonymous
1988                      classes are a bit special: it's impossible to
1989                      define constructor for them, hence constructors
1990                      must be generated following the hints provided by
1991                      the `new' expression. Whether a super constructor
1992                      of that nature exists or not is to be verified
1993                      later on in verify_constructor_super. 
1994
1995                      It's during the expansion of a `new' statement
1996                      refering to an anonymous class that a ctor will
1997                      be generated for the anonymous class, with the
1998                      right arguments. */
1999
2000                 }
2001 |       NEW_TK class_type OP_TK CP_TK 
2002                 { create_anonymous_class ($1.location, $2); }
2003         class_body         
2004                 { 
2005                   tree id = build_wfl_node (DECL_NAME (GET_CPC ()));
2006                   EXPR_WFL_LINECOL (id) = EXPR_WFL_LINECOL ($2);
2007
2008                   end_class_declaration (1);
2009
2010                   /* Now we can craft the new expression. The
2011                      statement doesn't need to be remember so that a
2012                      constructor can be generated, since its signature
2013                      is already known. */
2014                   $$ = build_new_invocation (id, NULL_TREE);
2015                 }
2016 ;
2017
2018 something_dot_new:              /* Added, not part of the specs. */
2019         name DOT_TK NEW_TK
2020                 { $$ = $1; }
2021 |       primary DOT_TK NEW_TK
2022                 { $$ = $1; }
2023 ;
2024
2025 argument_list:
2026         expression
2027                 { 
2028                   $$ = tree_cons (NULL_TREE, $1, NULL_TREE);
2029                   ctxp->formal_parameter_number = 1; 
2030                 }
2031 |       argument_list C_TK expression
2032                 {
2033                   ctxp->formal_parameter_number += 1;
2034                   $$ = tree_cons (NULL_TREE, $3, $1);
2035                 }
2036 |       argument_list C_TK error
2037                 {yyerror ("Missing term"); RECOVER;}
2038 ;
2039
2040 array_creation_expression:
2041         NEW_TK primitive_type dim_exprs
2042                 { $$ = build_newarray_node ($2, $3, 0); }
2043 |       NEW_TK class_or_interface_type dim_exprs
2044                 { $$ = build_newarray_node ($2, $3, 0); }
2045 |       NEW_TK primitive_type dim_exprs dims
2046                 { $$ = build_newarray_node ($2, $3, CURRENT_OSB (ctxp));}
2047 |       NEW_TK class_or_interface_type dim_exprs dims
2048                 { $$ = build_newarray_node ($2, $3, CURRENT_OSB (ctxp));}
2049         /* Added, JDK1.1 anonymous array. Initial documentation rule
2050            modified */
2051 |       NEW_TK class_or_interface_type dims array_initializer
2052                 {
2053                   char *sig;
2054                   while (CURRENT_OSB (ctxp)--)
2055                     obstack_1grow (&temporary_obstack, '[');
2056                   sig = obstack_finish (&temporary_obstack);
2057                   $$ = build (NEW_ANONYMOUS_ARRAY_EXPR, NULL_TREE,
2058                               $2, get_identifier (sig), $4);
2059                 }
2060 |       NEW_TK primitive_type dims array_initializer
2061                 { 
2062                   tree type = $2;
2063                   while (CURRENT_OSB (ctxp)--)
2064                     type = build_java_array_type (type, -1);
2065                   $$ = build (NEW_ANONYMOUS_ARRAY_EXPR, NULL_TREE, 
2066                               build_pointer_type (type), NULL_TREE, $4);
2067                 }
2068 |       NEW_TK error CSB_TK
2069                 {yyerror ("'[' expected"); DRECOVER ("]");}
2070 |       NEW_TK error OSB_TK
2071                 {yyerror ("']' expected"); RECOVER;}
2072 ;
2073
2074 dim_exprs:
2075         dim_expr
2076                 { $$ = build_tree_list (NULL_TREE, $1); }
2077 |       dim_exprs dim_expr
2078                 { $$ = tree_cons (NULL_TREE, $2, $$); }
2079 ;
2080
2081 dim_expr:
2082         OSB_TK expression CSB_TK
2083                 { 
2084                   if (JNUMERIC_TYPE_P (TREE_TYPE ($2)))
2085                     {
2086                       $2 = build_wfl_node ($2);
2087                       TREE_TYPE ($2) = NULL_TREE;
2088                     }
2089                   EXPR_WFL_LINECOL ($2) = $1.location;
2090                   $$ = $2;
2091                 }
2092 |       OSB_TK expression error
2093                 {yyerror ("']' expected"); RECOVER;}
2094 |       OSB_TK error
2095                 {
2096                   yyerror ("Missing term");
2097                   yyerror ("']' expected");
2098                   RECOVER;
2099                 }
2100 ;
2101
2102 dims:                           
2103         OSB_TK CSB_TK
2104                 { 
2105                   int allocate = 0;
2106                   /* If not initialized, allocate memory for the osb
2107                      numbers stack */
2108                   if (!ctxp->osb_limit)
2109                     {
2110                       allocate = ctxp->osb_limit = 32;
2111                       ctxp->osb_depth = -1;
2112                     }
2113                   /* If capacity overflown, reallocate a bigger chunk */
2114                   else if (ctxp->osb_depth+1 == ctxp->osb_limit)
2115                     allocate = ctxp->osb_limit << 1;
2116                   
2117                   if (allocate)
2118                     {
2119                       allocate *= sizeof (int);
2120                       if (ctxp->osb_number)
2121                         ctxp->osb_number = (int *)xrealloc (ctxp->osb_number,
2122                                                             allocate);
2123                       else
2124                         ctxp->osb_number = (int *)xmalloc (allocate);
2125                     }
2126                   ctxp->osb_depth++;
2127                   CURRENT_OSB (ctxp) = 1;
2128                 }
2129 |       dims OSB_TK CSB_TK
2130                 { CURRENT_OSB (ctxp)++; }
2131 |       dims OSB_TK error
2132                 { yyerror ("']' expected"); RECOVER;}
2133 ;
2134
2135 field_access:
2136         primary DOT_TK identifier
2137                 { $$ = make_qualified_primary ($1, $3, $2.location); }
2138                 /*  FIXME - REWRITE TO: 
2139                 { $$ = build_binop (COMPONENT_REF, $2.location, $1, $3); } */
2140 |       SUPER_TK DOT_TK identifier
2141                 {
2142                   tree super_wfl = 
2143                     build_wfl_node (super_identifier_node);
2144                   EXPR_WFL_LINECOL (super_wfl) = $1.location;
2145                   $$ = make_qualified_name (super_wfl, $3, $2.location);
2146                 }
2147 |       SUPER_TK error
2148                 {yyerror ("Field expected"); DRECOVER (super_field_acces);}
2149 ;
2150
2151 method_invocation:
2152         name OP_TK CP_TK
2153                 { $$ = build_method_invocation ($1, NULL_TREE); }
2154 |       name OP_TK argument_list CP_TK
2155                 { $$ = build_method_invocation ($1, $3); }
2156 |       primary DOT_TK identifier OP_TK CP_TK
2157                 { 
2158                   if (TREE_CODE ($1) == THIS_EXPR)
2159                     $$ = build_this_super_qualified_invocation 
2160                       (1, $3, NULL_TREE, 0, $2.location);
2161                   else
2162                     {
2163                       tree invok = build_method_invocation ($3, NULL_TREE);
2164                       $$ = make_qualified_primary ($1, invok, $2.location);
2165                     }
2166                 }
2167 |       primary DOT_TK identifier OP_TK argument_list CP_TK
2168                 { 
2169                   if (TREE_CODE ($1) == THIS_EXPR)
2170                     $$ = build_this_super_qualified_invocation 
2171                       (1, $3, $5, 0, $2.location);
2172                   else
2173                     {
2174                       tree invok = build_method_invocation ($3, $5);
2175                       $$ = make_qualified_primary ($1, invok, $2.location);
2176                     }
2177                 }
2178 |       SUPER_TK DOT_TK identifier OP_TK CP_TK
2179                 { 
2180                   $$ = build_this_super_qualified_invocation 
2181                     (0, $3, NULL_TREE, $1.location, $2.location);
2182                 }
2183 |       SUPER_TK DOT_TK identifier OP_TK argument_list CP_TK
2184                 {
2185                   $$ = build_this_super_qualified_invocation 
2186                     (0, $3, $5, $1.location, $2.location);
2187                 }
2188         /* Screws up thing. I let it here until I'm convinced it can
2189            be removed. FIXME
2190 |       primary DOT_TK error
2191                 {yyerror ("'(' expected"); DRECOVER(bad);} */
2192 |       SUPER_TK DOT_TK error CP_TK
2193                 { yyerror ("'(' expected"); DRECOVER (method_invocation); }
2194 |       SUPER_TK DOT_TK error DOT_TK
2195                 { yyerror ("'(' expected"); DRECOVER (method_invocation); }
2196 ;
2197
2198 array_access:
2199         name OSB_TK expression CSB_TK
2200                 { $$ = build_array_ref ($2.location, $1, $3); }
2201 |       primary_no_new_array OSB_TK expression CSB_TK
2202                 { $$ = build_array_ref ($2.location, $1, $3); }
2203 |       name OSB_TK error
2204                 {
2205                   yyerror ("Missing term and ']' expected");
2206                   DRECOVER(array_access);
2207                 }
2208 |       name OSB_TK expression error
2209                 {
2210                   yyerror ("']' expected");
2211                   DRECOVER(array_access);
2212                 }
2213 |       primary_no_new_array OSB_TK error
2214                 {
2215                   yyerror ("Missing term and ']' expected");
2216                   DRECOVER(array_access);
2217                 }
2218 |       primary_no_new_array OSB_TK expression error
2219                 {
2220                   yyerror ("']' expected");
2221                   DRECOVER(array_access);
2222                 }
2223 ;
2224
2225 postfix_expression:
2226         primary
2227 |       name
2228 |       post_increment_expression
2229 |       post_decrement_expression
2230 ;
2231
2232 post_increment_expression:
2233         postfix_expression INCR_TK
2234                 { $$ = build_incdec ($2.token, $2.location, $1, 1); }
2235 ;
2236
2237 post_decrement_expression:
2238         postfix_expression DECR_TK
2239                 { $$ = build_incdec ($2.token, $2.location, $1, 1); }
2240 ;
2241
2242 unary_expression:
2243         pre_increment_expression
2244 |       pre_decrement_expression
2245 |       PLUS_TK unary_expression
2246                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2247 |       MINUS_TK unary_expression
2248                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2249 |       unary_expression_not_plus_minus
2250 |       PLUS_TK error
2251                 {yyerror ("Missing term"); RECOVER}
2252 |       MINUS_TK error
2253                 {yyerror ("Missing term"); RECOVER}
2254 ;
2255
2256 pre_increment_expression:
2257         INCR_TK unary_expression
2258                 {$$ = build_incdec ($1.token, $1.location, $2, 0); }
2259 |       INCR_TK error
2260                 {yyerror ("Missing term"); RECOVER}
2261 ;
2262
2263 pre_decrement_expression:
2264         DECR_TK unary_expression
2265                 {$$ = build_incdec ($1.token, $1.location, $2, 0); }
2266 |       DECR_TK error
2267                 {yyerror ("Missing term"); RECOVER}
2268 ;
2269
2270 unary_expression_not_plus_minus:
2271         postfix_expression
2272 |       NOT_TK unary_expression
2273                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2274 |       NEG_TK unary_expression
2275                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2276 |       cast_expression
2277 |       NOT_TK error
2278                 {yyerror ("Missing term"); RECOVER}
2279 |       NEG_TK error
2280                 {yyerror ("Missing term"); RECOVER}
2281 ;
2282
2283 cast_expression:                /* Error handling here is potentially weak */
2284         OP_TK primitive_type dims CP_TK unary_expression
2285                 { 
2286                   tree type = $2;
2287                   while (CURRENT_OSB (ctxp)--)
2288                     type = build_java_array_type (type, -1);
2289                   ctxp->osb_depth--;
2290                   $$ = build_cast ($1.location, type, $5); 
2291                 }
2292 |       OP_TK primitive_type CP_TK unary_expression
2293                 { $$ = build_cast ($1.location, $2, $4); }
2294 |       OP_TK expression CP_TK unary_expression_not_plus_minus
2295                 { $$ = build_cast ($1.location, $2, $4); }
2296 |       OP_TK name dims CP_TK unary_expression_not_plus_minus
2297                 { 
2298                   const char *ptr;
2299                   while (CURRENT_OSB (ctxp)--)
2300                     obstack_1grow (&temporary_obstack, '[');
2301                   ctxp->osb_depth--;
2302                   obstack_grow0 (&temporary_obstack, 
2303                                  IDENTIFIER_POINTER (EXPR_WFL_NODE ($2)),
2304                                  IDENTIFIER_LENGTH (EXPR_WFL_NODE ($2)));
2305                   ptr = obstack_finish (&temporary_obstack);
2306                   EXPR_WFL_NODE ($2) = get_identifier (ptr);
2307                   $$ = build_cast ($1.location, $2, $5);
2308                 }
2309 |       OP_TK primitive_type OSB_TK error
2310                 {yyerror ("']' expected, invalid type expression");}
2311 |       OP_TK error
2312                 {
2313                   if (ctxp->prevent_ese != lineno)
2314                     yyerror ("Invalid type expression"); RECOVER;
2315                   RECOVER;
2316                 }
2317 |       OP_TK primitive_type dims CP_TK error
2318                 {yyerror ("Missing term"); RECOVER;}
2319 |       OP_TK primitive_type CP_TK error
2320                 {yyerror ("Missing term"); RECOVER;}
2321 |       OP_TK name dims CP_TK error
2322                 {yyerror ("Missing term"); RECOVER;}
2323 ;
2324
2325 multiplicative_expression:
2326         unary_expression
2327 |       multiplicative_expression MULT_TK unary_expression
2328                 { 
2329                   $$ = build_binop (BINOP_LOOKUP ($2.token), 
2330                                     $2.location, $1, $3);
2331                 }
2332 |       multiplicative_expression DIV_TK unary_expression
2333                 {
2334                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2335                                     $1, $3); 
2336                 }
2337 |       multiplicative_expression REM_TK unary_expression
2338                 {
2339                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2340                                     $1, $3); 
2341                 }
2342 |       multiplicative_expression MULT_TK error
2343                 {yyerror ("Missing term"); RECOVER;}
2344 |       multiplicative_expression DIV_TK error
2345                 {yyerror ("Missing term"); RECOVER;}
2346 |       multiplicative_expression REM_TK error
2347                 {yyerror ("Missing term"); RECOVER;}
2348 ;
2349
2350 additive_expression:
2351         multiplicative_expression
2352 |       additive_expression PLUS_TK multiplicative_expression
2353                 {
2354                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2355                                     $1, $3); 
2356                 }
2357 |       additive_expression MINUS_TK multiplicative_expression
2358                 {
2359                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2360                                     $1, $3); 
2361                 }
2362 |       additive_expression PLUS_TK error
2363                 {yyerror ("Missing term"); RECOVER;}
2364 |       additive_expression MINUS_TK error
2365                 {yyerror ("Missing term"); RECOVER;}
2366 ;
2367
2368 shift_expression:
2369         additive_expression
2370 |       shift_expression LS_TK additive_expression
2371                 {
2372                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2373                                     $1, $3); 
2374                 }
2375 |       shift_expression SRS_TK additive_expression
2376                 {
2377                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2378                                     $1, $3); 
2379                 }
2380 |       shift_expression ZRS_TK additive_expression
2381                 {
2382                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2383                                     $1, $3); 
2384                 }
2385 |       shift_expression LS_TK error
2386                 {yyerror ("Missing term"); RECOVER;}
2387 |       shift_expression SRS_TK error
2388                 {yyerror ("Missing term"); RECOVER;}
2389 |       shift_expression ZRS_TK error
2390                 {yyerror ("Missing term"); RECOVER;}
2391 ;
2392
2393 relational_expression:
2394         shift_expression
2395 |       relational_expression LT_TK shift_expression
2396                 {
2397                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2398                                     $1, $3); 
2399                 }
2400 |       relational_expression GT_TK shift_expression
2401                 {
2402                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2403                                     $1, $3); 
2404                 }
2405 |       relational_expression LTE_TK shift_expression
2406                 {
2407                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2408                                     $1, $3); 
2409                 }
2410 |       relational_expression GTE_TK shift_expression
2411                 {
2412                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2413                                     $1, $3); 
2414                 }
2415 |       relational_expression INSTANCEOF_TK reference_type
2416                 { $$ = build_binop (INSTANCEOF_EXPR, $2.location, $1, $3); }
2417 |       relational_expression LT_TK error
2418                 {yyerror ("Missing term"); RECOVER;}
2419 |       relational_expression GT_TK error
2420                 {yyerror ("Missing term"); RECOVER;}
2421 |       relational_expression LTE_TK error
2422                 {yyerror ("Missing term"); RECOVER;}
2423 |       relational_expression GTE_TK error
2424                 {yyerror ("Missing term"); RECOVER;}
2425 |       relational_expression INSTANCEOF_TK error
2426                 {yyerror ("Invalid reference type"); RECOVER;}
2427 ;
2428
2429 equality_expression:
2430         relational_expression
2431 |       equality_expression EQ_TK relational_expression
2432                 {
2433                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2434                                     $1, $3); 
2435                 }
2436 |       equality_expression NEQ_TK relational_expression
2437                 {
2438                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2439                                     $1, $3); 
2440                 }
2441 |       equality_expression EQ_TK error
2442                 {yyerror ("Missing term"); RECOVER;}
2443 |       equality_expression NEQ_TK error
2444                 {yyerror ("Missing term"); RECOVER;}
2445 ;
2446
2447 and_expression:
2448         equality_expression
2449 |       and_expression AND_TK equality_expression
2450                 {
2451                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2452                                     $1, $3); 
2453                 }
2454 |       and_expression AND_TK error
2455                 {yyerror ("Missing term"); RECOVER;}
2456 ;
2457
2458 exclusive_or_expression:
2459         and_expression
2460 |       exclusive_or_expression XOR_TK and_expression
2461                 {
2462                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2463                                     $1, $3); 
2464                 }
2465 |       exclusive_or_expression XOR_TK error
2466                 {yyerror ("Missing term"); RECOVER;}
2467 ;
2468
2469 inclusive_or_expression:
2470         exclusive_or_expression
2471 |       inclusive_or_expression OR_TK exclusive_or_expression
2472                 {
2473                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2474                                     $1, $3); 
2475                 }
2476 |       inclusive_or_expression OR_TK error
2477                 {yyerror ("Missing term"); RECOVER;}
2478 ;
2479
2480 conditional_and_expression:
2481         inclusive_or_expression
2482 |       conditional_and_expression BOOL_AND_TK inclusive_or_expression
2483                 {
2484                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2485                                     $1, $3); 
2486                 }
2487 |       conditional_and_expression BOOL_AND_TK error
2488                 {yyerror ("Missing term"); RECOVER;}
2489 ;
2490
2491 conditional_or_expression:
2492         conditional_and_expression
2493 |       conditional_or_expression BOOL_OR_TK conditional_and_expression
2494                 {
2495                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2496                                     $1, $3); 
2497                 }
2498 |       conditional_or_expression BOOL_OR_TK error
2499                 {yyerror ("Missing term"); RECOVER;}
2500 ;
2501
2502 conditional_expression:         /* Error handling here is weak */
2503         conditional_or_expression
2504 |       conditional_or_expression REL_QM_TK expression REL_CL_TK conditional_expression
2505                 {
2506                   $$ = build (CONDITIONAL_EXPR, NULL_TREE, $1, $3, $5);
2507                   EXPR_WFL_LINECOL ($$) = $2.location;
2508                 }
2509 |       conditional_or_expression REL_QM_TK REL_CL_TK error
2510                 {
2511                   YYERROR_NOW;
2512                   yyerror ("Missing term");
2513                   DRECOVER (1);
2514                 }
2515 |       conditional_or_expression REL_QM_TK error
2516                 {yyerror ("Missing term"); DRECOVER (2);}
2517 |       conditional_or_expression REL_QM_TK expression REL_CL_TK error
2518                 {yyerror ("Missing term"); DRECOVER (3);}
2519 ;
2520
2521 assignment_expression:
2522         conditional_expression
2523 |       assignment
2524 ;
2525
2526 assignment:
2527         left_hand_side assignment_operator assignment_expression
2528                 { $$ = build_assignment ($2.token, $2.location, $1, $3); }
2529 |       left_hand_side assignment_operator error
2530                 {
2531                   if (ctxp->prevent_ese != lineno)
2532                     yyerror ("Missing term");
2533                   DRECOVER (assign);
2534                 }
2535 ;
2536
2537 left_hand_side:
2538         name
2539 |       field_access
2540 |       array_access
2541 ;
2542
2543 assignment_operator:
2544         ASSIGN_ANY_TK
2545 |       ASSIGN_TK
2546 ;
2547
2548 expression:
2549         assignment_expression
2550 ;
2551
2552 constant_expression:
2553         expression
2554 ;
2555
2556 %%
2557 \f
2558
2559 /* This section of the code deal with save/restoring parser contexts.
2560    Add mode documentation here. FIXME */
2561
2562 /* Helper function. Create a new parser context. With
2563    COPY_FROM_PREVIOUS set to a non zero value, content of the previous
2564    context is copied, otherwise, the new context is zeroed. The newly
2565    created context becomes the current one.  */
2566
2567 static void
2568 create_new_parser_context (copy_from_previous)
2569     int copy_from_previous;
2570 {
2571   struct parser_ctxt *new;
2572
2573   new =  (struct parser_ctxt *)xmalloc(sizeof (struct parser_ctxt));
2574   if (copy_from_previous)
2575     {
2576       memcpy ((PTR)new, (PTR)ctxp, sizeof (struct parser_ctxt));
2577       new->saved_data_ctx = 1;
2578     }
2579   else
2580     bzero ((PTR) new, sizeof (struct parser_ctxt));
2581       
2582   new->next = ctxp;
2583   ctxp = new;
2584 }
2585
2586 /* Create a new parser context and make it the current one. */
2587
2588 void
2589 java_push_parser_context ()
2590 {
2591   create_new_parser_context (0);
2592   if (ctxp->next)
2593     {
2594       ctxp->incomplete_class = ctxp->next->incomplete_class;
2595       ctxp->gclass_list = ctxp->next->gclass_list;
2596     }
2597 }  
2598
2599 void 
2600 java_pop_parser_context (generate)
2601      int generate;
2602 {
2603   tree current;
2604   struct parser_ctxt *toFree, *next;
2605
2606   if (!ctxp)
2607     return;
2608
2609   toFree = ctxp;
2610   next = ctxp->next;
2611   if (next)
2612     {
2613       next->incomplete_class = ctxp->incomplete_class;
2614       next->gclass_list = ctxp->gclass_list;
2615       lineno = ctxp->lineno;
2616       finput = ctxp->finput;
2617       current_class = ctxp->current_class;
2618     }
2619
2620   /* Set the single import class file flag to 0 for the current list
2621      of imported things */
2622   for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
2623     IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_PURPOSE (current)) = 0;
2624
2625   /* And restore those of the previous context */
2626   if ((ctxp = next))            /* Assignment is really meant here */
2627     for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
2628       IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_PURPOSE (current)) = 1;
2629   
2630   /* If we pushed a context to parse a class intended to be generated,
2631      we keep it so we can remember the class. What we could actually
2632      do is to just update a list of class names.  */
2633   if (generate)
2634     {
2635       toFree->next = ctxp_for_generation;
2636       ctxp_for_generation = toFree;
2637     }
2638   else
2639     free (toFree);
2640 }
2641
2642 /* Create a parser context for the use of saving some global
2643    variables.  */
2644
2645 void
2646 java_parser_context_save_global ()
2647 {
2648   if (!ctxp)
2649     {
2650       java_push_parser_context ();
2651       ctxp->saved_data_ctx = 1;
2652     }
2653
2654   /* If this context already stores data, create a new one suitable
2655      for data storage. */
2656   else if (ctxp->saved_data)
2657     create_new_parser_context (1);
2658
2659   ctxp->finput = finput;
2660   ctxp->lineno = lineno;
2661   ctxp->current_class = current_class;
2662   ctxp->filename = input_filename;
2663   ctxp->current_function_decl = current_function_decl;
2664   ctxp->saved_data = 1;
2665 }
2666
2667 /* Restore some global variables from the previous context. Make the
2668    previous context the current one.  */
2669
2670 void
2671 java_parser_context_restore_global ()
2672 {
2673   finput = ctxp->finput;
2674   lineno = ctxp->lineno;
2675   current_class = ctxp->current_class;
2676   input_filename = ctxp->filename;
2677   current_function_decl = ctxp->current_function_decl;
2678   ctxp->saved_data = 0;
2679   if (ctxp->saved_data_ctx)
2680     java_pop_parser_context (0);
2681 }
2682
2683 /* Suspend vital data for the current class/function being parsed so
2684    that an other class can be parsed. Used to let local/anonymous
2685    classes be parsed.  */
2686
2687 static void
2688 java_parser_context_suspend ()
2689 {
2690   /* This makes debugging through java_debug_context easier */
2691   static const char *name = "<inner buffer context>";
2692
2693   /* Duplicate the previous context, use it to save the globals we're
2694      interested in */
2695   create_new_parser_context (1);
2696   ctxp->current_function_decl = current_function_decl;
2697   ctxp->current_class = current_class;
2698
2699   /* Then create a new context which inherits all data from the
2700      previous one. This will be the new current context  */
2701   create_new_parser_context (1);
2702
2703   /* Help debugging */
2704   ctxp->next->filename = name;
2705 }
2706
2707 /* Resume vital data for the current class/function being parsed so
2708    that an other class can be parsed. Used to let local/anonymous
2709    classes be parsed.  The trick is the data storing file position
2710    informations must be restored to their current value, so parsing
2711    can resume as if no context was ever saved. */
2712
2713 static void
2714 java_parser_context_resume ()
2715 {
2716   struct parser_ctxt *old = ctxp;             /* This one is to be discarded */
2717   struct parser_ctxt *saver = old->next;      /* This one contain saved info */
2718   struct parser_ctxt *restored = saver->next; /* This one is the old current */
2719
2720   /* We need to inherit the list of classes to complete/generate */
2721   restored->incomplete_class = old->incomplete_class;
2722   restored->gclass_list = old->gclass_list;
2723   restored->classd_list = old->classd_list;
2724   restored->class_list = old->class_list;
2725
2726   /* Restore the current class and function from the saver */
2727   current_class = saver->current_class;
2728   current_function_decl = saver->current_function_decl;
2729
2730   /* Retrive the restored context */
2731   ctxp = restored;
2732
2733   /* Re-installed the data for the parsing to carry on */
2734   bcopy (&old->marker_begining, &ctxp->marker_begining,
2735          (size_t)(&ctxp->marker_end - &ctxp->marker_begining));
2736
2737   /* Buffer context can now be discarded */
2738   free (saver);
2739   free (old);
2740 }
2741
2742 /* Add a new anchor node to which all statement(s) initializing static
2743    and non static initialized upon declaration field(s) will be
2744    linked.  */
2745
2746 static void
2747 java_parser_context_push_initialized_field ()
2748 {
2749   tree node;
2750
2751   node = build_tree_list (NULL_TREE, NULL_TREE);
2752   TREE_CHAIN (node) = CPC_STATIC_INITIALIZER_LIST (ctxp);
2753   CPC_STATIC_INITIALIZER_LIST (ctxp) = node;
2754
2755   node = build_tree_list (NULL_TREE, NULL_TREE);
2756   TREE_CHAIN (node) = CPC_INITIALIZER_LIST (ctxp);
2757   CPC_INITIALIZER_LIST (ctxp) = node;
2758
2759   node = build_tree_list (NULL_TREE, NULL_TREE);
2760   TREE_CHAIN (node) = CPC_INSTANCE_INITIALIZER_LIST (ctxp);
2761   CPC_INSTANCE_INITIALIZER_LIST (ctxp) = node;
2762 }
2763
2764 /* Pop the lists of initialized field. If this lists aren't empty,
2765    remember them so we can use it to create and populate the $finit$
2766    or <clinit> functions. */
2767
2768 static void
2769 java_parser_context_pop_initialized_field ()
2770 {
2771   tree stmts;
2772   tree class_type = TREE_TYPE (GET_CPC ());
2773
2774   if (CPC_INITIALIZER_LIST (ctxp))
2775     {
2776       stmts = CPC_INITIALIZER_STMT (ctxp);
2777       CPC_INITIALIZER_LIST (ctxp) = TREE_CHAIN (CPC_INITIALIZER_LIST (ctxp));
2778       if (stmts && !java_error_count)
2779         TYPE_FINIT_STMT_LIST (class_type) = reorder_static_initialized (stmts);
2780     }
2781
2782   if (CPC_STATIC_INITIALIZER_LIST (ctxp))
2783     {
2784       stmts = CPC_STATIC_INITIALIZER_STMT (ctxp);
2785       CPC_STATIC_INITIALIZER_LIST (ctxp) = 
2786         TREE_CHAIN (CPC_STATIC_INITIALIZER_LIST (ctxp));
2787       /* Keep initialization in order to enforce 8.5 */
2788       if (stmts && !java_error_count)
2789         TYPE_CLINIT_STMT_LIST (class_type) = nreverse (stmts);
2790     }
2791
2792   /* JDK 1.1 instance initializers */
2793   if (CPC_INSTANCE_INITIALIZER_LIST (ctxp))
2794     {
2795       stmts = CPC_INSTANCE_INITIALIZER_STMT (ctxp);
2796       CPC_INSTANCE_INITIALIZER_LIST (ctxp) = 
2797         TREE_CHAIN (CPC_INSTANCE_INITIALIZER_LIST (ctxp));
2798       if (stmts && !java_error_count)
2799         TYPE_II_STMT_LIST (class_type) = nreverse (stmts);
2800     }
2801 }
2802
2803 static tree
2804 reorder_static_initialized (list)
2805      tree list;
2806 {
2807   /* We have to keep things in order. The alias initializer have to
2808      come first, then the initialized regular field, in reverse to
2809      keep them in lexical order. */
2810   tree marker, previous = NULL_TREE;
2811   for (marker = list; marker; previous = marker, marker = TREE_CHAIN (marker))
2812     if (TREE_CODE (marker) == TREE_LIST 
2813         && !TREE_VALUE (marker) && !TREE_PURPOSE (marker))
2814       break;
2815   
2816   /* No static initialized, the list is fine as is */
2817   if (!previous)
2818     list = TREE_CHAIN (marker);
2819
2820   /* No marker? reverse the whole list */
2821   else if (!marker)
2822     list = nreverse (list);
2823
2824   /* Otherwise, reverse what's after the marker and the new reordered
2825      sublist will replace the marker. */
2826   else
2827     {
2828       TREE_CHAIN (previous) = NULL_TREE;
2829       list = nreverse (list);
2830       list = chainon (TREE_CHAIN (marker), list);
2831     }
2832   return list;
2833 }
2834
2835 /* Helper functions to dump the parser context stack.  */
2836
2837 #define TAB_CONTEXT(C) \
2838   {int i; for (i = 0; i < (C); i++) fputc (' ', stderr);}
2839
2840 static void
2841 java_debug_context_do (tab)
2842      int tab;
2843 {
2844   struct parser_ctxt *copy = ctxp;
2845   while (copy)
2846     {
2847       TAB_CONTEXT (tab);
2848       fprintf (stderr, "ctxt: 0x%0lX\n", (unsigned long)copy);
2849       TAB_CONTEXT (tab);
2850       fprintf (stderr, "filename: %s\n", copy->filename);
2851       TAB_CONTEXT (tab);
2852       fprintf (stderr, "lineno: %d\n", copy->lineno);
2853       TAB_CONTEXT (tab);
2854       fprintf (stderr, "package: %s\n",
2855                (copy->package ? 
2856                 IDENTIFIER_POINTER (copy->package) : "<none>"));
2857       TAB_CONTEXT (tab);
2858       fprintf (stderr, "context for saving: %d\n", copy->saved_data_ctx);
2859       TAB_CONTEXT (tab);
2860       fprintf (stderr, "saved data: %d\n", copy->saved_data);
2861       copy = copy->next;
2862       tab += 2;
2863     }
2864 }
2865
2866 /* Dump the stacked up parser contexts. Intended to be called from a
2867    debugger.  */
2868
2869 void
2870 java_debug_context ()
2871 {
2872   java_debug_context_do (0);
2873 }
2874
2875 \f
2876
2877 /* Flag for the error report routine to issue the error the first time
2878    it's called (overriding the default behavior which is to drop the
2879    first invocation and honor the second one, taking advantage of a
2880    richer context.  */
2881 static int force_error = 0;
2882
2883 /* Reporting an constructor invocation error.  */
2884 static void
2885 parse_ctor_invocation_error ()
2886 {
2887   if (DECL_CONSTRUCTOR_P (current_function_decl))
2888     yyerror ("Constructor invocation must be first thing in a constructor"); 
2889   else
2890     yyerror ("Only constructors can invoke constructors");
2891 }
2892
2893 /* Reporting JDK1.1 features not implemented.  */
2894
2895 static tree
2896 parse_jdk1_1_error (msg)
2897     const char *msg;
2898 {
2899   sorry (": `%s' JDK1.1(TM) feature", msg);
2900   java_error_count++;
2901   return empty_stmt_node;
2902 }
2903
2904 static int do_warning = 0;
2905
2906 void
2907 yyerror (msg)
2908      const char *msg;
2909 {
2910   static java_lc elc;
2911   static int  prev_lineno;
2912   static const char *prev_msg;
2913
2914   int save_lineno;
2915   char *remainder, *code_from_source;
2916   extern struct obstack temporary_obstack;
2917   
2918   if (!force_error && prev_lineno == lineno)
2919     return;
2920
2921   /* Save current error location but report latter, when the context is
2922      richer.  */
2923   if (ctxp->java_error_flag == 0)
2924     {
2925       ctxp->java_error_flag = 1;
2926       elc = ctxp->elc;
2927       /* Do something to use the previous line if we're reaching the
2928          end of the file... */
2929 #ifdef VERBOSE_SKELETON
2930       printf ("* Error detected (%s)\n", (msg ? msg : "(null)"));
2931 #endif
2932       return;
2933     }
2934
2935   /* Ignore duplicate message on the same line. BTW, this is dubious. FIXME */
2936   if (!force_error && msg == prev_msg && prev_lineno == elc.line)
2937     return;
2938
2939   ctxp->java_error_flag = 0;
2940   if (do_warning)
2941     java_warning_count++;
2942   else
2943     java_error_count++;
2944   
2945   if (elc.col == 0 && msg && msg[1] == ';')
2946     {
2947       elc.col  = ctxp->p_line->char_col-1;
2948       elc.line = ctxp->p_line->lineno;
2949     }
2950
2951   save_lineno = lineno;
2952   prev_lineno = lineno = elc.line;
2953   prev_msg = msg;
2954
2955   code_from_source = java_get_line_col (ctxp->filename, elc.line, elc.col);
2956   obstack_grow0 (&temporary_obstack, 
2957                  code_from_source, strlen (code_from_source));
2958   remainder = obstack_finish (&temporary_obstack);
2959   if (do_warning)
2960     warning ("%s.\n%s", msg, remainder);
2961   else
2962     error ("%s.\n%s", msg, remainder);
2963
2964   /* This allow us to cheaply avoid an extra 'Invalid expression
2965      statement' error report when errors have been already reported on
2966      the same line. This occurs when we report an error but don't have
2967      a synchronization point other than ';', which
2968      expression_statement is the only one to take care of.  */
2969   ctxp->prevent_ese = lineno = save_lineno;
2970 }
2971
2972 static void
2973 issue_warning_error_from_context (cl, msg, ap)
2974      tree cl;
2975      const char *msg;
2976      va_list ap;
2977 {
2978   const char *saved, *saved_input_filename;
2979   char buffer [4096];
2980   vsprintf (buffer, msg, ap);
2981   force_error = 1;
2982
2983   ctxp->elc.line = EXPR_WFL_LINENO (cl);
2984   ctxp->elc.col  = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 : 
2985                     (EXPR_WFL_COLNO (cl) == 0xffe ? -2 : EXPR_WFL_COLNO (cl)));
2986
2987   /* We have a CL, that's a good reason for using it if it contains data */
2988   saved = ctxp->filename;
2989   if (TREE_CODE (cl) == EXPR_WITH_FILE_LOCATION && EXPR_WFL_FILENAME_NODE (cl))
2990     ctxp->filename = EXPR_WFL_FILENAME (cl);
2991   saved_input_filename = input_filename;
2992   input_filename = ctxp->filename;
2993   java_error (NULL);
2994   java_error (buffer);
2995   ctxp->filename = saved;
2996   input_filename = saved_input_filename;
2997   force_error = 0;
2998 }
2999
3000 /* Issue an error message at a current source line CL */
3001
3002 void
3003 parse_error_context VPARAMS ((tree cl, const char *msg, ...))
3004 {
3005 #ifndef ANSI_PROTOTYPES
3006   tree cl;
3007   const char *msg;
3008 #endif
3009   va_list ap;
3010
3011   VA_START (ap, msg);
3012 #ifndef ANSI_PROTOTYPES
3013   cl = va_arg (ap, tree);
3014   msg = va_arg (ap, const char *);
3015 #endif
3016   issue_warning_error_from_context (cl, msg, ap);
3017   va_end (ap);
3018 }
3019
3020 /* Issue a warning at a current source line CL */
3021
3022 static void
3023 parse_warning_context VPARAMS ((tree cl, const char *msg, ...))
3024 {
3025 #ifndef ANSI_PROTOTYPES
3026   tree cl;
3027   const char *msg;
3028 #endif
3029   va_list ap;
3030
3031   VA_START (ap, msg);
3032 #ifndef ANSI_PROTOTYPES
3033   cl = va_arg (ap, tree);
3034   msg = va_arg (ap, const char *);
3035 #endif
3036
3037   force_error = do_warning = 1;
3038   issue_warning_error_from_context (cl, msg, ap);
3039   do_warning = force_error = 0;
3040   va_end (ap);
3041 }
3042
3043 static tree
3044 find_expr_with_wfl (node)
3045      tree node;
3046 {
3047   while (node)
3048     {
3049       char code;
3050       tree to_return;
3051
3052       switch (TREE_CODE (node))
3053         {
3054         case BLOCK:
3055           node = BLOCK_EXPR_BODY (node);
3056           continue;
3057
3058         case COMPOUND_EXPR:
3059           to_return = find_expr_with_wfl (TREE_OPERAND (node, 0));
3060           if (to_return)
3061             return to_return;
3062           node = TREE_OPERAND (node, 1);
3063           continue;
3064
3065         case LOOP_EXPR:
3066           node = TREE_OPERAND (node, 0);
3067           continue;
3068           
3069         case LABELED_BLOCK_EXPR:
3070           node = TREE_OPERAND (node, 1);
3071           continue;
3072
3073         default:
3074           code = TREE_CODE_CLASS (TREE_CODE (node));
3075           if (((code == '1') || (code == '2') || (code == 'e'))
3076               && EXPR_WFL_LINECOL (node))
3077             return node;
3078           return NULL_TREE;
3079         }
3080     }
3081   return NULL_TREE;
3082 }
3083
3084 /* Issue a missing return statement error. Uses METHOD to figure the
3085    last line of the method the error occurs in.  */
3086
3087 static void
3088 missing_return_error (method)
3089      tree method;
3090 {
3091   EXPR_WFL_SET_LINECOL (wfl_operator, DECL_SOURCE_LINE_LAST (method), -2);
3092   parse_error_context (wfl_operator, "Missing return statement");
3093 }
3094
3095 /* Issue an unreachable statement error. From NODE, find the next
3096    statement to report appropriately.  */
3097 static void
3098 unreachable_stmt_error (node)
3099      tree node;
3100 {
3101   /* Browse node to find the next expression node that has a WFL. Use
3102      the location to report the error */
3103   if (TREE_CODE (node) == COMPOUND_EXPR)
3104     node = find_expr_with_wfl (TREE_OPERAND (node, 1));
3105   else
3106     node = find_expr_with_wfl (node);
3107
3108   if (node)
3109     {
3110       EXPR_WFL_SET_LINECOL (wfl_operator, EXPR_WFL_LINENO (node), -2);
3111       parse_error_context (wfl_operator, "Unreachable statement");
3112     }
3113   else
3114     fatal ("Can't get valid statement - unreachable_stmt_error");
3115 }
3116
3117 int
3118 java_report_errors ()
3119 {
3120   if (java_error_count)
3121     fprintf (stderr, "%d error%s", 
3122              java_error_count, (java_error_count == 1 ? "" : "s"));
3123   if (java_warning_count)
3124     fprintf (stderr, "%s%d warning%s", (java_error_count ? ", " : ""),
3125              java_warning_count, (java_warning_count == 1 ? "" : "s"));
3126   if (java_error_count || java_warning_count)
3127     putc ('\n', stderr);
3128   return java_error_count;
3129 }
3130
3131 static char *
3132 java_accstring_lookup (flags)
3133      int flags;
3134 {
3135   static char buffer [80];
3136 #define COPY_RETURN(S) {strcpy (buffer, S); return buffer;}
3137
3138   /* Access modifier looked-up first for easier report on forbidden
3139      access. */
3140   if (flags & ACC_PUBLIC) COPY_RETURN ("public");
3141   if (flags & ACC_PRIVATE) COPY_RETURN ("private");
3142   if (flags & ACC_PROTECTED) COPY_RETURN ("protected");
3143   if (flags & ACC_STATIC) COPY_RETURN ("static");
3144   if (flags & ACC_FINAL) COPY_RETURN ("final");
3145   if (flags & ACC_SYNCHRONIZED) COPY_RETURN ("synchronized");
3146   if (flags & ACC_VOLATILE) COPY_RETURN ("volatile");
3147   if (flags & ACC_TRANSIENT) COPY_RETURN ("transient");
3148   if (flags & ACC_NATIVE) COPY_RETURN ("native");
3149   if (flags & ACC_INTERFACE) COPY_RETURN ("interface");
3150   if (flags & ACC_ABSTRACT) COPY_RETURN ("abstract");
3151
3152   buffer [0] = '\0';
3153   return buffer;
3154 #undef COPY_RETURN
3155 }
3156
3157 /* Issuing error messages upon redefinition of classes, interfaces or
3158    variables. */
3159
3160 static void
3161 classitf_redefinition_error (context, id, decl, cl)
3162      const char *context;
3163      tree id, decl, cl;
3164 {
3165   parse_error_context (cl, "%s `%s' already defined in %s:%d", 
3166                        context, IDENTIFIER_POINTER (id), 
3167                        DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
3168   /* Here we should point out where its redefined. It's a unicode. FIXME */
3169 }
3170
3171 static void
3172 variable_redefinition_error (context, name, type, line)
3173      tree context, name, type;
3174      int line;
3175 {
3176   const char *type_name;
3177
3178   /* Figure a proper name for type. We might haven't resolved it */
3179   if (TREE_CODE (type) == POINTER_TYPE && !TREE_TYPE (type))
3180     type_name = IDENTIFIER_POINTER (TYPE_NAME (type));
3181   else
3182     type_name = lang_printable_name (type, 0);
3183
3184   parse_error_context (context,
3185                        "Variable `%s' is already defined in this method and was declared `%s %s' at line %d", 
3186                        IDENTIFIER_POINTER (name),
3187                        type_name, IDENTIFIER_POINTER (name), line);
3188 }
3189
3190 static tree
3191 build_array_from_name (type, type_wfl, name, ret_name)
3192      tree type, type_wfl, name, *ret_name;
3193 {
3194   int more_dims = 0;
3195   const char *string;
3196
3197   /* Eventually get more dims */
3198   string = IDENTIFIER_POINTER (name);
3199   while (string [more_dims] == '[')
3200     more_dims++;
3201   
3202   /* If we have, then craft a new type for this variable */
3203   if (more_dims)
3204     {
3205       name = get_identifier (&string [more_dims]);
3206
3207       /* If we have a pointer, use its type */
3208       if (TREE_CODE (type) == POINTER_TYPE)
3209         type = TREE_TYPE (type);
3210
3211       /* Building the first dimension of a primitive type uses this
3212          function */
3213       if (JPRIMITIVE_TYPE_P (type))
3214         {
3215           type = build_java_array_type (type, -1);
3216           CLASS_LOADED_P (type) = 1;
3217           more_dims--;
3218         }
3219       /* Otherwise, if we have a WFL for this type, use it (the type
3220          is already an array on an unresolved type, and we just keep
3221          on adding dimensions) */
3222       else if (type_wfl)
3223         type = type_wfl;
3224
3225       /* Add all the dimensions */
3226       while (more_dims--)
3227         type = build_unresolved_array_type (type);
3228
3229       /* The type may have been incomplete in the first place */
3230       if (type_wfl)
3231         type = obtain_incomplete_type (type);
3232     }
3233
3234   if (ret_name)
3235     *ret_name = name;
3236   return type;
3237 }
3238
3239 /* Build something that the type identifier resolver will identify as
3240    being an array to an unresolved type. TYPE_WFL is a WFL on a
3241    identifier. */
3242
3243 static tree
3244 build_unresolved_array_type (type_or_wfl)
3245      tree type_or_wfl;
3246 {
3247   const char *ptr;
3248
3249   /* TYPE_OR_WFL might be an array on a resolved type. In this case,
3250      just create a array type */
3251   if (TREE_CODE (type_or_wfl) == RECORD_TYPE)
3252     {
3253       tree type = build_java_array_type (type_or_wfl, -1);
3254       CLASS_LOADED_P (type) = CLASS_LOADED_P (type_or_wfl);
3255       return type;
3256     }
3257
3258   obstack_1grow (&temporary_obstack, '[');
3259   obstack_grow0 (&temporary_obstack,
3260                  IDENTIFIER_POINTER (EXPR_WFL_NODE (type_or_wfl)),
3261                  IDENTIFIER_LENGTH (EXPR_WFL_NODE (type_or_wfl)));
3262   ptr = obstack_finish (&temporary_obstack);
3263   return build_expr_wfl (get_identifier (ptr),
3264                          EXPR_WFL_FILENAME (type_or_wfl),
3265                          EXPR_WFL_LINENO (type_or_wfl),
3266                          EXPR_WFL_COLNO (type_or_wfl));
3267 }
3268
3269 static void
3270 parser_add_interface (class_decl, interface_decl, wfl)
3271      tree class_decl, interface_decl, wfl;
3272 {
3273   if (maybe_add_interface (TREE_TYPE (class_decl), TREE_TYPE (interface_decl)))
3274     parse_error_context (wfl, "Interface `%s' repeated",
3275                          IDENTIFIER_POINTER (DECL_NAME (interface_decl)));
3276 }
3277
3278 /* Bulk of common class/interface checks. Return 1 if an error was
3279    encountered. TAG is 0 for a class, 1 for an interface.  */
3280
3281 static int
3282 check_class_interface_creation (is_interface, flags, raw_name, qualified_name, decl, cl)
3283      int is_interface, flags;
3284      tree raw_name, qualified_name, decl, cl;
3285 {
3286   tree node;
3287   int sca = 0;                  /* Static class allowed */
3288   int icaf = 0;                 /* Inner class allowed flags */
3289   int uaaf = CLASS_MODIFIERS;   /* Usually allowed access flags */
3290
3291   if (!quiet_flag)
3292     fprintf (stderr, " %s%s %s", 
3293              (CPC_INNER_P () ? "inner" : ""),
3294              (is_interface ? "interface" : "class"), 
3295              IDENTIFIER_POINTER (qualified_name));
3296
3297   /* Scope of an interface/class type name:
3298        - Can't be imported by a single type import
3299        - Can't already exists in the package */
3300   if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (raw_name)
3301       && (node = find_name_in_single_imports (raw_name)))
3302     {
3303       parse_error_context 
3304         (cl, "%s name `%s' clashes with imported type `%s'",
3305          (is_interface ? "Interface" : "Class"),
3306          IDENTIFIER_POINTER (raw_name), IDENTIFIER_POINTER (node));
3307       return 1;
3308     }
3309   if (decl && CLASS_COMPLETE_P (decl))
3310     {
3311       classitf_redefinition_error ((is_interface ? "Interface" : "Class"), 
3312                                    qualified_name, decl, cl);
3313       return 1;
3314     }
3315
3316   if (check_inner_class_redefinition (raw_name, cl))
3317     return 1;
3318
3319   /* If public, file name should match class/interface name, except
3320      when dealing with an inner class */
3321   if (!CPC_INNER_P () && (flags & ACC_PUBLIC ))
3322     {
3323       const char *f;
3324
3325       /* Contains OS dependent assumption on path separator. FIXME */
3326       for (f = &input_filename [strlen (input_filename)]; 
3327            f != input_filename && f[0] != '/' && f[0] != DIR_SEPARATOR;
3328            f--)
3329         ;
3330       if (f[0] == '/' || f[0] == DIR_SEPARATOR)
3331         f++;
3332       if (strncmp (IDENTIFIER_POINTER (raw_name), 
3333                    f , IDENTIFIER_LENGTH (raw_name)) ||
3334           f [IDENTIFIER_LENGTH (raw_name)] != '.')
3335         parse_error_context
3336           (cl, "Public %s `%s' must be defined in a file called `%s.java'", 
3337                              (is_interface ? "interface" : "class"),
3338                              IDENTIFIER_POINTER (qualified_name),
3339                              IDENTIFIER_POINTER (raw_name));
3340     }
3341
3342   /* Static classes can be declared only in top level classes. Note:
3343      once static, a inner class is a top level class. */
3344   if (flags & ACC_STATIC)
3345     {
3346       /* Catch the specific error of declaring an class inner class
3347          with no toplevel enclosing class. Prevent check_modifiers from
3348          complaining a second time */
3349       if (CPC_INNER_P () && !TOPLEVEL_CLASS_DECL_P (GET_CPC()))
3350         {
3351           parse_error_context (cl, "Inner class `%s' can't be static. Static classes can only occur in interfaces and top-level classes", 
3352                                IDENTIFIER_POINTER (qualified_name));
3353           sca = ACC_STATIC;
3354         }
3355       /* Else, in the context of a top-level class declaration, let
3356          `check_modifiers' do its job, otherwise, give it a go */
3357       else
3358         sca = (GET_CPC_LIST () ? ACC_STATIC : 0);
3359     }
3360
3361   /* Inner classes can be declared private or protected
3362      within their enclosing classes. */
3363   if (CPC_INNER_P ())
3364     {
3365       /* A class which is local to a block can't be public, private,
3366          protected or static. But it is created final, so allow this
3367          one. */
3368       if (current_function_decl)
3369         icaf = sca = uaaf = ACC_FINAL;
3370       else
3371         {
3372           check_modifiers_consistency (flags);
3373           icaf = ACC_PRIVATE|ACC_PROTECTED;
3374         }
3375     }
3376
3377   if (is_interface) 
3378     {
3379       if (CPC_INNER_P ())
3380         uaaf = INTERFACE_INNER_MODIFIERS;
3381       else
3382         uaaf = INTERFACE_MODIFIERS;
3383       
3384       check_modifiers ("Illegal modifier `%s' for interface declaration", 
3385                        flags, uaaf);
3386     }
3387   else
3388     check_modifiers ((current_function_decl ?
3389                       "Illegal modifier `%s' for local class declaration" :
3390                       "Illegal modifier `%s' for class declaration"),
3391                      flags, uaaf|sca|icaf);
3392   return 0;
3393 }
3394
3395 static void
3396 make_nested_class_name (cpc_list)
3397      tree cpc_list;
3398 {
3399   tree name;
3400
3401   if (!cpc_list)
3402     return;
3403   else
3404     make_nested_class_name (TREE_CHAIN (cpc_list));
3405
3406   /* Pick the qualified name when dealing with the first upmost
3407      enclosing class */
3408   name = (TREE_CHAIN (cpc_list) ? 
3409           TREE_PURPOSE (cpc_list) : DECL_NAME (TREE_VALUE (cpc_list)));
3410   obstack_grow (&temporary_obstack,
3411                 IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name));
3412   /* Why is NO_DOLLAR_IN_LABEL defined? */
3413 #if 0
3414 #ifdef NO_DOLLAR_IN_LABEL
3415   fatal ("make_nested_class_name: Can't use '$' as a separator "
3416          "for inner classes");
3417 #endif
3418 #endif
3419   obstack_1grow (&temporary_obstack, '$');
3420 }
3421
3422 /* Can't redefine a class already defined in an earlier scope. */
3423
3424 static int
3425 check_inner_class_redefinition (raw_name, cl)
3426      tree raw_name, cl;
3427 {
3428   tree scope_list;
3429
3430   for (scope_list = GET_CPC_LIST (); scope_list; 
3431        scope_list = GET_NEXT_ENCLOSING_CPC (scope_list))
3432     if (raw_name == GET_CPC_UN_NODE (scope_list))
3433       {
3434         parse_error_context 
3435           (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",
3436            IDENTIFIER_POINTER (raw_name));
3437         return 1;
3438       }
3439   return 0;
3440 }
3441
3442 static tree
3443 find_as_inner_class (enclosing, name, cl)
3444      tree enclosing, name, cl;
3445 {
3446   tree qual, to_return;
3447   if (!enclosing)
3448     return NULL_TREE;
3449
3450   name = TYPE_NAME (name);
3451
3452   /* First search: within the scope of `enclosing', search for name */
3453   if (QUALIFIED_P (name) && cl && EXPR_WFL_NODE (cl) == name)
3454     qual = EXPR_WFL_QUALIFICATION (cl);
3455   else if (cl)
3456     qual = build_tree_list (cl, NULL_TREE);
3457   else
3458     qual = build_tree_list (build_expr_wfl (name, NULL, 0, 0), NULL_TREE);
3459   
3460   if ((to_return = find_as_inner_class_do (qual, enclosing)))
3461     return to_return;
3462
3463   /* We're dealing with a qualified name. Try to resolve thing until
3464      we get something that is an enclosing class. */
3465   if (QUALIFIED_P (name) && cl && EXPR_WFL_NODE (cl) == name)
3466     {
3467       tree acc = NULL_TREE, decl = NULL_TREE, ptr;
3468
3469       for(qual = EXPR_WFL_QUALIFICATION (cl); qual && !decl; 
3470           qual = TREE_CHAIN (qual))
3471         {
3472           acc = merge_qualified_name (acc, 
3473                                       EXPR_WFL_NODE (TREE_PURPOSE (qual)));
3474           BUILD_PTR_FROM_NAME (ptr, acc);
3475           decl = do_resolve_class (NULL_TREE, ptr, NULL_TREE, cl);
3476         }
3477
3478       /* A NULL qual and a decl means that the search ended
3479          successfully?!? We have to do something then. FIXME */
3480       
3481       if (decl)
3482         enclosing = decl;
3483       else
3484         qual = EXPR_WFL_QUALIFICATION (cl);
3485     }
3486   /* Otherwise, create a qual for the other part of the resolution. */
3487   else
3488     qual = build_tree_list (build_expr_wfl (name, NULL, 0, 0), NULL_TREE);
3489
3490   return find_as_inner_class_do (qual, enclosing);
3491 }
3492
3493 /* We go inside the list of sub classes and try to find a way
3494    through. */
3495
3496 static tree
3497 find_as_inner_class_do (qual, enclosing)
3498      tree qual, enclosing;
3499 {
3500   if (!qual)
3501     return NULL_TREE;
3502
3503   for (; qual && enclosing; qual = TREE_CHAIN (qual))
3504     {
3505       tree name_to_match = EXPR_WFL_NODE (TREE_PURPOSE (qual));
3506       tree next_enclosing = NULL_TREE;
3507       tree inner_list;
3508
3509       for (inner_list = DECL_INNER_CLASS_LIST (enclosing);
3510            inner_list; inner_list = TREE_CHAIN (inner_list))
3511         {
3512           if (TREE_VALUE (inner_list) == name_to_match)
3513             {
3514               next_enclosing = TREE_PURPOSE (inner_list);
3515               break;
3516             }
3517         }
3518       enclosing = next_enclosing;
3519     }
3520
3521   return (!qual && enclosing ? enclosing : NULL_TREE);
3522 }
3523
3524 /* Reach all inner classes and tie their unqualified name to a
3525    DECL. */
3526
3527 static void
3528 set_nested_class_simple_name_value (outer, set)
3529      tree outer;
3530      int set;
3531 {
3532   tree l;
3533
3534   for (l = DECL_INNER_CLASS_LIST (outer); l; l = TREE_CHAIN (l))
3535     IDENTIFIER_GLOBAL_VALUE (TREE_VALUE (l)) = (set ? 
3536                                                 TREE_PURPOSE (l) : NULL_TREE);
3537 }
3538
3539 static void
3540 link_nested_class_to_enclosing ()
3541 {
3542   if (GET_ENCLOSING_CPC ())
3543     {
3544       tree enclosing = GET_ENCLOSING_CPC_CONTEXT ();
3545       DECL_INNER_CLASS_LIST (enclosing) = 
3546         tree_cons (GET_CPC (), GET_CPC_UN (),
3547                    DECL_INNER_CLASS_LIST (enclosing));
3548       enclosing = enclosing;
3549     }
3550 }
3551
3552 static tree
3553 maybe_make_nested_class_name (name)
3554      tree name;
3555 {
3556   tree id = NULL_TREE;
3557
3558   if (CPC_INNER_P ())
3559     {
3560       make_nested_class_name (GET_CPC_LIST ());
3561       obstack_grow0 (&temporary_obstack,
3562                      IDENTIFIER_POINTER (name), 
3563                      IDENTIFIER_LENGTH (name));
3564       id = get_identifier (obstack_finish (&temporary_obstack));
3565       if (ctxp->package)
3566         QUALIFIED_P (id) = 1;
3567     }
3568   return id;
3569 }
3570
3571 /* If DECL is NULL, create and push a new DECL, record the current
3572    line CL and do other maintenance things.  */
3573
3574 static tree
3575 maybe_create_class_interface_decl (decl, raw_name, qualified_name, cl)
3576      tree decl, raw_name, qualified_name, cl;
3577 {
3578   if (!decl)
3579     decl = push_class (make_class (), qualified_name);
3580
3581   /* Take care of the file and line business */
3582   DECL_SOURCE_FILE (decl) = EXPR_WFL_FILENAME (cl);
3583   /* If we're emiting xrefs, store the line/col number information */
3584   if (flag_emit_xref)
3585     DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (cl);
3586   else
3587     DECL_SOURCE_LINE (decl) = EXPR_WFL_LINENO (cl);
3588   CLASS_FROM_SOURCE_P (TREE_TYPE (decl)) = 1;
3589   CLASS_FROM_CURRENTLY_COMPILED_SOURCE_P (TREE_TYPE (decl)) =
3590     IS_A_COMMAND_LINE_FILENAME_P (EXPR_WFL_FILENAME_NODE (cl));
3591
3592   PUSH_CPC (decl, raw_name);
3593   DECL_CONTEXT (decl) = GET_ENCLOSING_CPC_CONTEXT ();
3594
3595   /* Link the declaration to the already seen ones */
3596   TREE_CHAIN (decl) = ctxp->class_list;
3597   ctxp->class_list = decl;
3598
3599   /* Create a new nodes in the global lists */
3600   ctxp->gclass_list = tree_cons (NULL_TREE, decl, ctxp->gclass_list);
3601   all_class_list = tree_cons (NULL_TREE, decl, all_class_list);
3602
3603   /* Install a new dependency list element */
3604   create_jdep_list (ctxp);
3605
3606   SOURCE_FRONTEND_DEBUG (("Defining class/interface %s", 
3607                           IDENTIFIER_POINTER (qualified_name)));
3608   return decl;
3609 }
3610
3611 static void
3612 add_superinterfaces (decl, interface_list)
3613      tree decl, interface_list;
3614 {
3615   tree node;
3616   /* Superinterface(s): if present and defined, parser_check_super_interface ()
3617      takes care of ensuring that:
3618        - This is an accessible interface type,
3619        - Circularity detection.
3620    parser_add_interface is then called. If present but not defined,
3621    the check operation is delayed until the super interface gets
3622    defined.  */
3623   for (node = interface_list; node; node = TREE_CHAIN (node))
3624     {
3625       tree current = TREE_PURPOSE (node);
3626       tree idecl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (current));
3627       if (idecl && CLASS_LOADED_P (TREE_TYPE (idecl)))
3628         {
3629           if (!parser_check_super_interface (idecl, decl, current))
3630             parser_add_interface (decl, idecl, current);
3631         }
3632       else
3633         register_incomplete_type (JDEP_INTERFACE,
3634                                   current, decl, NULL_TREE);
3635     }
3636 }
3637
3638 /* Create an interface in pass1 and return its decl. Return the
3639    interface's decl in pass 2.  */
3640
3641 static tree
3642 create_interface (flags, id, super)
3643      int flags;
3644      tree id, super;
3645 {
3646   tree raw_name = EXPR_WFL_NODE (id);
3647   tree q_name = parser_qualified_classname (flags & ACC_STATIC, raw_name);
3648   tree decl = IDENTIFIER_CLASS_VALUE (q_name);
3649
3650   EXPR_WFL_NODE (id) = q_name;  /* Keep source location, even if refined. */
3651
3652   /* Basic checks: scope, redefinition, modifiers */ 
3653   if (check_class_interface_creation (1, flags, raw_name, q_name, decl, id))
3654     {
3655       PUSH_ERROR ();
3656       return NULL_TREE;
3657     }
3658
3659   /* Suspend the current parsing context if we're parsing an inner
3660      interface */
3661   if (CPC_INNER_P ())
3662     java_parser_context_suspend ();
3663
3664   /* Push a new context for (static) initialized upon declaration fields */
3665   java_parser_context_push_initialized_field ();
3666
3667   /* Interface modifiers check
3668        - public/abstract allowed (already done at that point)
3669        - abstract is obsolete (comes first, it's a warning, or should be)
3670        - Can't use twice the same (checked in the modifier rule) */
3671   if ((flags & ACC_ABSTRACT) && flag_redundant)
3672     parse_warning_context 
3673       (MODIFIER_WFL (ABSTRACT_TK),
3674        "Redundant use of `abstract' modifier. Interface `%s' is implicitely abstract", IDENTIFIER_POINTER (raw_name));
3675
3676   /* Create a new decl if DECL is NULL, otherwise fix it */
3677   decl = maybe_create_class_interface_decl (decl, raw_name, q_name, id);
3678
3679   /* Set super info and mark the class a complete */
3680   set_super_info (ACC_INTERFACE | flags, TREE_TYPE (decl), 
3681                   object_type_node, ctxp->interface_number);
3682   ctxp->interface_number = 0;
3683   CLASS_COMPLETE_P (decl) = 1;
3684   add_superinterfaces (decl, super);
3685
3686   return decl;
3687 }
3688
3689 /* Anonymous class counter. Will be reset to 1 every time a non
3690    anonymous class gets created. */
3691 static int anonymous_class_counter = 1;
3692
3693 /* Patch anonymous class CLASS, by either extending or implementing
3694    DEP.  */
3695
3696 static void
3697 patch_anonymous_class (type_decl, class_decl, wfl)
3698     tree type_decl, class_decl, wfl;
3699 {
3700   tree class = TREE_TYPE (class_decl);
3701   tree type =  TREE_TYPE (type_decl);
3702   tree binfo = TYPE_BINFO (class);
3703
3704   /* If it's an interface, implement it */
3705   if (CLASS_INTERFACE (type_decl))
3706     {
3707       tree s_binfo;
3708       int length;
3709
3710       if (parser_check_super_interface (type_decl, class_decl, wfl))
3711         return;
3712
3713       s_binfo = TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (class)), 0);
3714       length = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (class))+1;
3715       TYPE_BINFO_BASETYPES (class) = make_tree_vec (length);
3716       TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (class)), 0) = s_binfo;
3717       /* And add the interface */
3718       parser_add_interface (class_decl, type_decl, wfl);
3719     }
3720   /* Otherwise, it's a type we want to extend */
3721   else
3722     {
3723       if (parser_check_super (type_decl, class_decl, wfl))
3724         return;
3725       BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo), 0)) = type;
3726     }
3727 }
3728
3729 static tree
3730 create_anonymous_class (location, type_name)
3731     int location;
3732     tree type_name;
3733 {
3734   char buffer [80];
3735   tree super = NULL_TREE, itf = NULL_TREE;
3736   tree id, type_decl, class;
3737
3738   /* The unqualified name of the anonymous class. It's just a number. */
3739   sprintf (buffer, "%d", anonymous_class_counter++);
3740   id = build_wfl_node (get_identifier (buffer));
3741   EXPR_WFL_LINECOL (id) = location;
3742
3743   /* We know about the type to extend/implement. We go ahead */
3744   if ((type_decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (type_name))))
3745     {
3746       /* Create a class which either implements on extends the designated
3747          class. The class bears an innacessible name. */
3748       if (CLASS_INTERFACE (type_decl))
3749         {
3750           /* It's OK to modify it here. It's been already used and
3751              shouldn't be reused */
3752           ctxp->interface_number = 1;
3753           /* Interfaces should presented as a list of WFLs */
3754           itf = build_tree_list (type_name, NULL_TREE);
3755         }
3756       else
3757         super = type_name;
3758     }
3759
3760   class = create_class (ACC_FINAL, id, super, itf);
3761
3762   /* We didn't know anything about the stuff. We register a dependence. */
3763   if (!type_decl)
3764     register_incomplete_type (JDEP_ANONYMOUS, type_name, class, NULL_TREE);
3765
3766   ANONYMOUS_CLASS_P (TREE_TYPE (class)) = 1;
3767   return class;
3768 }
3769
3770 /* Create a class in pass1 and return its decl. Return class
3771    interface's decl in pass 2.  */
3772
3773 static tree
3774 create_class (flags, id, super, interfaces)
3775      int flags;
3776      tree id, super, interfaces;
3777 {
3778   tree raw_name = EXPR_WFL_NODE (id);
3779   tree class_id, decl;
3780   tree super_decl_type;
3781
3782   class_id = parser_qualified_classname (0, raw_name);
3783   decl = IDENTIFIER_CLASS_VALUE (class_id);
3784   EXPR_WFL_NODE (id) = class_id;
3785
3786   /* Basic check: scope, redefinition, modifiers */
3787   if (check_class_interface_creation (0, flags, raw_name, class_id, decl, id))
3788     {
3789       PUSH_ERROR ();
3790       return NULL_TREE;
3791     }
3792   
3793   /* Suspend the current parsing context if we're parsing an inner
3794      class or an anonymous class. */
3795   if (CPC_INNER_P ())
3796     java_parser_context_suspend ();
3797   /* Push a new context for (static) initialized upon declaration fields */
3798   java_parser_context_push_initialized_field ();
3799
3800   /* Class modifier check: 
3801        - Allowed modifier (already done at that point)
3802        - abstract AND final forbidden 
3803        - Public classes defined in the correct file */
3804   if ((flags & ACC_ABSTRACT) && (flags & ACC_FINAL))
3805     parse_error_context
3806       (id, "Class `%s' can't be declared both abstract and final",
3807        IDENTIFIER_POINTER (raw_name));
3808
3809   /* Create a new decl if DECL is NULL, otherwise fix it */
3810   decl = maybe_create_class_interface_decl (decl, raw_name, class_id, id);
3811
3812   /* If SUPER exists, use it, otherwise use Object */
3813   if (super)
3814     {
3815       /* Can't extend java.lang.Object */
3816       if (TREE_TYPE (IDENTIFIER_CLASS_VALUE (class_id)) == object_type_node)
3817         {
3818           parse_error_context (id, "Can't extend `java.lang.Object'");
3819           return NULL_TREE;
3820         }
3821
3822       super_decl_type = 
3823         register_incomplete_type (JDEP_SUPER, super, decl, NULL_TREE);
3824     }
3825   else if (TREE_TYPE (decl) != object_type_node)
3826     super_decl_type = object_type_node;
3827   /* We're defining java.lang.Object */
3828   else
3829     super_decl_type = NULL_TREE;
3830
3831   /* Set super info and mark the class a complete */
3832   set_super_info (flags, TREE_TYPE (decl), super_decl_type, 
3833                   ctxp->interface_number);
3834   ctxp->interface_number = 0;
3835   CLASS_COMPLETE_P (decl) = 1;
3836   add_superinterfaces (decl, interfaces);
3837
3838   /* If the class is a top level inner class, install an alias. */
3839   if (INNER_CLASS_DECL_P (decl) && CLASS_STATIC (decl))
3840     {
3841       tree alias = parser_qualified_classname (1, raw_name);
3842       IDENTIFIER_GLOBAL_VALUE (alias) = decl;
3843     }
3844
3845   /* Add the private this$<n> field, Replicate final locals still in
3846      scope as private final fields mangled like val$<local_name>.
3847      This doesn't not occur for top level (static) inner classes. */
3848   if (PURE_INNER_CLASS_DECL_P (decl))
3849     add_inner_class_fields (decl, current_function_decl);
3850
3851   /* If doing xref, store the location at which the inherited class
3852      (if any) was seen. */
3853   if (flag_emit_xref && super)
3854     DECL_INHERITED_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (super);
3855
3856   /* Eventually sets the @deprecated tag flag */
3857   CHECK_DEPRECATED (decl);
3858
3859   /* Reset the anonymous class counter when declaring non inner classes */
3860   if (!INNER_CLASS_DECL_P (decl))
3861     anonymous_class_counter = 1;
3862
3863   return decl;
3864 }
3865
3866 /* End a class declaration: register the statements used to create
3867    $finit$ and <clinit>, pop the current class and resume the prior
3868    parser context if necessary.  */
3869
3870 static void
3871 end_class_declaration (resume)
3872      int resume;
3873 {
3874   /* If an error occured, context weren't pushed and won't need to be
3875      popped by a resume. */
3876   int no_error_occured = ctxp->next && GET_CPC () != error_mark_node;
3877
3878   java_parser_context_pop_initialized_field ();
3879   POP_CPC ();
3880   if (resume && no_error_occured)
3881     java_parser_context_resume ();
3882
3883   /* We're ending a class declaration, this is a good time to reset
3884      the interface cout. Note that might have been already done in
3885      create_interface, but if at that time an inner class was being
3886      dealt with, the interface count was reset in a context created
3887      for the sake of handling inner classes declaration. */
3888   ctxp->interface_number = 0;
3889 }
3890
3891 static void
3892 add_inner_class_fields (class_decl, fct_decl)
3893      tree class_decl;
3894      tree fct_decl;
3895 {
3896   tree block, marker, f;
3897
3898   f = add_field (TREE_TYPE (class_decl),
3899                  build_current_thisn (TREE_TYPE (class_decl)),
3900                  build_pointer_type (TREE_TYPE (DECL_CONTEXT (class_decl))), 
3901                  ACC_PRIVATE);
3902   FIELD_THISN (f) = 1;
3903
3904   if (!fct_decl)
3905     return;
3906     
3907   for (block = GET_CURRENT_BLOCK (fct_decl); 
3908        block && TREE_CODE (block) == BLOCK; block = BLOCK_SUPERCONTEXT (block))
3909     {
3910       tree decl;
3911       for (decl = BLOCK_EXPR_DECLS (block); decl; decl = TREE_CHAIN (decl))
3912         {
3913           char *name, *pname;
3914           tree wfl, init, list;
3915           
3916           /* Avoid non final arguments. */
3917           if (!LOCAL_FINAL (decl))
3918             continue;
3919           
3920           MANGLE_OUTER_LOCAL_VARIABLE_NAME (name, DECL_NAME (decl));
3921           MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_ID (pname, DECL_NAME (decl));
3922           wfl = build_wfl_node (get_identifier (name));
3923           init = build_wfl_node (get_identifier (pname));
3924           /* Build an initialization for the field: it will be
3925              initialized by a parameter added to $finit$, bearing a
3926              mangled name of the field itself (param$<n>.) The
3927              parameter is provided to $finit$ by the constructor
3928              invoking it (hence the constructor will also feature a
3929              hidden parameter, set to the value of the outer context
3930              local at the time the inner class is created.)
3931              
3932              Note: we take into account all possible locals that can
3933              be accessed by the inner class. It's actually not trivial
3934              to minimize these aliases down to the ones really
3935              used. One way to do that would be to expand all regular
3936              methods first, then $finit$ to get a picture of what's
3937              used.  It works with the exception that we would have to
3938              go back on all constructor invoked in regular methods to
3939              have their invokation reworked (to include the right amount
3940              of alias initializer parameters.)
3941
3942              The only real way around, I think, is a first pass to
3943              identify locals really used in the inner class. We leave
3944              the flag FIELD_LOCAL_ALIAS_USED around for that future
3945              use.
3946              
3947              On the other hand, it only affect local inner classes,
3948              whose constructors (and $finit$ call) will be featuring
3949              unecessary arguments. It's easy for a developper to keep
3950              this number of parameter down by using the `final'
3951              keyword only when necessary. For the time being, we can
3952              issue a warning on unecessary finals. FIXME */
3953           init = build_assignment (ASSIGN_TK, EXPR_WFL_LINECOL (wfl), 
3954                                    wfl, init);
3955
3956           /* Register the field. The TREE_LIST holding the part
3957              initialized/initializer will be marked ARG_FINAL_P so
3958              that the created field can be marked
3959              FIELD_LOCAL_ALIAS. */
3960           list = build_tree_list (wfl, init);
3961           ARG_FINAL_P (list) = 1;
3962           register_fields (ACC_PRIVATE | ACC_FINAL, TREE_TYPE (decl), list);
3963         }
3964     }
3965
3966   if (!CPC_INITIALIZER_STMT (ctxp))
3967     return;
3968
3969   /* If we ever registered an alias field, insert and marker to
3970      remeber where the list ends. The second part of the list (the one
3971      featuring initialized fields) so it can be later reversed to
3972      enforce 8.5. The marker will be removed during that operation. */
3973   marker = build_tree_list (NULL_TREE, NULL_TREE);
3974   TREE_CHAIN (marker) = CPC_INITIALIZER_STMT (ctxp);
3975   SET_CPC_INITIALIZER_STMT (ctxp, marker);
3976 }
3977
3978 /* Can't use lookup_field () since we don't want to load the class and
3979    can't set the CLASS_LOADED_P flag */
3980
3981 static tree
3982 find_field (class, name)
3983      tree class;
3984      tree name;
3985 {
3986   tree decl;
3987   for (decl = TYPE_FIELDS (class); decl; decl = TREE_CHAIN (decl))
3988     {
3989       if (DECL_NAME (decl) == name)
3990         return decl;
3991     }
3992   return NULL_TREE;
3993 }
3994
3995 /* Wrap around lookup_field that doesn't potentially upset the value
3996    of CLASS */
3997
3998 static tree
3999 lookup_field_wrapper (class, name)
4000      tree class, name;
4001 {
4002   tree type = class;
4003   tree decl = NULL_TREE;
4004   java_parser_context_save_global ();
4005
4006   /* Last chance: if we're within the context of an inner class, we
4007      might be trying to access a local variable defined in an outer
4008      context. We try to look for it now. */
4009   if (INNER_CLASS_TYPE_P (class))
4010     {
4011       char *alias_buffer;
4012       tree new_name;
4013       MANGLE_OUTER_LOCAL_VARIABLE_NAME (alias_buffer, name);
4014       new_name = get_identifier (alias_buffer);
4015       decl = lookup_field (&type, new_name);
4016       if (decl && decl != error_mark_node)
4017         FIELD_LOCAL_ALIAS_USED (decl) = 1;
4018     }
4019   if (!decl || decl == error_mark_node)
4020     {
4021       type = class;
4022       decl = lookup_field (&type, name);
4023     }
4024
4025   java_parser_context_restore_global ();
4026   return decl == error_mark_node ? NULL : decl;
4027 }
4028
4029 /* Find duplicate field within the same class declarations and report
4030    the error. Returns 1 if a duplicated field was found, 0
4031    otherwise.  */
4032
4033 static int
4034 duplicate_declaration_error_p (new_field_name, new_type, cl)
4035      tree new_field_name, new_type, cl;
4036 {
4037   /* This might be modified to work with method decl as well */
4038   tree decl = find_field (TREE_TYPE (GET_CPC ()), new_field_name);
4039   if (decl)
4040     {
4041       char *t1 = xstrdup (purify_type_name
4042                          ((TREE_CODE (new_type) == POINTER_TYPE 
4043                            && TREE_TYPE (new_type) == NULL_TREE) ?
4044                           IDENTIFIER_POINTER (TYPE_NAME (new_type)) :
4045                           lang_printable_name (new_type, 1)));
4046       /* The type may not have been completed by the time we report
4047          the error */
4048       char *t2 = xstrdup (purify_type_name
4049                          ((TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE 
4050                            && TREE_TYPE (TREE_TYPE (decl)) == NULL_TREE) ?
4051                           IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl))) :
4052                           lang_printable_name (TREE_TYPE (decl), 1)));
4053       parse_error_context 
4054         (cl , "Duplicate variable declaration: `%s %s' was `%s %s' (%s:%d)", 
4055          t1, IDENTIFIER_POINTER (new_field_name),
4056          t2, IDENTIFIER_POINTER (DECL_NAME (decl)),
4057          DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
4058       free (t1);
4059       free (t2);
4060       return 1;
4061     }
4062   return 0;
4063 }
4064
4065 /* Field registration routine. If TYPE doesn't exist, field
4066    declarations are linked to the undefined TYPE dependency list, to
4067    be later resolved in java_complete_class () */
4068
4069 static void
4070 register_fields (flags, type, variable_list)
4071      int flags;
4072      tree type, variable_list;
4073 {
4074   tree current, saved_type;
4075   tree class_type = NULL_TREE;
4076   int saved_lineno = lineno;
4077   int must_chain = 0;
4078   tree wfl = NULL_TREE;
4079
4080   if (GET_CPC ())
4081     class_type = TREE_TYPE (GET_CPC ());
4082
4083   if (!class_type || class_type == error_mark_node)
4084     return;
4085
4086   /* If we're adding fields to interfaces, those fields are public,
4087      static, final */
4088   if (CLASS_INTERFACE (TYPE_NAME (class_type)))
4089     {
4090       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (PUBLIC_TK),
4091                                  flags, ACC_PUBLIC, "interface field(s)");
4092       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (STATIC_TK),
4093                                  flags, ACC_STATIC, "interface field(s)");
4094       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (FINAL_TK),
4095                                  flags, ACC_FINAL, "interface field(s)");
4096       check_modifiers ("Illegal interface member modifier `%s'", flags,
4097                        INTERFACE_FIELD_MODIFIERS);
4098       flags |= (ACC_PUBLIC | ACC_STATIC | ACC_FINAL);
4099     }
4100
4101   /* Obtain a suitable type for resolution, if necessary */
4102   SET_TYPE_FOR_RESOLUTION (type, wfl, must_chain);
4103
4104   /* If TYPE is fully resolved and we don't have a reference, make one */
4105   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4106
4107   for (current = variable_list, saved_type = type; current; 
4108        current = TREE_CHAIN (current), type = saved_type)
4109     {
4110       tree real_type;
4111       tree field_decl;
4112       tree cl = TREE_PURPOSE (current);
4113       tree init = TREE_VALUE (current);
4114       tree current_name = EXPR_WFL_NODE (cl);
4115
4116       /* Can't declare static fields in inner classes */
4117       if ((flags & ACC_STATIC) && !TOPLEVEL_CLASS_TYPE_P (class_type)
4118           && !CLASS_INTERFACE (TYPE_NAME (class_type)))
4119         parse_error_context 
4120           (cl, "Field `%s' can't be static in innerclass `%s'. Only members of interfaces and top-level classes can be static",
4121            IDENTIFIER_POINTER (EXPR_WFL_NODE (cl)),
4122            lang_printable_name (class_type, 0));
4123
4124       /* Process NAME, as it may specify extra dimension(s) for it */
4125       type = build_array_from_name (type, wfl, current_name, &current_name);
4126
4127       /* Type adjustment. We may have just readjusted TYPE because
4128          the variable specified more dimensions. Make sure we have
4129          a reference if we can and don't have one already. Also
4130          change the name if we have an init. */
4131       if (type != saved_type)
4132         {
4133           PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4134           if (init)
4135             EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = current_name;
4136         }
4137
4138       real_type = GET_REAL_TYPE (type);
4139       /* Check for redeclarations */
4140       if (duplicate_declaration_error_p (current_name, real_type, cl))
4141         continue;
4142
4143       /* Set lineno to the line the field was found and create a
4144          declaration for it. Eventually sets the @deprecated tag flag. */
4145       if (flag_emit_xref)
4146         lineno = EXPR_WFL_LINECOL (cl);
4147       else
4148         lineno = EXPR_WFL_LINENO (cl);
4149       field_decl = add_field (class_type, current_name, real_type, flags);
4150       CHECK_DEPRECATED (field_decl);
4151
4152       /* If the couple initializer/initialized is marked ARG_FINAL_P, we
4153          mark the created field FIELD_LOCAL_ALIAS, so that we can 
4154          hide parameters to this inner class $finit$ and constructors. */
4155       if (ARG_FINAL_P (current))
4156         FIELD_LOCAL_ALIAS (field_decl) = 1;
4157       
4158       /* Check if we must chain. */
4159       if (must_chain)
4160         register_incomplete_type (JDEP_FIELD, wfl, field_decl, type);
4161           
4162       /* If we have an initialization value tied to the field */
4163       if (init)
4164         {
4165           /* The field is declared static */
4166           if (flags & ACC_STATIC)
4167             {
4168               /* We include the field and its initialization part into
4169                  a list used to generate <clinit>. After <clinit> is
4170                  walked, field initializations will be processed and
4171                  fields initialized with known constants will be taken
4172                  out of <clinit> and have their DECL_INITIAL set
4173                  appropriately. */
4174               TREE_CHAIN (init) = CPC_STATIC_INITIALIZER_STMT (ctxp);
4175               SET_CPC_STATIC_INITIALIZER_STMT (ctxp, init);
4176               if (TREE_OPERAND (init, 1) 
4177                   && TREE_CODE (TREE_OPERAND (init, 1)) == NEW_ARRAY_INIT)
4178                 TREE_STATIC (TREE_OPERAND (init, 1)) = 1;
4179             }
4180           /* A non-static field declared with an immediate initialization is
4181              to be initialized in <init>, if any.  This field is remembered
4182              to be processed at the time of the generation of <init>. */
4183           else
4184             {
4185               TREE_CHAIN (init) = CPC_INITIALIZER_STMT (ctxp);
4186               SET_CPC_INITIALIZER_STMT (ctxp, init);
4187             }
4188           MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
4189           DECL_INITIAL (field_decl) = TREE_OPERAND (init, 1);
4190         }
4191     }
4192   lineno = saved_lineno;
4193 }
4194
4195 /* Generate $finit$, using the list of initialized fields to populate
4196    its body. $finit$'s parameter(s) list is adjusted to include the
4197    one(s) used to initialized the field(s) caching outer context
4198    local(s). */
4199
4200 static tree
4201 generate_finit (class_type)
4202      tree class_type;
4203 {
4204   int count = 0;
4205   tree list = TYPE_FINIT_STMT_LIST (class_type);
4206   tree mdecl, current, parms;
4207
4208   parms = build_alias_initializer_parameter_list (AIPL_FUNCTION_CREATION, 
4209                                                   class_type, NULL_TREE, 
4210                                                   &count);
4211   CRAFTED_PARAM_LIST_FIXUP (parms);
4212   mdecl = create_artificial_method (class_type, ACC_PRIVATE, void_type_node,
4213                                     finit_identifier_node, parms);
4214   fix_method_argument_names (parms, mdecl);
4215   layout_class_method (class_type, CLASSTYPE_SUPER (class_type),
4216                        mdecl, NULL_TREE);
4217   DECL_FUNCTION_NAP (mdecl) = count;
4218   start_artificial_method_body (mdecl);
4219
4220   for (current = list; current; current = TREE_CHAIN (current))
4221     java_method_add_stmt (mdecl, 
4222                           build_debugable_stmt (EXPR_WFL_LINECOL (current), 
4223                                                 current));
4224   end_artificial_method_body (mdecl);
4225   return mdecl;
4226 }
4227
4228 static void
4229 add_instance_initializer (mdecl)
4230      tree mdecl;
4231 {
4232   tree current;
4233   tree stmt_list = TYPE_II_STMT_LIST (DECL_CONTEXT (mdecl));
4234   tree compound = NULL_TREE;
4235
4236   if (stmt_list)
4237     {
4238       for (current = stmt_list; current; current = TREE_CHAIN (current))
4239         compound = add_stmt_to_compound (compound, NULL_TREE, current);
4240
4241       java_method_add_stmt (mdecl, build1 (INSTANCE_INITIALIZERS_EXPR,
4242                                            NULL_TREE, compound));
4243     }
4244 }
4245
4246 /* Shared accros method_declarator and method_header to remember the
4247    patch stage that was reached during the declaration of the method.
4248    A method DECL is built differently is there is no patch
4249    (JDEP_NO_PATCH) or a patch (JDEP_METHOD or JDEP_METHOD_RETURN)
4250    pending on the currently defined method.  */
4251
4252 static int patch_stage;
4253
4254 /* Check the method declaration and add the method to its current
4255    class.  If the argument list is known to contain incomplete types,
4256    the method is partially added and the registration will be resume
4257    once the method arguments resolved. If TYPE is NULL, we're dealing
4258    with a constructor.  */
4259
4260 static tree
4261 method_header (flags, type, mdecl, throws)
4262      int flags;
4263      tree type, mdecl, throws;
4264 {
4265   tree meth = TREE_VALUE (mdecl);
4266   tree id = TREE_PURPOSE (mdecl);
4267   tree type_wfl = NULL_TREE;
4268   tree meth_name = NULL_TREE;
4269   tree current, orig_arg, this_class = NULL;
4270   int saved_lineno;
4271   int constructor_ok = 0, must_chain;
4272   int count;
4273   
4274   check_modifiers_consistency (flags);
4275
4276   if (GET_CPC ())
4277     this_class = TREE_TYPE (GET_CPC ());
4278
4279   if (!this_class || this_class == error_mark_node)
4280     return NULL_TREE;
4281   
4282   /* There are some forbidden modifiers for an abstract method and its
4283      class must be abstract as well.  */
4284   if (type && (flags & ACC_ABSTRACT))
4285     {
4286       ABSTRACT_CHECK (flags, ACC_PRIVATE, id, "Private");
4287       ABSTRACT_CHECK (flags, ACC_STATIC, id, "Static");
4288       ABSTRACT_CHECK (flags, ACC_FINAL, id, "Final");
4289       ABSTRACT_CHECK (flags, ACC_NATIVE, id, "Native");
4290       ABSTRACT_CHECK (flags, ACC_SYNCHRONIZED,id, "Synchronized");
4291       if (!CLASS_ABSTRACT (TYPE_NAME (this_class))
4292           && !CLASS_INTERFACE (TYPE_NAME (this_class)))
4293         parse_error_context 
4294           (id, "Class `%s' must be declared abstract to define abstract method `%s'", 
4295            IDENTIFIER_POINTER (DECL_NAME (ctxp->current_parsed_class)),
4296            IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
4297     }
4298
4299   /* Things to be checked when declaring a constructor */
4300   if (!type)
4301     {
4302       int ec = java_error_count;
4303       /* 8.6: Constructor declarations: we might be trying to define a
4304          method without specifying a return type. */
4305       if (EXPR_WFL_NODE (id) != GET_CPC_UN ())
4306         parse_error_context 
4307           (id, "Invalid method declaration, return type required");
4308       /* 8.6.3: Constructor modifiers */
4309       else
4310         {
4311           JCONSTRUCTOR_CHECK (flags, ACC_ABSTRACT, id, "abstract");
4312           JCONSTRUCTOR_CHECK (flags, ACC_STATIC, id, "static");
4313           JCONSTRUCTOR_CHECK (flags, ACC_FINAL, id, "final");
4314           JCONSTRUCTOR_CHECK (flags, ACC_NATIVE, id, "native");
4315           JCONSTRUCTOR_CHECK (flags, ACC_SYNCHRONIZED, id, "synchronized");
4316         }
4317       /* If we found error here, we don't consider it's OK to tread
4318          the method definition as a constructor, for the rest of this
4319          function */
4320       if (ec == java_error_count)
4321         constructor_ok = 1;
4322     }
4323
4324   /* Method declared within the scope of an interface are implicitly
4325      abstract and public. Conflicts with other erroneously provided
4326      modifiers are checked right after. */
4327
4328   if (CLASS_INTERFACE (TYPE_NAME (this_class)))
4329     {
4330       /* If FLAGS isn't set because of a modifier, turn the
4331          corresponding modifier WFL to NULL so we issue a warning on
4332          the obsolete use of the modifier */
4333       if (!(flags & ACC_PUBLIC))
4334         MODIFIER_WFL (PUBLIC_TK) = NULL;
4335       if (!(flags & ACC_ABSTRACT))
4336         MODIFIER_WFL (ABSTRACT_TK) = NULL;
4337       flags |= ACC_PUBLIC;
4338       flags |= ACC_ABSTRACT;
4339     }
4340
4341   /* Inner class can't declare static methods */
4342   if ((flags & ACC_STATIC) && !TOPLEVEL_CLASS_TYPE_P (this_class))
4343     {
4344       parse_error_context 
4345         (id, "Method `%s' can't be static in inner class `%s'. Only members of interfaces and top-level classes can be static",
4346          IDENTIFIER_POINTER (EXPR_WFL_NODE (id)),
4347          lang_printable_name (this_class, 0));
4348     }
4349
4350   /* Modifiers context reset moved up, so abstract method declaration
4351      modifiers can be later checked.  */
4352
4353   /* Set constructor returned type to void and method name to <init>,
4354      unless we found an error identifier the constructor (in which
4355      case we retain the original name) */
4356   if (!type)
4357     {
4358       type = void_type_node;
4359       if (constructor_ok)
4360         meth_name = init_identifier_node;
4361     }
4362   else
4363     meth_name = EXPR_WFL_NODE (id);
4364
4365   /* Do the returned type resolution and registration if necessary */
4366   SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
4367
4368   if (meth_name)
4369     type = build_array_from_name (type, type_wfl, meth_name, &meth_name);
4370   EXPR_WFL_NODE (id) = meth_name;
4371   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4372
4373   if (must_chain)
4374     {
4375       patch_stage = JDEP_METHOD_RETURN;
4376       register_incomplete_type (patch_stage, type_wfl, id, type);
4377       TREE_TYPE (meth) = GET_REAL_TYPE (type);
4378     }
4379   else
4380     TREE_TYPE (meth) = type;
4381
4382   saved_lineno = lineno;
4383   /* When defining an abstract or interface method, the curly
4384      bracket at level 1 doesn't exist because there is no function
4385      body */
4386   lineno = (ctxp->first_ccb_indent1 ? ctxp->first_ccb_indent1 : 
4387             EXPR_WFL_LINENO (id));
4388
4389   /* Remember the original argument list */
4390   orig_arg = TYPE_ARG_TYPES (meth);
4391
4392   if (patch_stage)              /* includes ret type and/or all args */
4393     {
4394       jdep *jdep;
4395       meth = add_method_1 (this_class, flags, meth_name, meth);
4396       /* Patch for the return type */
4397       if (patch_stage == JDEP_METHOD_RETURN)
4398         {
4399           jdep = CLASSD_LAST (ctxp->classd_list);
4400           JDEP_GET_PATCH (jdep) = &TREE_TYPE (TREE_TYPE (meth));
4401         }
4402       /* This is the stop JDEP. METH allows the function's signature
4403          to be computed. */
4404       register_incomplete_type (JDEP_METHOD_END, NULL_TREE, meth, NULL_TREE);
4405     }
4406   else
4407     meth = add_method (this_class, flags, meth_name, 
4408                        build_java_signature (meth));
4409
4410   /* Remember final parameters */
4411   MARK_FINAL_PARMS (meth, orig_arg);
4412
4413   /* Fix the method argument list so we have the argument name
4414      information */
4415   fix_method_argument_names (orig_arg, meth);
4416
4417   /* Register the parameter number and re-install the current line
4418      number */
4419   DECL_MAX_LOCALS (meth) = ctxp->formal_parameter_number+1;
4420   lineno = saved_lineno;
4421
4422   /* Register exception specified by the `throws' keyword for
4423      resolution and set the method decl appropriate field to the list.
4424      Note: the grammar ensures that what we get here are class
4425      types. */
4426   if (throws)
4427     {
4428       throws = nreverse (throws);
4429       for (current = throws; current; current = TREE_CHAIN (current))
4430         {
4431           register_incomplete_type (JDEP_EXCEPTION, TREE_VALUE (current),
4432                                     NULL_TREE, NULL_TREE);
4433           JDEP_GET_PATCH (CLASSD_LAST (ctxp->classd_list)) = 
4434             &TREE_VALUE (current);
4435         }
4436       DECL_FUNCTION_THROWS (meth) = throws;
4437     }
4438
4439   /* We set the DECL_NAME to ID so we can track the location where
4440      the function was declared. This allow us to report
4441      redefinition error accurately. When method are verified,
4442      DECL_NAME is reinstalled properly (using the content of the
4443      WFL node ID) (see check_method_redefinition). We don't do that
4444      when Object is being defined. Constructor <init> names will be
4445      reinstalled the same way. */
4446   if (TREE_TYPE (GET_CPC ()) != object_type_node)
4447     DECL_NAME (meth) = id;
4448
4449   /* Set the flag if we correctly processed a constructor */
4450   if (constructor_ok)
4451     {
4452       DECL_CONSTRUCTOR_P (meth) = 1;
4453       /* Compute and store the number of artificial parameters declared
4454          for this constructor */
4455       for (count = 0, current = TYPE_FIELDS (this_class); current; 
4456            current = TREE_CHAIN (current))
4457         if (FIELD_LOCAL_ALIAS (current))
4458           count++;
4459       DECL_FUNCTION_NAP (meth) = count;
4460     }
4461
4462   /* Eventually set the @deprecated tag flag */
4463   CHECK_DEPRECATED (meth);
4464
4465   /* If doing xref, store column and line number information instead
4466      of the line number only. */
4467   if (flag_emit_xref)
4468     DECL_SOURCE_LINE (meth) = EXPR_WFL_LINECOL (id);
4469
4470   return meth;
4471 }
4472
4473 static void
4474 fix_method_argument_names (orig_arg, meth)
4475     tree orig_arg, meth;
4476 {
4477   tree arg = TYPE_ARG_TYPES (TREE_TYPE (meth));
4478   if (TREE_CODE (TREE_TYPE (meth)) == METHOD_TYPE)
4479     {
4480       TREE_PURPOSE (arg) = this_identifier_node;
4481       arg = TREE_CHAIN (arg);
4482     }
4483   while (orig_arg != end_params_node)
4484     {
4485       TREE_PURPOSE (arg) = TREE_PURPOSE (orig_arg);
4486       orig_arg = TREE_CHAIN (orig_arg);
4487       arg = TREE_CHAIN (arg);
4488     }
4489 }
4490
4491 /* Complete the method declaration with METHOD_BODY.  */
4492
4493 static void
4494 finish_method_declaration (method_body)
4495      tree method_body;
4496 {
4497   int flags;
4498
4499   if (!current_function_decl)
4500     return;
4501
4502   flags = get_access_flags_from_decl (current_function_decl);
4503
4504   /* 8.4.5 Method Body */
4505   if ((flags & ACC_ABSTRACT || flags & ACC_NATIVE) && method_body)
4506     {
4507       tree wfl = DECL_NAME (current_function_decl);
4508       parse_error_context (wfl, 
4509                            "%s method `%s' can't have a body defined",
4510                            (METHOD_NATIVE (current_function_decl) ?
4511                             "Native" : "Abstract"),
4512                            IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
4513       method_body = NULL_TREE;
4514     }
4515   else if (!(flags & ACC_ABSTRACT) && !(flags & ACC_NATIVE) && !method_body)
4516     {
4517       tree wfl = DECL_NAME (current_function_decl);
4518       parse_error_context
4519         (wfl, 
4520          "Non native and non abstract method `%s' must have a body defined",
4521          IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
4522       method_body = NULL_TREE;
4523     }
4524
4525   if (flag_emit_class_files && method_body 
4526       && TREE_CODE (method_body) == NOP_EXPR 
4527       && TREE_TYPE (current_function_decl) 
4528       && TREE_TYPE (TREE_TYPE (current_function_decl)) == void_type_node)
4529     method_body = build1 (RETURN_EXPR, void_type_node, NULL);
4530
4531   BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (current_function_decl)) = method_body;
4532   maybe_absorb_scoping_blocks ();
4533   /* Exit function's body */
4534   exit_block ();
4535   /* Merge last line of the function with first line, directly in the
4536      function decl. It will be used to emit correct debug info. */
4537   if (!flag_emit_xref)
4538     DECL_SOURCE_LINE_MERGE (current_function_decl, ctxp->last_ccb_indent1);
4539
4540   /* Since function's argument's list are shared, reset the
4541      ARG_FINAL_P parameter that might have been set on some of this
4542      function parameters. */
4543   UNMARK_FINAL_PARMS (current_function_decl);
4544   
4545   /* So we don't have an irrelevant function declaration context for
4546      the next static block we'll see. */
4547   current_function_decl = NULL_TREE;
4548 }
4549
4550 /* Build a an error message for constructor circularity errors.  */
4551
4552 static char *
4553 constructor_circularity_msg (from, to)
4554      tree from, to;
4555 {
4556   static char string [4096];
4557   char *t = xstrdup (lang_printable_name (from, 0));
4558   sprintf (string, "`%s' invokes `%s'", t, lang_printable_name (to, 0));
4559   free (t);
4560   return string;
4561 }
4562
4563 /* Verify a circular call to METH. Return 1 if an error is found, 0
4564    otherwise.  */
4565
4566 static int
4567 verify_constructor_circularity (meth, current)
4568      tree meth, current;
4569 {
4570   static tree list = NULL_TREE;
4571   tree c;
4572   for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
4573     {
4574       if (TREE_VALUE (c) == meth)
4575         {
4576           char *t;
4577           if (list)
4578             {
4579               tree liste;
4580               list = nreverse (list);
4581               for (liste = list; liste; liste = TREE_CHAIN (liste))
4582                 {
4583                   parse_error_context 
4584                     (TREE_PURPOSE (TREE_PURPOSE (liste)), "%s",
4585                      constructor_circularity_msg
4586                       (TREE_VALUE (liste), TREE_VALUE (TREE_PURPOSE (liste)))); 
4587                   java_error_count--;
4588                 }
4589             }
4590           t = xstrdup (lang_printable_name (meth, 0));
4591           parse_error_context (TREE_PURPOSE (c), 
4592                                "%s: recursive invocation of constructor `%s'",
4593                                constructor_circularity_msg (current, meth), t);
4594           free (t);
4595           list = NULL_TREE;
4596           return 1;
4597         }
4598     }
4599   for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
4600     {
4601       list = tree_cons (c, current, list);
4602       if (verify_constructor_circularity (meth, TREE_VALUE (c)))
4603         return 1;
4604       list = TREE_CHAIN (list);
4605     }
4606   return 0;
4607 }
4608
4609 /* Check modifiers that can be declared but exclusively */
4610
4611 static void
4612 check_modifiers_consistency (flags)
4613      int flags;
4614 {
4615   int acc_count = 0;
4616   tree cl = NULL_TREE;
4617
4618   THIS_MODIFIER_ONLY (flags, ACC_PUBLIC, PUBLIC_TK, acc_count, cl);
4619   THIS_MODIFIER_ONLY (flags, ACC_PRIVATE, PRIVATE_TK, acc_count, cl);
4620   THIS_MODIFIER_ONLY (flags, ACC_PROTECTED, PROTECTED_TK, acc_count, cl);
4621   if (acc_count > 1)
4622     parse_error_context
4623       (cl, "Inconsistent member declaration.  At most one of `public', `private', or `protected' may be specified");
4624
4625   acc_count = 0;
4626   cl = NULL_TREE;
4627   THIS_MODIFIER_ONLY (flags, ACC_FINAL, FINAL_TK, acc_count, cl);
4628   THIS_MODIFIER_ONLY (flags, ACC_VOLATILE, VOLATILE_TK, acc_count, cl);
4629   if (acc_count > 1)
4630     parse_error_context (cl,
4631                          "Inconsistent member declaration.  At most one of `final' or `volatile' may be specified");
4632 }
4633
4634 /* Check the methode header METH for abstract specifics features */
4635
4636 static void
4637 check_abstract_method_header (meth)
4638      tree meth;
4639 {
4640   int flags = get_access_flags_from_decl (meth);
4641   /* DECL_NAME might still be a WFL node */
4642   tree name = GET_METHOD_NAME (meth);
4643
4644   OBSOLETE_MODIFIER_WARNING2 (MODIFIER_WFL (ABSTRACT_TK), flags,
4645                               ACC_ABSTRACT, "abstract method",
4646                               IDENTIFIER_POINTER (name));
4647   OBSOLETE_MODIFIER_WARNING2 (MODIFIER_WFL (PUBLIC_TK), flags, 
4648                               ACC_PUBLIC, "abstract method",
4649                               IDENTIFIER_POINTER (name));
4650
4651   check_modifiers ("Illegal modifier `%s' for interface method",
4652                   flags, INTERFACE_METHOD_MODIFIERS);
4653 }
4654
4655 /* Create a FUNCTION_TYPE node and start augmenting it with the
4656    declared function arguments. Arguments type that can't be resolved
4657    are left as they are, but the returned node is marked as containing
4658    incomplete types.  */
4659
4660 static tree
4661 method_declarator (id, list)
4662      tree id, list;
4663 {
4664   tree arg_types = NULL_TREE, current, node;
4665   tree meth = make_node (FUNCTION_TYPE);
4666   jdep *jdep;
4667
4668   patch_stage = JDEP_NO_PATCH;
4669
4670   /* If we're dealing with an inner class constructor, we hide the
4671      this$<n> decl in the name field of its parameter declaration.  We
4672      also might have to hide the outer context local alias
4673      initializers. Not done when the class is a toplevel class. */
4674   if (PURE_INNER_CLASS_DECL_P (GET_CPC ()) 
4675       && EXPR_WFL_NODE (id) == GET_CPC_UN ())
4676     {
4677       tree aliases_list, type, thisn;
4678       /* First the aliases, linked to the regular parameters */
4679       aliases_list =
4680         build_alias_initializer_parameter_list (AIPL_FUNCTION_DECLARATION, 
4681                                                 TREE_TYPE (GET_CPC ()),
4682                                                 NULL_TREE, NULL);
4683       list = chainon (nreverse (aliases_list), list);
4684
4685       /* Then this$<n> */
4686       type = TREE_TYPE (DECL_CONTEXT (GET_CPC ()));
4687       thisn = build_current_thisn (TREE_TYPE (GET_CPC ()));
4688       list = tree_cons (build_wfl_node (thisn), build_pointer_type (type),
4689                         list);
4690     }
4691   
4692   for (current = list; current; current = TREE_CHAIN (current))
4693     {
4694       int must_chain = 0;
4695       tree wfl_name = TREE_PURPOSE (current);
4696       tree type = TREE_VALUE (current);
4697       tree name = EXPR_WFL_NODE (wfl_name);
4698       tree already, arg_node;
4699       tree type_wfl = NULL_TREE;
4700       tree real_type;
4701
4702       /* Obtain a suitable type for resolution, if necessary */
4703       SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
4704
4705       /* Process NAME, as it may specify extra dimension(s) for it */
4706       type = build_array_from_name (type, type_wfl, name, &name);
4707       EXPR_WFL_NODE (wfl_name) = name;
4708
4709       real_type = GET_REAL_TYPE (type);
4710       if (TREE_CODE (real_type) == RECORD_TYPE)
4711         {
4712           real_type = promote_type (real_type);
4713           if (TREE_CODE (type) == TREE_LIST)
4714             TREE_PURPOSE (type) = real_type;
4715         }
4716
4717       /* Check redefinition */
4718       for (already = arg_types; already; already = TREE_CHAIN (already))
4719         if (TREE_PURPOSE (already) == name)
4720           {
4721             parse_error_context
4722               (wfl_name, "Variable `%s' is used more than once in the argument list of method `%s'",
4723                IDENTIFIER_POINTER (name),
4724                IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
4725             break;
4726           }
4727
4728       /* If we've an incomplete argument type, we know there is a location
4729          to patch when the type get resolved, later.  */
4730       jdep = NULL;
4731       if (must_chain)
4732         {
4733           patch_stage = JDEP_METHOD;
4734           type = register_incomplete_type (patch_stage, 
4735                                            type_wfl, wfl_name, type);
4736           jdep = CLASSD_LAST (ctxp->classd_list);
4737           JDEP_MISC (jdep) = id;
4738         }
4739
4740       /* The argument node: a name and a (possibly) incomplete type.  */
4741       arg_node = build_tree_list (name, real_type);
4742       /* Remeber arguments declared final. */
4743       ARG_FINAL_P (arg_node) = ARG_FINAL_P (current);
4744       
4745       if (jdep)
4746         JDEP_GET_PATCH (jdep) = &TREE_VALUE (arg_node);
4747       TREE_CHAIN (arg_node) = arg_types;
4748       arg_types = arg_node;
4749     }
4750   TYPE_ARG_TYPES (meth) = chainon (nreverse (arg_types), end_params_node);
4751   node = build_tree_list (id, meth);
4752   return node;
4753 }
4754
4755 static int
4756 unresolved_type_p (wfl, returned)
4757      tree wfl;
4758      tree *returned;
4759      
4760 {
4761   if (TREE_CODE (wfl) == EXPR_WITH_FILE_LOCATION)
4762     {
4763       if (returned)
4764         {
4765           tree decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (wfl));
4766           if (decl && current_class && (decl == TYPE_NAME (current_class)))
4767             *returned = TREE_TYPE (decl);
4768           else if (GET_CPC_UN () == EXPR_WFL_NODE (wfl))
4769             *returned = TREE_TYPE (GET_CPC ());
4770           else
4771             *returned = NULL_TREE;
4772         }
4773       return 1;
4774     }
4775   if (returned)
4776     *returned = wfl;
4777   return 0;
4778 }
4779
4780 /* From NAME, build a qualified identifier node using the
4781    qualification from the current package definition. */
4782
4783 static tree
4784 parser_qualified_classname (is_static, name)
4785      int is_static;
4786      tree name;
4787 {
4788   tree nested_class_name;
4789
4790   if (!is_static 
4791       && (nested_class_name = maybe_make_nested_class_name (name)))
4792     return nested_class_name;
4793
4794   if (ctxp->package)
4795     return merge_qualified_name (ctxp->package, name);
4796   else 
4797     return name;
4798 }
4799
4800 /* Called once the type a interface extends is resolved. Returns 0 if
4801    everything is OK.  */
4802
4803 static int
4804 parser_check_super_interface (super_decl, this_decl, this_wfl)
4805      tree super_decl, this_decl, this_wfl;
4806 {
4807   tree super_type = TREE_TYPE (super_decl);
4808
4809   /* Has to be an interface */
4810   if (!CLASS_INTERFACE (super_decl))
4811     {
4812       parse_error_context 
4813         (this_wfl, "Can't use %s `%s' to implement/extend %s `%s'",
4814          (TYPE_ARRAY_P (super_type) ? "array" : "class"),
4815          IDENTIFIER_POINTER (DECL_NAME (super_decl)),
4816          (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (this_decl))) ? 
4817           "interface" : "class"),
4818          IDENTIFIER_POINTER (DECL_NAME (this_decl)));
4819       return 1;
4820     }
4821
4822   /* Check scope: same package OK, other package: OK if public */
4823   if (check_pkg_class_access (DECL_NAME (super_decl), lookup_cl (this_decl)))
4824     return 1;
4825
4826   SOURCE_FRONTEND_DEBUG (("Completing interface %s with %s",
4827                           IDENTIFIER_POINTER (DECL_NAME (this_decl)),
4828                           IDENTIFIER_POINTER (DECL_NAME (super_decl))));
4829   return 0;
4830 }
4831
4832 /* Makes sure that SUPER_DECL is suitable to extend THIS_DECL. Returns
4833    0 if everthing is OK.  */
4834
4835 static int
4836 parser_check_super (super_decl, this_decl, wfl)
4837      tree super_decl, this_decl, wfl;
4838 {
4839   tree super_type = TREE_TYPE (super_decl);
4840
4841   /* SUPER should be a CLASS (neither an array nor an interface) */
4842   if (TYPE_ARRAY_P (super_type) || CLASS_INTERFACE (TYPE_NAME (super_type)))
4843     {
4844       parse_error_context 
4845         (wfl, "Class `%s' can't subclass %s `%s'",
4846          IDENTIFIER_POINTER (DECL_NAME (this_decl)),
4847          (CLASS_INTERFACE (TYPE_NAME (super_type)) ? "interface" : "array"),
4848          IDENTIFIER_POINTER (DECL_NAME (super_decl)));
4849       return 1;
4850     }
4851
4852   if (CLASS_FINAL (TYPE_NAME (super_type)))
4853     {
4854       parse_error_context (wfl, "Can't subclass final classes: %s",
4855                            IDENTIFIER_POINTER (DECL_NAME (super_decl)));
4856       return 1;
4857     }
4858
4859   /* Check scope: same package OK, other package: OK if public */
4860   if (check_pkg_class_access (DECL_NAME (super_decl), wfl))
4861     return 1;
4862   
4863   SOURCE_FRONTEND_DEBUG (("Completing class %s with %s",
4864                           IDENTIFIER_POINTER (DECL_NAME (this_decl)),
4865                           IDENTIFIER_POINTER (DECL_NAME (super_decl))));
4866   return 0;
4867 }
4868
4869 /* Create a new dependency list and link it (in a LIFO manner) to the
4870    CTXP list of type dependency list.  */
4871
4872 static void
4873 create_jdep_list (ctxp)
4874      struct parser_ctxt *ctxp;
4875 {
4876   jdeplist *new = (jdeplist *)xmalloc (sizeof (jdeplist));      
4877   new->first = new->last = NULL;
4878   new->next = ctxp->classd_list;
4879   ctxp->classd_list = new;
4880 }
4881
4882 static jdeplist *
4883 reverse_jdep_list (ctxp)
4884      struct parser_ctxt *ctxp;
4885 {
4886   register jdeplist *prev = NULL, *current, *next;
4887   for (current = ctxp->classd_list; current; current = next)
4888     {
4889       next = current->next;
4890       current->next = prev;
4891       prev = current;
4892     }
4893   return prev;
4894 }
4895
4896 /* Create a fake pointer based on the ID stored in
4897    TYPE_NAME. TYPE_NAME can be a WFL or a incomplete type asking to be
4898    registered again. */
4899
4900 static tree
4901 obtain_incomplete_type (type_name)
4902      tree type_name;
4903 {
4904   tree ptr, name;
4905
4906   if (TREE_CODE (type_name) == EXPR_WITH_FILE_LOCATION)
4907     name = EXPR_WFL_NODE (type_name);
4908   else if (INCOMPLETE_TYPE_P (type_name))
4909     name = TYPE_NAME (type_name);
4910   else
4911     fatal ("invalid type name - obtain_incomplete_type");
4912
4913   for (ptr = ctxp->incomplete_class; ptr; ptr = TREE_CHAIN (ptr))
4914     if (TYPE_NAME (ptr) == name)
4915       break;
4916
4917   if (!ptr)
4918     {
4919       push_obstacks (&permanent_obstack, &permanent_obstack);
4920       BUILD_PTR_FROM_NAME (ptr, name);
4921       layout_type (ptr);
4922       pop_obstacks ();
4923       TREE_CHAIN (ptr) = ctxp->incomplete_class;
4924       ctxp->incomplete_class = ptr;
4925     }
4926
4927   return ptr;
4928 }
4929
4930 /* Register a incomplete type whose name is WFL. Reuse PTR if PTR is
4931    non NULL instead of computing a new fake type based on WFL. The new
4932    dependency is inserted in the current type dependency list, in FIFO
4933    manner.  */
4934
4935 static tree
4936 register_incomplete_type (kind, wfl, decl, ptr)
4937      int kind;
4938      tree wfl, decl, ptr;
4939 {
4940   jdep *new = (jdep *)xmalloc (sizeof (jdep));
4941
4942   if (!ptr && kind != JDEP_METHOD_END) /* JDEP_METHOD_END is a mere marker */
4943     ptr = obtain_incomplete_type (wfl);
4944
4945   JDEP_KIND (new) = kind;
4946   JDEP_DECL (new) = decl;
4947   JDEP_SOLV (new) = ptr;
4948   JDEP_WFL (new) = wfl;
4949   JDEP_CHAIN (new) = NULL;
4950   JDEP_MISC (new) = NULL_TREE;
4951   /* For some dependencies, set the enclosing class of the current
4952      class to be the enclosing context */
4953   if ((kind == JDEP_SUPER || kind == JDEP_INTERFACE || kind == JDEP_ANONYMOUS)
4954       && GET_ENCLOSING_CPC ())
4955     JDEP_ENCLOSING (new) = TREE_VALUE (GET_ENCLOSING_CPC ());
4956   else
4957     JDEP_ENCLOSING (new) = GET_CPC ();
4958   JDEP_GET_PATCH (new) = (tree *)NULL;
4959
4960   JDEP_INSERT (ctxp->classd_list, new);
4961
4962   return ptr;
4963 }
4964
4965 void
4966 java_check_circular_reference ()
4967 {
4968   tree current;
4969   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
4970     {
4971       tree type = TREE_TYPE (current);
4972       if (CLASS_INTERFACE (current))
4973         {
4974           /* Check all interfaces this class extends */
4975           tree basetype_vec = TYPE_BINFO_BASETYPES (type);
4976           int n, i;
4977
4978           if (!basetype_vec)
4979             return;
4980           n = TREE_VEC_LENGTH (basetype_vec);
4981           for (i = 0; i < n; i++)
4982             {
4983               tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
4984               if (vec_elt && BINFO_TYPE (vec_elt) != object_type_node 
4985                   && interface_of_p (type, BINFO_TYPE (vec_elt)))
4986                 parse_error_context (lookup_cl (current),
4987                                      "Cyclic interface inheritance");
4988             }
4989         }
4990       else
4991         if (inherits_from_p (CLASSTYPE_SUPER (type), type))
4992           parse_error_context (lookup_cl (current), 
4993                                "Cyclic class inheritance%s",
4994                                (cyclic_inheritance_report ?
4995                                 cyclic_inheritance_report : ""));
4996     }
4997 }
4998
4999 /* Augment the parameter list PARM with parameters crafted to
5000    initialize outer context locals aliases. Through ARTIFICIAL, a
5001    count is kept of the number of crafted parameters. MODE governs
5002    what eventually gets created: something suitable for a function
5003    creation or a function invocation, either the constructor or
5004    $finit$.  */
5005
5006 static tree
5007 build_alias_initializer_parameter_list (mode, class_type, parm, artificial)
5008     int mode;
5009     tree class_type, parm;
5010     int *artificial;
5011 {
5012   tree field;
5013   for (field = TYPE_FIELDS (class_type); field; field = TREE_CHAIN (field))
5014     if (FIELD_LOCAL_ALIAS (field))
5015       {
5016         char *buffer = IDENTIFIER_POINTER (DECL_NAME (field));
5017         tree purpose = NULL_TREE, value = NULL_TREE, name = NULL_TREE;
5018
5019         switch (mode)
5020           {
5021           case AIPL_FUNCTION_DECLARATION:
5022             MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (buffer, &buffer [4]);
5023             purpose = build_wfl_node (get_identifier (buffer));
5024             if (TREE_CODE (TREE_TYPE (field)) == POINTER_TYPE)
5025               value = build_wfl_node (TYPE_NAME (TREE_TYPE (field)));
5026             else
5027               value = TREE_TYPE (field);
5028             break;
5029
5030           case AIPL_FUNCTION_CREATION:
5031             MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (buffer, &buffer [4]);
5032             purpose = get_identifier (buffer);
5033             value = TREE_TYPE (field);
5034             break;
5035
5036           case AIPL_FUNCTION_FINIT_INVOCATION:
5037             MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (buffer, &buffer [4]);
5038             /* Now, this is wrong. purpose should always be the NAME
5039                of something and value its matching value (decl, type,
5040                etc...) FIXME -- but there is a lot to fix. */
5041
5042             /* When invoked for this kind of operation, we already
5043                know whether a field is used or not. */
5044             purpose = TREE_TYPE (field);
5045             value = build_wfl_node (get_identifier (buffer));
5046             break;
5047
5048           case AIPL_FUNCTION_CTOR_INVOCATION:
5049             /* There are two case: the constructor invokation happends
5050                outside the local inner, in which case, locales from the outer
5051                context are directly used.
5052
5053                Otherwise, we fold to using the alias directly. */
5054             if (class_type == current_class)
5055               value = field;
5056             else
5057               {
5058                 name = get_identifier (&buffer[4]);
5059                 value = IDENTIFIER_LOCAL_VALUE (name);
5060               }
5061             break;
5062           }
5063         parm = tree_cons (purpose, value, parm);
5064         if (artificial)
5065           *artificial +=1;
5066       }
5067   return parm;
5068 }
5069
5070 /* Craft a constructor for CLASS_DECL -- what we should do when none
5071    where found. ARGS is non NULL when a special signature must be
5072    enforced. This is the case for anonymous classes.  */
5073
5074 static void
5075 craft_constructor (class_decl, args)
5076      tree class_decl, args;
5077 {
5078   tree class_type = TREE_TYPE (class_decl);
5079   tree parm = NULL_TREE;
5080   int flags = (get_access_flags_from_decl (class_decl) & ACC_PUBLIC ?
5081                ACC_PUBLIC : 0);
5082   int i = 0, artificial = 0;
5083   tree decl, ctor_name;
5084   char buffer [80];
5085   
5086   push_obstacks (&permanent_obstack, &permanent_obstack);
5087
5088   /* The constructor name is <init> unless we're dealing with an
5089      anonymous class, in which case the name will be fixed after having
5090      be expanded. */
5091   if (ANONYMOUS_CLASS_P (class_type))
5092     ctor_name = DECL_NAME (class_decl);
5093   else
5094     ctor_name = init_identifier_node;
5095
5096   /* If we're dealing with an inner class constructor, we hide the
5097      this$<n> decl in the name field of its parameter declaration. */
5098   if (PURE_INNER_CLASS_TYPE_P (class_type))
5099     {
5100       tree type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class_type)));
5101       parm = tree_cons (build_current_thisn (class_type),
5102                         build_pointer_type (type), parm);
5103
5104       /* Some more arguments to be hidden here. The values of the local
5105          variables of the outer context that the inner class needs to see. */
5106       parm = build_alias_initializer_parameter_list (AIPL_FUNCTION_CREATION,
5107                                                      class_type, parm, 
5108                                                      &artificial);
5109     }
5110
5111   /* Then if there are any args to be enforced, enforce them now */
5112   for (; args && args != end_params_node; args = TREE_CHAIN (args))
5113     {
5114       sprintf (buffer, "parm%d", i++);
5115       parm = tree_cons (get_identifier (buffer), TREE_VALUE (args), parm);
5116     }
5117
5118   CRAFTED_PARAM_LIST_FIXUP (parm);
5119   decl = create_artificial_method (class_type, flags, void_type_node, 
5120                                    ctor_name, parm);
5121   fix_method_argument_names (parm, decl);
5122   /* Now, mark the artificial parameters. */
5123   DECL_FUNCTION_NAP (decl) = artificial;
5124
5125   pop_obstacks ();
5126   DECL_CONSTRUCTOR_P (decl) = 1;
5127 }
5128
5129
5130 /* Fix the constructors. This will be called right after circular
5131    references have been checked. It is necessary to fix constructors
5132    early even if no code generation will take place for that class:
5133    some generated constructor might be required by the class whose
5134    compilation triggered this one to be simply loaded.  */
5135
5136 void
5137 java_fix_constructors ()
5138 {
5139   tree current;
5140
5141   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
5142     {
5143       tree class_type = TREE_TYPE (current);
5144       int saw_ctor = 0;
5145       tree decl;
5146
5147       if (CLASS_INTERFACE (TYPE_NAME (class_type)))
5148         continue;
5149
5150       for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
5151         {
5152           if (DECL_CONSTRUCTOR_P (decl))
5153             {
5154               fix_constructors (decl);
5155               saw_ctor = 1;
5156             }
5157         }
5158
5159       /* Anonymous class constructor can't be generated that early. */
5160       if (!saw_ctor && !ANONYMOUS_CLASS_P (class_type))
5161         craft_constructor (current, NULL_TREE);
5162     }
5163 }
5164
5165 /* safe_layout_class just makes sure that we can load a class without
5166    disrupting the current_class, input_file, lineno, etc, information
5167    about the class processed currently.  */
5168
5169 void
5170 safe_layout_class (class)
5171      tree class;
5172 {
5173   tree save_current_class = current_class;
5174   const char *save_input_filename = input_filename;
5175   int save_lineno = lineno;
5176
5177   push_obstacks (&permanent_obstack, &permanent_obstack);
5178
5179   layout_class (class);
5180   pop_obstacks ();
5181
5182   current_class = save_current_class;
5183   input_filename = save_input_filename;
5184   lineno = save_lineno;
5185   CLASS_LOADED_P (class) = 1;
5186 }
5187
5188 static tree
5189 jdep_resolve_class (dep)
5190      jdep *dep;
5191 {
5192   tree decl;
5193
5194   if (JDEP_RESOLVED_P (dep))
5195     decl = JDEP_RESOLVED_DECL (dep);
5196   else
5197     {
5198       decl = resolve_class (JDEP_ENCLOSING (dep), JDEP_TO_RESOLVE (dep),
5199                             JDEP_DECL (dep), JDEP_WFL (dep));
5200       JDEP_RESOLVED (dep, decl);
5201     }
5202     
5203   if (!decl)
5204     complete_class_report_errors (dep);
5205
5206   return decl;
5207 }
5208
5209 /* Complete unsatisfied class declaration and their dependencies */
5210
5211 void
5212 java_complete_class ()
5213 {
5214   tree cclass;
5215   jdeplist *cclassd;
5216   int error_found;
5217   tree type;
5218
5219   push_obstacks (&permanent_obstack, &permanent_obstack);
5220
5221   /* Process imports */
5222   process_imports ();
5223
5224   /* Rever things so we have the right order */
5225   ctxp->class_list = nreverse (ctxp->class_list);
5226   ctxp->classd_list = reverse_jdep_list (ctxp);
5227
5228   for (cclassd = ctxp->classd_list, cclass = ctxp->class_list; 
5229        cclass && cclassd; 
5230        cclass = TREE_CHAIN (cclass), cclassd = CLASSD_CHAIN (cclassd))
5231     {
5232       jdep *dep;
5233       for (dep = CLASSD_FIRST (cclassd); dep; dep = JDEP_CHAIN (dep))
5234         {
5235           tree decl;
5236           if (!(decl = jdep_resolve_class (dep)))
5237             continue;
5238
5239           /* Now it's time to patch */
5240           switch (JDEP_KIND (dep))
5241             {
5242             case JDEP_SUPER:
5243               /* Simply patch super */
5244               if (parser_check_super (decl, JDEP_DECL (dep), JDEP_WFL (dep)))
5245                 continue;
5246               BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO 
5247                 (TREE_TYPE (JDEP_DECL (dep)))), 0)) = TREE_TYPE (decl);
5248               break;
5249
5250             case JDEP_FIELD:
5251               {
5252                 /* We do part of the job done in add_field */
5253                 tree field_decl = JDEP_DECL (dep);
5254                 tree field_type = TREE_TYPE (decl);
5255                 push_obstacks (&permanent_obstack, &permanent_obstack);
5256                 if (TREE_CODE (field_type) == RECORD_TYPE)
5257                   field_type = promote_type (field_type);
5258                 pop_obstacks ();
5259                 TREE_TYPE (field_decl) = field_type;
5260                 DECL_ALIGN (field_decl) = 0;
5261                 DECL_USER_ALIGN (field_decl) = 0;
5262                 layout_decl (field_decl, 0);
5263                 SOURCE_FRONTEND_DEBUG 
5264                   (("Completed field/var decl `%s' with `%s'",
5265                     IDENTIFIER_POINTER (DECL_NAME (field_decl)),
5266                     IDENTIFIER_POINTER (DECL_NAME (decl))));
5267                 break;
5268               }
5269             case JDEP_METHOD:   /* We start patching a method */
5270             case JDEP_METHOD_RETURN:
5271               error_found = 0;
5272               while (1)
5273                 {
5274                   if (decl)
5275                     {
5276                       type = TREE_TYPE(decl);
5277                       if (TREE_CODE (type) == RECORD_TYPE)
5278                         type = promote_type (type);
5279                       JDEP_APPLY_PATCH (dep, type);
5280                       SOURCE_FRONTEND_DEBUG 
5281                         (((JDEP_KIND (dep) == JDEP_METHOD_RETURN ?
5282                            "Completing fct `%s' with ret type `%s'":
5283                            "Completing arg `%s' with type `%s'"),
5284                           IDENTIFIER_POINTER (EXPR_WFL_NODE 
5285                                               (JDEP_DECL_WFL (dep))),
5286                           IDENTIFIER_POINTER (DECL_NAME (decl))));
5287                     }
5288                   else
5289                     error_found = 1;
5290                   dep = JDEP_CHAIN (dep);
5291                   if (JDEP_KIND (dep) == JDEP_METHOD_END)
5292                     break;
5293                   else
5294                     decl = jdep_resolve_class (dep);
5295                 }
5296               if (!error_found)
5297                 {
5298                   tree mdecl = JDEP_DECL (dep), signature;
5299                   push_obstacks (&permanent_obstack, &permanent_obstack);
5300                   /* Recompute and reset the signature, check first that
5301                      all types are now defined. If they're not,
5302                      dont build the signature. */
5303                   if (check_method_types_complete (mdecl))
5304                     {
5305                       signature = build_java_signature (TREE_TYPE (mdecl));
5306                       set_java_signature (TREE_TYPE (mdecl), signature);
5307                     }
5308                   pop_obstacks ();
5309                 }
5310               else
5311                 continue;
5312               break;
5313
5314             case JDEP_INTERFACE:
5315               if (parser_check_super_interface (decl, JDEP_DECL (dep),
5316                                                 JDEP_WFL (dep)))
5317                 continue;
5318               parser_add_interface (JDEP_DECL (dep), decl, JDEP_WFL (dep));
5319               break;
5320
5321             case JDEP_PARM:
5322             case JDEP_VARIABLE:
5323               type = TREE_TYPE(decl);
5324               if (TREE_CODE (type) == RECORD_TYPE)
5325                 type = promote_type (type);
5326               JDEP_APPLY_PATCH (dep, type);
5327               break;
5328
5329             case JDEP_TYPE:
5330               JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
5331               SOURCE_FRONTEND_DEBUG 
5332                 (("Completing a random type dependency on a '%s' node",
5333                   tree_code_name [TREE_CODE (JDEP_DECL (dep))]));
5334               break;
5335
5336             case JDEP_EXCEPTION:
5337               JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
5338               SOURCE_FRONTEND_DEBUG 
5339                 (("Completing `%s' `throws' argument node",
5340                   IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)))));
5341               break;
5342
5343             case JDEP_ANONYMOUS:
5344               patch_anonymous_class (decl, JDEP_DECL (dep), JDEP_WFL (dep));
5345               break;
5346
5347             default:
5348               fatal ("Can't handle patch code %d - java_complete_class",
5349                      JDEP_KIND (dep));
5350             }
5351         }
5352     }
5353   pop_obstacks ();
5354   return;
5355 }
5356
5357 /* Resolve class CLASS_TYPE. Handle the case of trying to resolve an
5358    array.  */
5359
5360 static tree
5361 resolve_class (enclosing, class_type, decl, cl)
5362      tree enclosing, class_type, decl, cl;
5363 {
5364   const char *name = IDENTIFIER_POINTER (TYPE_NAME (class_type));
5365   const char *base = name;
5366   tree resolved_type = TREE_TYPE (class_type);
5367   tree resolved_type_decl;
5368   
5369   if (resolved_type != NULL_TREE)
5370     {
5371       tree resolved_type_decl = TYPE_NAME (resolved_type);
5372       if (resolved_type_decl == NULL_TREE
5373           || TREE_CODE (resolved_type_decl) == IDENTIFIER_NODE)
5374         {
5375           resolved_type_decl = build_decl (TYPE_DECL,
5376                                            TYPE_NAME (class_type),
5377                                            resolved_type);
5378         }
5379       return resolved_type_decl;
5380     }
5381
5382   /* 1- Check to see if we have an array. If true, find what we really
5383      want to resolve  */
5384   while (name[0] == '[')
5385     name++;
5386   if (base != name)
5387     TYPE_NAME (class_type) = get_identifier (name);
5388
5389   /* 2- Resolve the bare type */
5390   if (!(resolved_type_decl = do_resolve_class (enclosing, class_type, 
5391                                                decl, cl)))
5392     return NULL_TREE;
5393   resolved_type = TREE_TYPE (resolved_type_decl);
5394
5395   /* 3- If we have and array, reconstruct the array down to its nesting */
5396   if (base != name)
5397     {
5398       while (base != name)
5399         {
5400           if (TREE_CODE (resolved_type) == RECORD_TYPE)
5401             resolved_type  = promote_type (resolved_type);
5402           resolved_type = build_java_array_type (resolved_type, -1);
5403           CLASS_LOADED_P (resolved_type) = 1;
5404           name--;
5405         }
5406       /* Build a fake decl for this, since this is what is expected to
5407          be returned.  */
5408       resolved_type_decl =
5409         build_decl (TYPE_DECL, TYPE_NAME (resolved_type), resolved_type);
5410       /* Figure how those two things are important for error report. FIXME */
5411       DECL_SOURCE_LINE (resolved_type_decl) = 0;
5412       DECL_SOURCE_FILE (resolved_type_decl) = input_filename;
5413       TYPE_NAME (class_type) = TYPE_NAME (resolved_type);
5414     }
5415   TREE_TYPE (class_type) = resolved_type;
5416   return resolved_type_decl;
5417 }
5418
5419 /* Effectively perform the resolution of class CLASS_TYPE. DECL or CL
5420    are used to report error messages.  */
5421
5422 tree
5423 do_resolve_class (enclosing, class_type, decl, cl)
5424      tree enclosing, class_type, decl, cl;
5425 {
5426   tree new_class_decl;
5427
5428   /* Do not try to replace TYPE_NAME (class_type) by a variable, since
5429      it is changed by find_in_imports{_on_demand} and (but it doesn't
5430      really matter) qualify_and_find */
5431
5432   /* 0- Search in the current class as an inner class */
5433
5434   /* Maybe some code here should be added to load the class or
5435      something, at least if the class isn't an inner class and ended
5436      being loaded from class file. FIXME. */
5437   while (enclosing)
5438     {
5439       tree name;
5440
5441       if ((new_class_decl = find_as_inner_class (enclosing, class_type, cl)))
5442         return new_class_decl;
5443
5444       /* Now go to the upper classes, bail out if necessary. */
5445       enclosing = CLASSTYPE_SUPER (TREE_TYPE (enclosing));
5446       if (!enclosing || enclosing == object_type_node)
5447         break;
5448       
5449       if (TREE_CODE (enclosing) == RECORD_TYPE)
5450         {
5451           enclosing = TYPE_NAME (enclosing);
5452           continue;
5453         }
5454
5455       if (TREE_CODE (enclosing) == IDENTIFIER_NODE)
5456         {
5457           BUILD_PTR_FROM_NAME (name, enclosing);
5458         }
5459       else
5460         name = enclosing;
5461       enclosing = do_resolve_class (NULL, name, NULL, NULL);
5462     }
5463
5464   /* 1- Check for the type in single imports. This will change
5465      TYPE_NAME() if something relevant is found */
5466   find_in_imports (class_type);
5467
5468   /* 2- And check for the type in the current compilation unit */
5469   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
5470     {
5471       if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
5472           !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
5473         load_class (TYPE_NAME (class_type), 0);
5474       return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5475     }
5476
5477   /* 3- Search according to the current package definition */
5478   if (!QUALIFIED_P (TYPE_NAME (class_type)))
5479     {
5480       if ((new_class_decl = qualify_and_find (class_type, ctxp->package,
5481                                              TYPE_NAME (class_type))))
5482         return new_class_decl;
5483     }
5484
5485   /* 4- Check the import on demands. Don't allow bar.baz to be
5486      imported from foo.* */
5487   if (!QUALIFIED_P (TYPE_NAME (class_type)))
5488     if (find_in_imports_on_demand (class_type))
5489       return NULL_TREE;
5490
5491   /* If found in find_in_imports_on_demant, the type has already been
5492      loaded. */
5493   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
5494     return new_class_decl;
5495
5496   /* 5- Try with a name qualified with the package name we've seen so far */
5497   if (!QUALIFIED_P (TYPE_NAME (class_type)))
5498     {
5499       tree package;
5500       for (package = package_list; package; package = TREE_CHAIN (package))
5501         if ((new_class_decl = qualify_and_find (class_type,
5502                                                TREE_PURPOSE (package), 
5503                                                TYPE_NAME (class_type))))
5504           return new_class_decl;
5505     }
5506
5507   /* 5- Check an other compilation unit that bears the name of type */
5508   load_class (TYPE_NAME (class_type), 0);
5509   if (check_pkg_class_access (TYPE_NAME (class_type), 
5510                               (cl ? cl : lookup_cl (decl))))
5511     return NULL_TREE;
5512
5513   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
5514     return new_class_decl;
5515
5516   /* 6- Last call for a resolution */
5517   return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5518 }
5519
5520 static tree
5521 qualify_and_find (class_type, package, name)
5522      tree class_type, package, name;
5523 {
5524   tree new_qualified = merge_qualified_name (package, name);
5525   tree new_class_decl;
5526
5527   if (!IDENTIFIER_CLASS_VALUE (new_qualified))
5528     load_class (new_qualified, 0);
5529   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (new_qualified)))
5530     {
5531       if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
5532           !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
5533         load_class (new_qualified, 0);
5534       TYPE_NAME (class_type) = new_qualified;
5535       return IDENTIFIER_CLASS_VALUE (new_qualified);
5536     }
5537   return NULL_TREE;
5538 }
5539
5540 /* Resolve NAME and lay it out (if not done and if not the current
5541    parsed class). Return a decl node. This function is meant to be
5542    called when type resolution is necessary during the walk pass.  */
5543
5544 static tree
5545 resolve_and_layout (something, cl)
5546      tree something;
5547      tree cl;
5548 {
5549   tree decl;
5550
5551   /* Don't do that on the current class */
5552   if (something == current_class)
5553     return TYPE_NAME (current_class);
5554
5555   /* Don't do anything for void and other primitive types */
5556   if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
5557     return NULL_TREE;
5558
5559   /* Pointer types can be reall pointer types or fake pointers. When
5560      finding a real pointer, recheck for primitive types */
5561   if (TREE_CODE (something) == POINTER_TYPE)
5562     {
5563       if (TREE_TYPE (something))
5564         {
5565           something = TREE_TYPE (something);
5566           if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
5567             return NULL_TREE;
5568         }
5569       else
5570         something = TYPE_NAME (something);
5571     }
5572
5573   /* Don't do anything for arrays of primitive types */
5574   if (TREE_CODE (something) == RECORD_TYPE && TYPE_ARRAY_P (something)
5575       && JPRIMITIVE_TYPE_P (TYPE_ARRAY_ELEMENT (something)))
5576     return NULL_TREE;
5577
5578   /* Something might be a WFL */
5579   if (TREE_CODE (something) == EXPR_WITH_FILE_LOCATION)
5580     something = EXPR_WFL_NODE (something);
5581
5582   /* Otherwise, if something is not and IDENTIFIER_NODE, it can be a a
5583      TYPE_DECL or a real TYPE */
5584   else if (TREE_CODE (something) != IDENTIFIER_NODE)
5585     something = (TREE_CODE (TYPE_NAME (something)) == TYPE_DECL ?
5586             DECL_NAME (TYPE_NAME (something)) : TYPE_NAME (something));
5587
5588   if (!(decl = resolve_no_layout (something, cl)))
5589     return NULL_TREE;
5590
5591   /* Resolve and layout if necessary */
5592   layout_class_methods (TREE_TYPE (decl));
5593   /* Check methods, but only once */
5594   if (CLASS_FROM_SOURCE_P (TREE_TYPE (decl)) 
5595       && !CLASS_LOADED_P (TREE_TYPE (decl)))
5596     CHECK_METHODS (decl);
5597   if (TREE_TYPE (decl) != current_class && !CLASS_LOADED_P (TREE_TYPE (decl)))
5598     safe_layout_class (TREE_TYPE (decl));
5599
5600   return decl;
5601 }
5602
5603 /* Resolve a class, returns its decl but doesn't perform any
5604    layout. The current parsing context is saved and restored */
5605
5606 static tree
5607 resolve_no_layout (name, cl)
5608      tree name, cl;
5609 {
5610   tree ptr, decl;
5611   BUILD_PTR_FROM_NAME (ptr, name);
5612   java_parser_context_save_global ();
5613   decl = resolve_class (TYPE_NAME (current_class), ptr, NULL_TREE, cl);
5614   java_parser_context_restore_global ();
5615   
5616   return decl;
5617 }
5618
5619 /* Called when reporting errors. Skip leader '[' in a complex array
5620    type description that failed to be resolved.  */
5621
5622 static const char *
5623 purify_type_name (name)
5624      const char *name;
5625 {
5626   while (*name && *name == '[')
5627     name++;
5628   return name;
5629 }
5630
5631 /* The type CURRENT refers to can't be found. We print error messages.  */
5632
5633 static void
5634 complete_class_report_errors (dep)
5635      jdep *dep;
5636 {
5637   const char *name;
5638
5639   if (!JDEP_WFL (dep))
5640     return;
5641
5642   name = IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)));
5643   switch (JDEP_KIND (dep))
5644     {
5645     case JDEP_SUPER:
5646       parse_error_context  
5647         (JDEP_WFL (dep), "Superclass `%s' of class `%s' not found",
5648          purify_type_name (name),
5649          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5650       break;
5651     case JDEP_FIELD:
5652       parse_error_context
5653         (JDEP_WFL (dep), "Type `%s' not found in declaration of field `%s'",
5654          purify_type_name (name),
5655          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5656       break;
5657     case JDEP_METHOD:           /* Covers arguments */
5658       parse_error_context
5659         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the argument `%s' of method `%s'",
5660          purify_type_name (name),
5661          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))),
5662          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_MISC (dep))));
5663       break;
5664     case JDEP_METHOD_RETURN:    /* Covers return type */
5665       parse_error_context
5666         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the return type of method `%s'", 
5667          purify_type_name (name),
5668          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))));
5669       break;
5670     case JDEP_INTERFACE:
5671       parse_error_context
5672         (JDEP_WFL (dep), "Superinterface `%s' of %s `%s' not found",
5673          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))),
5674          (CLASS_OR_INTERFACE (JDEP_DECL (dep), "class", "interface")),
5675          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5676       break;
5677     case JDEP_VARIABLE:
5678       parse_error_context
5679         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the local variable `%s'", 
5680          purify_type_name (IDENTIFIER_POINTER 
5681                            (EXPR_WFL_NODE (JDEP_WFL (dep)))),
5682          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5683       break;
5684     case JDEP_EXCEPTION:        /* As specified by `throws' */
5685       parse_error_context 
5686           (JDEP_WFL (dep), "Class `%s' not found in `throws'",
5687          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))));
5688       break;
5689     default:
5690       /* Fix for -Wall. Just break doing nothing. The error will be
5691          caught later */
5692       break;
5693     }
5694 }
5695
5696 /* Return a static string containing the DECL prototype string. If
5697    DECL is a constructor, use the class name instead of the form
5698    <init> */
5699
5700 static const char *
5701 get_printable_method_name (decl)
5702      tree decl;
5703 {
5704   const char *to_return;
5705   tree name = NULL_TREE;
5706
5707   if (DECL_CONSTRUCTOR_P (decl))
5708     {
5709       name = DECL_NAME (decl);
5710       DECL_NAME (decl) = DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)));
5711     }
5712       
5713   to_return = lang_printable_name (decl, 0);
5714   if (DECL_CONSTRUCTOR_P (decl))
5715     DECL_NAME (decl) = name;
5716   
5717   return to_return;
5718 }
5719
5720 /* Reinstall the proper DECL_NAME on METHOD. Return 0 if the method
5721    nevertheless needs to be verfied, 1 otherwise.  */
5722
5723 static int
5724 reset_method_name (method)
5725      tree method;
5726 {
5727   if (!DECL_CLINIT_P (method) && !DECL_FINIT_P (method))
5728     {
5729       /* NAME is just the plain name when Object is being defined */
5730       if (DECL_CONTEXT (method) != object_type_node)
5731         DECL_NAME (method) = (DECL_CONSTRUCTOR_P (method) ? 
5732                               init_identifier_node : GET_METHOD_NAME (method));
5733       return 0;
5734     }
5735   else 
5736     return 1;
5737 }
5738
5739 /* Return the name of METHOD_DECL, when DECL_NAME is a WFL */
5740
5741 tree
5742 java_get_real_method_name (method_decl)
5743      tree method_decl;
5744 {
5745   tree method_name = DECL_NAME (method_decl);
5746   if (DECL_CONSTRUCTOR_P (method_decl))
5747     return init_identifier_node;
5748
5749   /* Explain here why METHOD_DECL doesn't have the DECL_CONSTRUCTUR_P
5750      and still can be a constructor. FIXME */
5751
5752   /* Don't confuse method only bearing the name of their class as
5753      constructors */
5754   else if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (method_decl))
5755            && ctxp
5756            && GET_CPC_UN () == EXPR_WFL_NODE (method_name)
5757            && get_access_flags_from_decl (method_decl) <= ACC_PROTECTED
5758            && TREE_TYPE (TREE_TYPE (method_decl)) == void_type_node)
5759     return init_identifier_node;
5760   else
5761     return EXPR_WFL_NODE (method_name);
5762 }
5763
5764 /* Track method being redefined inside the same class. As a side
5765    effect, set DECL_NAME to an IDENTIFIER (prior entering this
5766    function it's a FWL, so we can track errors more accurately.)  */
5767
5768 static int
5769 check_method_redefinition (class, method)
5770      tree class, method;
5771 {
5772   tree redef, name;
5773   tree cl = DECL_NAME (method);
5774   tree sig = TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (method));
5775   /* decl name of artificial <clinit> and $finit$ doesn't need to be
5776      fixed and checked */
5777
5778   /* Reset the method name before running the check. If it returns 1,
5779      the method doesn't need to be verified with respect to method
5780      redeclaration and we return 0 */
5781   if (reset_method_name (method))
5782     return 0;
5783
5784   name = DECL_NAME (method);
5785   for (redef = TYPE_METHODS (class); redef; redef = TREE_CHAIN (redef))
5786     {
5787       if (redef == method)
5788         break;
5789       if (DECL_NAME (redef) == name 
5790           && sig == TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (redef)))
5791         {
5792           parse_error_context 
5793             (cl, "Duplicate %s declaration `%s'",
5794              (DECL_CONSTRUCTOR_P (redef) ? "constructor" : "method"),
5795              get_printable_method_name (redef));
5796           return 1;
5797         }
5798     }
5799   return 0;
5800 }
5801
5802 static void
5803 check_abstract_method_definitions (do_interface, class_decl, type)
5804      int do_interface;
5805      tree class_decl, type;
5806 {
5807   tree class = TREE_TYPE (class_decl);
5808   tree method, end_type;
5809
5810   end_type = (do_interface ? object_type_node : type);
5811   for (method = TYPE_METHODS (type); method; method = TREE_CHAIN (method))
5812     {
5813       tree other_super, other_method, method_sig, method_name;
5814       int found = 0;
5815       int end_type_reached = 0;
5816       
5817       if (!METHOD_ABSTRACT (method) || METHOD_FINAL (method))
5818         continue;
5819       
5820       /* Now verify that somewhere in between TYPE and CLASS,
5821          abstract method METHOD gets a non abstract definition
5822          that is inherited by CLASS.  */
5823       
5824       method_sig = build_java_signature (TREE_TYPE (method));
5825       method_name = DECL_NAME (method);
5826       if (TREE_CODE (method_name) == EXPR_WITH_FILE_LOCATION)
5827         method_name = EXPR_WFL_NODE (method_name);
5828
5829       other_super = class;
5830       do {
5831         if (other_super == end_type)
5832           end_type_reached = 1;
5833         
5834         /* Method search */
5835         for (other_method = TYPE_METHODS (other_super); other_method;
5836             other_method = TREE_CHAIN (other_method))
5837           {
5838             tree s = build_java_signature (TREE_TYPE (other_method));
5839             tree other_name = DECL_NAME (other_method);
5840             
5841             if (TREE_CODE (other_name) == EXPR_WITH_FILE_LOCATION)
5842               other_name = EXPR_WFL_NODE (other_name);
5843             if (!DECL_CLINIT_P (other_method)
5844                 && !DECL_CONSTRUCTOR_P (other_method)
5845                 && method_name == other_name && method_sig == s)
5846              {
5847                found = 1;
5848                break;
5849              }
5850           }
5851         other_super = CLASSTYPE_SUPER (other_super);
5852       } while (!end_type_reached);
5853  
5854       /* Report that abstract METHOD didn't find an implementation
5855          that CLASS can use. */
5856       if (!found)
5857         {
5858           char *t = xstrdup (lang_printable_name 
5859                             (TREE_TYPE (TREE_TYPE (method)), 0));
5860           tree ccn = DECL_NAME (TYPE_NAME (DECL_CONTEXT (method)));
5861           tree saved_wfl = NULL_TREE;
5862           
5863           if (TREE_CODE (DECL_NAME (method)) == EXPR_WITH_FILE_LOCATION)
5864             {
5865               saved_wfl = DECL_NAME (method);
5866               DECL_NAME (method) = EXPR_WFL_NODE (DECL_NAME (method));
5867             }
5868           
5869           parse_error_context 
5870             (lookup_cl (class_decl),
5871              "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",
5872              IDENTIFIER_POINTER (DECL_NAME (class_decl)),
5873              t, lang_printable_name (method, 0), 
5874              (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))) ? 
5875               "interface" : "class"),
5876              IDENTIFIER_POINTER (ccn),
5877              (CLASS_INTERFACE (class_decl) ? "interface" : "class"),
5878              IDENTIFIER_POINTER (DECL_NAME (class_decl)));
5879           
5880           free (t);
5881           
5882           if (saved_wfl)
5883             DECL_NAME (method) = saved_wfl;
5884         }
5885     }
5886 }
5887
5888 /* Check that CLASS_DECL somehow implements all inherited abstract
5889    methods.  */
5890
5891 static void
5892 java_check_abstract_method_definitions (class_decl)
5893      tree class_decl;
5894 {
5895   tree class = TREE_TYPE (class_decl);
5896   tree super, vector;
5897   int i;
5898
5899   if (CLASS_ABSTRACT (class_decl))
5900     return;
5901
5902   /* Check for inherited types */
5903   super = class;
5904   do {
5905     super = CLASSTYPE_SUPER (super);
5906     check_abstract_method_definitions (0, class_decl, super);
5907   } while (super != object_type_node);
5908
5909   /* Check for implemented interfaces. */
5910   vector = TYPE_BINFO_BASETYPES (class);
5911   for (i = 1; i < TREE_VEC_LENGTH (vector); i++)
5912     {
5913       super = BINFO_TYPE (TREE_VEC_ELT (vector, i));
5914       check_abstract_method_definitions (1, class_decl, super);
5915     }
5916 }
5917
5918 /* Check all the types method DECL uses and return 1 if all of them
5919    are now complete, 0 otherwise. This is used to check whether its
5920    safe to build a method signature or not.  */
5921
5922 static int
5923 check_method_types_complete (decl)
5924      tree decl;
5925 {
5926   tree type = TREE_TYPE (decl);
5927   tree args;
5928
5929   if (!INCOMPLETE_TYPE_P (TREE_TYPE (type)))
5930     return 0;
5931   
5932   args = TYPE_ARG_TYPES (type);
5933   if (TREE_CODE (type) == METHOD_TYPE)
5934     args = TREE_CHAIN (args);
5935   for (; args != end_params_node; args = TREE_CHAIN (args))
5936     if (INCOMPLETE_TYPE_P (TREE_VALUE (args)))
5937       return 0;
5938
5939   return 1;
5940 }
5941
5942 /* Check all the methods of CLASS_DECL. Methods are first completed
5943    then checked according to regular method existance rules.  If no
5944    constructor for CLASS_DECL were encountered, then build its
5945    declaration.  */
5946
5947 static void
5948 java_check_regular_methods (class_decl)
5949      tree class_decl;
5950 {
5951   int saw_constructor = ANONYMOUS_CLASS_P (TREE_TYPE (class_decl));
5952   tree method;
5953   tree class = CLASS_TO_HANDLE_TYPE (TREE_TYPE (class_decl));
5954   tree saved_found_wfl = NULL_TREE, found = NULL_TREE;
5955   tree mthrows;
5956
5957   /* It is not necessary to check methods defined in java.lang.Object */
5958   if (class == object_type_node)
5959     return;
5960
5961   if (!TYPE_NVIRTUALS (class))
5962     TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
5963
5964   /* Should take interfaces into account. FIXME */
5965   for (method = TYPE_METHODS (class); method; method = TREE_CHAIN (method))
5966     {
5967       tree sig;
5968       tree method_wfl = DECL_NAME (method);
5969       int aflags;
5970
5971       /* If we previously found something and its name was saved,
5972          reinstall it now */
5973       if (found && saved_found_wfl)
5974         {
5975           DECL_NAME (found) = saved_found_wfl;
5976           saved_found_wfl = NULL_TREE;
5977         }
5978
5979       /* Check for redefinitions */
5980       if (check_method_redefinition (class, method))
5981         continue;
5982
5983       /* If we see one constructor a mark so we don't generate the
5984          default one. Also skip other verifications: constructors
5985          can't be inherited hence hiden or overriden */
5986      if (DECL_CONSTRUCTOR_P (method))
5987        {
5988          saw_constructor = 1;
5989          continue;
5990        }
5991
5992       /* We verify things thrown by the method. They must inherits from
5993          java.lang.Throwable */
5994       for (mthrows = DECL_FUNCTION_THROWS (method);
5995            mthrows; mthrows = TREE_CHAIN (mthrows))
5996         {
5997           if (!inherits_from_p (TREE_VALUE (mthrows), throwable_type_node))
5998             parse_error_context 
5999               (TREE_PURPOSE (mthrows), "Class `%s' in `throws' clause must be a subclass of class `java.lang.Throwable'",
6000                IDENTIFIER_POINTER 
6001                  (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))));
6002         }
6003
6004       sig = build_java_argument_signature (TREE_TYPE (method));
6005       found = lookup_argument_method2 (class, DECL_NAME (method), sig);
6006
6007       /* Inner class can't declare static methods */
6008       if (METHOD_STATIC (method) && !TOPLEVEL_CLASS_DECL_P (class_decl))
6009         {
6010           char *t = xstrdup (lang_printable_name (class, 0));
6011           parse_error_context 
6012             (method_wfl, "Method `%s' can't be static in inner class `%s'. Only members of interfaces and top-level classes can be static",
6013              lang_printable_name (method, 0), t);
6014           free (t);
6015         }
6016
6017       /* Nothing overrides or it's a private method. */
6018       if (!found)
6019         continue;
6020       if (METHOD_PRIVATE (found))
6021         {
6022           found = NULL_TREE;
6023           continue;
6024         }
6025
6026       /* If found wasn't verified, it's DECL_NAME won't be set properly. 
6027          We set it temporarily for the sake of the error report. */
6028       saved_found_wfl = DECL_NAME (found);
6029       reset_method_name (found);
6030
6031       /* If `found' is declared in an interface, make sure the
6032          modifier matches. */
6033       if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (found))) 
6034           && clinit_identifier_node != DECL_NAME (found)
6035           && !METHOD_PUBLIC (method))
6036         {
6037           tree found_decl = TYPE_NAME (DECL_CONTEXT (found));
6038           parse_error_context (method_wfl, "Class `%s' must override `%s' with a public method in order to implement interface `%s'",
6039                                IDENTIFIER_POINTER (DECL_NAME (class_decl)),
6040                                lang_printable_name (method, 0),
6041                                IDENTIFIER_POINTER (DECL_NAME (found_decl)));
6042         }
6043
6044       /* Can't override a method with the same name and different return
6045          types. */
6046       if (TREE_TYPE (TREE_TYPE (found)) != TREE_TYPE (TREE_TYPE (method)))
6047         {
6048           char *t = xstrdup 
6049             (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
6050           parse_error_context 
6051             (method_wfl,
6052              "Method `%s' was defined with return type `%s' in class `%s'", 
6053              lang_printable_name (found, 0), t,
6054              IDENTIFIER_POINTER 
6055                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6056           free (t);
6057         }
6058
6059       aflags = get_access_flags_from_decl (found);
6060       /* If the method has default, access in an other package, then
6061          issue a warning that the current method doesn't override the
6062          one that was found elsewhere. Do not issue this warning when
6063          the match was found in java.lang.Object.  */
6064       if (DECL_CONTEXT (found) != object_type_node
6065           && ((aflags & ACC_VISIBILITY) == 0)
6066           && !class_in_current_package (DECL_CONTEXT (found))
6067           && !DECL_CLINIT_P (found)
6068           && flag_not_overriding)
6069         {
6070           parse_warning_context 
6071             (method_wfl, "Method `%s' in class `%s' does not override the corresponding method in class `%s', which is private to a different package",
6072              lang_printable_name (found, 0),
6073              IDENTIFIER_POINTER (DECL_NAME (class_decl)),
6074              IDENTIFIER_POINTER (DECL_NAME 
6075                                  (TYPE_NAME (DECL_CONTEXT (found)))));
6076           continue;
6077         }
6078
6079       /* Can't override final. Can't override static. */
6080       if (METHOD_FINAL (found) || METHOD_STATIC (found))
6081         {
6082           /* Static *can* override static */
6083           if (METHOD_STATIC (found) && METHOD_STATIC (method))
6084             continue;
6085           parse_error_context 
6086             (method_wfl,
6087              "%s methods can't be overriden. Method `%s' is %s in class `%s'",
6088              (METHOD_FINAL (found) ? "Final" : "Static"),
6089              lang_printable_name (found, 0),
6090              (METHOD_FINAL (found) ? "final" : "static"),
6091              IDENTIFIER_POINTER
6092                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6093           continue;
6094         }
6095
6096       /* Static method can't override instance method. */
6097       if (METHOD_STATIC (method))
6098         {
6099           parse_error_context 
6100             (method_wfl,
6101              "Instance methods can't be overriden by a static method. Method `%s' is an instance method in class `%s'",
6102              lang_printable_name (found, 0),
6103              IDENTIFIER_POINTER
6104                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6105           continue;
6106         }
6107
6108       /* - Overriding/hiding public must be public
6109          - Overriding/hiding protected must be protected or public
6110          - If the overriden or hidden method has default (package)
6111            access, then the overriding or hiding method must not be
6112            private; otherwise, a compile-time error occurs.  If
6113            `found' belongs to an interface, things have been already
6114            taken care of.  */
6115       if (!CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (found)))
6116           && ((METHOD_PUBLIC (found) && !METHOD_PUBLIC (method))
6117               || (METHOD_PROTECTED (found) 
6118                   && !(METHOD_PUBLIC (method) || METHOD_PROTECTED (method)))
6119               || (!(aflags & (ACC_PUBLIC | ACC_PRIVATE | ACC_STATIC))
6120                   && METHOD_PRIVATE (method))))
6121         {
6122           parse_error_context 
6123             (method_wfl,
6124              "Methods can't be overridden to be more private. Method `%s' is not %s in class `%s'", lang_printable_name (method, 0),
6125              (METHOD_PUBLIC (method) ? "public" : 
6126               (METHOD_PRIVATE (method) ? "private" : "protected")),
6127              IDENTIFIER_POINTER (DECL_NAME 
6128                                  (TYPE_NAME (DECL_CONTEXT (found)))));
6129           continue;
6130         }
6131
6132       /* Overriding methods must have compatible `throws' clauses on checked
6133          exceptions, if any */
6134       check_throws_clauses (method, method_wfl, found);
6135
6136       /* Inheriting multiple methods with the same signature. FIXME */
6137     }
6138   
6139   /* Don't forget eventual pending found and saved_found_wfl. Take
6140      into account that we might have exited because we saw an
6141      artificial method as the last entry. */
6142
6143   if (found && !DECL_ARTIFICIAL (found) && saved_found_wfl)
6144     DECL_NAME (found) = saved_found_wfl;
6145
6146   if (!TYPE_NVIRTUALS (class))
6147     TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
6148
6149   /* Search for inherited abstract method not yet implemented in this
6150      class.  */
6151   java_check_abstract_method_definitions (class_decl);
6152
6153   if (!saw_constructor)
6154     fatal ("No constructor found");
6155 }
6156
6157 /* Return a non zero value if the `throws' clause of METHOD (if any)
6158    is incompatible with the `throws' clause of FOUND (if any).  */
6159
6160 static void
6161 check_throws_clauses (method, method_wfl, found)
6162      tree method, method_wfl, found;
6163 {
6164   tree mthrows, fthrows;
6165
6166   /* Can't check these things with class loaded from bytecode. FIXME */
6167   if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (found)))
6168     return;
6169
6170   for (mthrows = DECL_FUNCTION_THROWS (method);
6171        mthrows; mthrows = TREE_CHAIN (mthrows))
6172     {
6173       /* We don't verify unchecked expressions */
6174       if (IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (mthrows)))
6175         continue;
6176       /* Checked expression must be compatible */
6177       for (fthrows = DECL_FUNCTION_THROWS (found); 
6178            fthrows; fthrows = TREE_CHAIN (fthrows))
6179         if (inherits_from_p (TREE_VALUE (mthrows), TREE_VALUE (fthrows)))
6180           break;
6181       if (!fthrows)
6182         {
6183           parse_error_context 
6184             (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'",
6185              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))),
6186              lang_printable_name (found, 0),
6187              IDENTIFIER_POINTER 
6188                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6189         }
6190     }
6191 }
6192
6193 /* Check abstract method of interface INTERFACE */
6194
6195 static void
6196 java_check_abstract_methods (interface_decl)
6197      tree interface_decl;
6198 {
6199   int i, n;
6200   tree method, basetype_vec, found;
6201   tree interface = TREE_TYPE (interface_decl);
6202
6203   for (method = TYPE_METHODS (interface); method; method = TREE_CHAIN (method))
6204     {
6205       tree method_wfl = DECL_NAME (method);
6206
6207       /* 2- Check for double definition inside the defining interface */
6208       if (check_method_redefinition (interface, method))
6209         continue;
6210
6211       /* 3- Overriding is OK as far as we preserve the return type and
6212          the thrown exceptions (FIXME) */
6213       found = lookup_java_interface_method2 (interface, method);
6214       if (found)
6215         {
6216           char *t;
6217           tree saved_found_wfl = DECL_NAME (found);
6218           reset_method_name (found);
6219           t = xstrdup (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
6220           parse_error_context 
6221             (method_wfl,
6222              "Method `%s' was defined with return type `%s' in class `%s'",
6223              lang_printable_name (found, 0), t,
6224              IDENTIFIER_POINTER 
6225                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6226           free (t);
6227           DECL_NAME (found) = saved_found_wfl;
6228           continue;
6229         }
6230     }
6231
6232   /* 4- Inherited methods can't differ by their returned types */
6233   if (!(basetype_vec = TYPE_BINFO_BASETYPES (interface)))
6234     return;
6235   n = TREE_VEC_LENGTH (basetype_vec);
6236   for (i = 0; i < n; i++)
6237     {
6238       tree sub_interface_method, sub_interface;
6239       tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
6240       if (!vec_elt)
6241         continue;
6242       sub_interface = BINFO_TYPE (vec_elt);
6243       for (sub_interface_method = TYPE_METHODS (sub_interface); 
6244            sub_interface_method;
6245            sub_interface_method = TREE_CHAIN (sub_interface_method))
6246         {
6247           found = lookup_java_interface_method2 (interface, 
6248                                                  sub_interface_method);
6249           if (found && (found != sub_interface_method))
6250             {
6251               tree saved_found_wfl = DECL_NAME (found);
6252               reset_method_name (found);
6253               parse_error_context 
6254                 (lookup_cl (sub_interface_method),
6255                  "Interface `%s' inherits method `%s' from interface `%s'. This method is redefined with a different return type in interface `%s'",
6256                  IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (interface))),
6257                  lang_printable_name (found, 0),
6258                  IDENTIFIER_POINTER 
6259                    (DECL_NAME (TYPE_NAME 
6260                                (DECL_CONTEXT (sub_interface_method)))),
6261                  IDENTIFIER_POINTER 
6262                    (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6263               DECL_NAME (found) = saved_found_wfl;
6264             }
6265         }
6266     }
6267 }
6268
6269 /* Lookup methods in interfaces using their name and partial
6270    signature. Return a matching method only if their types differ.  */
6271
6272 static tree
6273 lookup_java_interface_method2 (class, method_decl)
6274      tree class, method_decl;
6275 {
6276   int i, n;
6277   tree basetype_vec = TYPE_BINFO_BASETYPES (class), to_return;
6278
6279   if (!basetype_vec)
6280     return NULL_TREE;
6281
6282   n = TREE_VEC_LENGTH (basetype_vec);
6283   for (i = 0; i < n; i++)
6284     {
6285       tree vec_elt = TREE_VEC_ELT (basetype_vec, i), to_return;
6286       if ((BINFO_TYPE (vec_elt) != object_type_node)
6287           && (to_return = 
6288               lookup_java_method2 (BINFO_TYPE (vec_elt), method_decl, 1)))
6289         return to_return;
6290     }
6291   for (i = 0; i < n; i++)
6292     {
6293       to_return = lookup_java_interface_method2 
6294         (BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i)), method_decl);
6295       if (to_return)
6296         return to_return;
6297     }
6298
6299   return NULL_TREE;
6300 }
6301
6302 /* Lookup method using their name and partial signature. Return a
6303    matching method only if their types differ.  */
6304
6305 static tree
6306 lookup_java_method2 (clas, method_decl, do_interface)
6307      tree clas, method_decl;
6308      int do_interface;
6309 {
6310   tree method, method_signature, method_name, method_type, name;
6311
6312   method_signature = build_java_argument_signature (TREE_TYPE (method_decl));
6313   name = DECL_NAME (method_decl);
6314   method_name = (TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ? 
6315                  EXPR_WFL_NODE (name) : name);
6316   method_type = TREE_TYPE (TREE_TYPE (method_decl));
6317
6318   while (clas != NULL_TREE)
6319     {
6320       for (method = TYPE_METHODS (clas);
6321            method != NULL_TREE;  method = TREE_CHAIN (method))
6322         {
6323           tree method_sig = build_java_argument_signature (TREE_TYPE (method));
6324           tree name = DECL_NAME (method);
6325           if ((TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
6326                EXPR_WFL_NODE (name) : name) == method_name
6327               && method_sig == method_signature 
6328               && TREE_TYPE (TREE_TYPE (method)) != method_type)
6329             return method;
6330         }
6331       clas = (do_interface ? NULL_TREE : CLASSTYPE_SUPER (clas));
6332     }
6333   return NULL_TREE;
6334 }
6335
6336 /* Return the line that matches DECL line number, and try its best to
6337    position the column number. Used during error reports.  */
6338
6339 static tree
6340 lookup_cl (decl)
6341      tree decl;
6342 {
6343   static tree cl = NULL_TREE;
6344   char *line, *found;
6345   
6346   if (!decl)
6347     return NULL_TREE;
6348
6349   if (cl == NULL_TREE)
6350     cl = build_expr_wfl (NULL_TREE, NULL, 0, 0);
6351
6352   EXPR_WFL_FILENAME_NODE (cl) = get_identifier (DECL_SOURCE_FILE (decl));
6353   EXPR_WFL_SET_LINECOL (cl, DECL_SOURCE_LINE_FIRST (decl), -1);
6354
6355   line = java_get_line_col (IDENTIFIER_POINTER (EXPR_WFL_FILENAME_NODE (cl)),
6356                             EXPR_WFL_LINENO (cl), EXPR_WFL_COLNO (cl));
6357
6358   found = strstr ((const char *)line, 
6359                   (const char *)IDENTIFIER_POINTER (DECL_NAME (decl)));
6360   if (found)
6361     EXPR_WFL_SET_LINECOL (cl, EXPR_WFL_LINENO (cl), found - line);
6362
6363   return cl;
6364 }
6365
6366 /* Look for a simple name in the single-type import list */
6367
6368 static tree
6369 find_name_in_single_imports (name)
6370      tree name;
6371 {
6372   tree node;
6373
6374   for (node = ctxp->import_list; node; node = TREE_CHAIN (node))
6375     if (TREE_VALUE (node) == name)
6376       return (EXPR_WFL_NODE (TREE_PURPOSE (node)));
6377
6378   return NULL_TREE;
6379 }
6380
6381 /* Process all single-type import. */
6382
6383 static int
6384 process_imports ()
6385 {
6386   tree import;
6387   int error_found;
6388
6389   for (import = ctxp->import_list; import; import = TREE_CHAIN (import))
6390     {
6391       tree to_be_found = EXPR_WFL_NODE (TREE_PURPOSE (import));
6392
6393       /* Don't load twice something already defined. */
6394       if (IDENTIFIER_CLASS_VALUE (to_be_found))
6395         continue;
6396       QUALIFIED_P (to_be_found) = 1;
6397       load_class (to_be_found, 0);
6398       error_found =
6399         check_pkg_class_access (to_be_found, TREE_PURPOSE (import));
6400       if (!IDENTIFIER_CLASS_VALUE (to_be_found))
6401         {
6402           parse_error_context (TREE_PURPOSE (import),
6403                                "Class or interface `%s' not found in import",
6404                                IDENTIFIER_POINTER (to_be_found));
6405           return 1;
6406         }
6407       if (error_found)
6408         return 1;
6409     }
6410   return 0;
6411 }
6412
6413 /* Possibly find and mark a class imported by a single-type import
6414    statement.  */
6415
6416 static void
6417 find_in_imports (class_type)
6418      tree class_type;
6419 {
6420   tree import;
6421
6422   for (import = ctxp->import_list; import; import = TREE_CHAIN (import))
6423     if (TREE_VALUE (import) == TYPE_NAME (class_type))
6424       {
6425         TYPE_NAME (class_type) = EXPR_WFL_NODE (TREE_PURPOSE (import));
6426         QUALIFIED_P (TYPE_NAME (class_type)) = 1;
6427       }
6428 }
6429
6430 static int
6431 note_possible_classname (name, len)
6432      const char *name;
6433      int len;
6434 {
6435   tree node;
6436   if (len > 5 && strncmp (&name [len-5], ".java", 5) == 0)
6437     len = len - 5;
6438   else if (len > 6 && strncmp (&name [len-6], ".class", 6) == 0)
6439     len = len - 6;
6440   else
6441     return 0;
6442   node = ident_subst (name, len, "", '/', '.', "");
6443   IS_A_CLASSFILE_NAME (node) = 1; /* Or soon to be */
6444   QUALIFIED_P (node) = strchr (name, '/') ? 1 : 0;
6445   return 1;
6446 }
6447
6448 /* Read a import directory, gathering potential match for further type
6449    references. Indifferently reads a filesystem or a ZIP archive
6450    directory.  */
6451
6452 static void
6453 read_import_dir (wfl)
6454      tree wfl;
6455 {
6456   tree package_id = EXPR_WFL_NODE (wfl);
6457   const char *package_name = IDENTIFIER_POINTER (package_id);
6458   int package_length = IDENTIFIER_LENGTH (package_id);
6459   DIR *dirp = NULL;
6460   JCF *saved_jcf = current_jcf;
6461
6462   int found = 0;
6463   int k;
6464   void *entry;
6465   struct buffer filename[1];
6466
6467
6468   if (IS_AN_IMPORT_ON_DEMAND_P (package_id))
6469     return;
6470   IS_AN_IMPORT_ON_DEMAND_P (package_id) = 1;
6471
6472   BUFFER_INIT (filename);
6473   buffer_grow (filename, package_length + 100);
6474
6475   for (entry = jcf_path_start (); entry != NULL; entry = jcf_path_next (entry))
6476     {
6477       const char *entry_name = jcf_path_name (entry);
6478       int entry_length = strlen (entry_name);
6479       if (jcf_path_is_zipfile (entry))
6480         {
6481           ZipFile *zipf;
6482           buffer_grow (filename, entry_length);
6483           memcpy (filename->data, entry_name, entry_length - 1);
6484           filename->data[entry_length-1] = '\0';
6485           zipf = opendir_in_zip (filename->data, jcf_path_is_system (entry));
6486           if (zipf == NULL)
6487             error ("malformed .zip archive in CLASSPATH: %s", entry_name);
6488           else
6489             {
6490               ZipDirectory *zipd = (ZipDirectory *) zipf->central_directory;
6491               BUFFER_RESET (filename);
6492               for (k = 0; k < package_length; k++)
6493                 {
6494                   char ch = package_name[k];
6495                   *filename->ptr++ = ch == '.' ? '/' : ch;
6496                 }
6497               *filename->ptr++ = '/';
6498
6499               for (k = 0; k < zipf->count;  k++, zipd = ZIPDIR_NEXT (zipd))
6500                 {
6501                   const char *current_entry = ZIPDIR_FILENAME (zipd);
6502                   int current_entry_len = zipd->filename_length;
6503
6504                   if (current_entry_len >= BUFFER_LENGTH (filename)
6505                       && strncmp (filename->data, current_entry, 
6506                                   BUFFER_LENGTH (filename)) != 0)
6507                     continue;
6508                   found |= note_possible_classname (current_entry,
6509                                                     current_entry_len);
6510                 }
6511             }
6512         }
6513       else
6514         {
6515           BUFFER_RESET (filename);
6516           buffer_grow (filename, entry_length + package_length + 4);
6517           strcpy (filename->data, entry_name);
6518           filename->ptr = filename->data + entry_length;
6519           for (k = 0; k < package_length; k++)
6520             {
6521               char ch = package_name[k];
6522               *filename->ptr++ = ch == '.' ? '/' : ch;
6523             }
6524           *filename->ptr = '\0';
6525
6526           dirp = opendir (filename->data);
6527           if (dirp == NULL)
6528             continue;
6529           *filename->ptr++ = '/';
6530           for (;;)
6531             {
6532               int len; 
6533               const char *d_name;
6534               struct dirent *direntp = readdir (dirp);
6535               if (!direntp)
6536                 break;
6537               d_name = direntp->d_name;
6538               len = strlen (direntp->d_name);
6539               buffer_grow (filename, len+1);
6540               strcpy (filename->ptr, d_name);
6541               found |= note_possible_classname (filename->data + entry_length,
6542                                                 package_length+len+1);
6543             }
6544           if (dirp)
6545             closedir (dirp);
6546         }
6547     }
6548
6549   free (filename->data);
6550
6551   /* Here we should have a unified way of retrieving an entry, to be
6552      indexed. */
6553   if (!found)
6554     {
6555       static int first = 1;
6556       if (first)
6557         {
6558           error ("Can't find default package `%s'. Check the CLASSPATH environment variable and the access to the archives.", package_name);
6559           java_error_count++;
6560           first = 0;
6561         }
6562       else
6563         parse_error_context (wfl, "Package `%s' not found in import",
6564                              package_name);
6565       current_jcf = saved_jcf;
6566       return;
6567     }
6568   current_jcf = saved_jcf;
6569 }
6570
6571 /* Possibly find a type in the import on demands specified
6572    types. Returns 1 if an error occured, 0 otherwise. Run throught the
6573    entire list, to detected potential double definitions.  */
6574                  
6575 static int
6576 find_in_imports_on_demand (class_type)
6577      tree class_type;
6578 {
6579   tree node, import, node_to_use = NULL_TREE;
6580   int seen_once = -1;
6581   tree cl = NULL_TREE;
6582
6583   for (import = ctxp->import_demand_list; import; import = TREE_CHAIN (import))
6584     {
6585       const char *id_name;
6586       obstack_grow (&temporary_obstack, 
6587                     IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))),
6588                     IDENTIFIER_LENGTH (EXPR_WFL_NODE (TREE_PURPOSE (import))));
6589       obstack_1grow (&temporary_obstack, '.');
6590       obstack_grow0 (&temporary_obstack, 
6591                      IDENTIFIER_POINTER (TYPE_NAME (class_type)),
6592                      IDENTIFIER_LENGTH (TYPE_NAME (class_type)));
6593       id_name = obstack_finish (&temporary_obstack);
6594               
6595       node = maybe_get_identifier (id_name);
6596       if (node && IS_A_CLASSFILE_NAME (node))
6597         {
6598           if (seen_once < 0)
6599             {
6600               cl = TREE_PURPOSE (import);
6601               seen_once = 1;
6602               node_to_use = node;
6603             }
6604           else
6605             {
6606               seen_once++;
6607               parse_error_context 
6608                 (import, "Type `%s' also potentially defined in package `%s'",
6609                  IDENTIFIER_POINTER (TYPE_NAME (class_type)),
6610                  IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))));
6611             }
6612         }
6613     }
6614
6615   if (seen_once == 1)
6616     {
6617       /* Setup lineno so that it refers to the line of the import (in
6618          case we parse a class file and encounter errors */
6619       tree decl;
6620       int saved_lineno = lineno;
6621       lineno = EXPR_WFL_LINENO (cl);
6622       TYPE_NAME (class_type) = node_to_use;
6623       QUALIFIED_P (TYPE_NAME (class_type)) = 1;
6624       decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
6625       /* If there is no DECL set for the class or if the class isn't
6626          loaded and not seen in source yet, the load */
6627       if (!decl || (!CLASS_LOADED_P (TREE_TYPE (decl))
6628                     && !CLASS_FROM_SOURCE_P (TREE_TYPE (decl))))
6629         load_class (node_to_use, 0);
6630       lineno = saved_lineno;
6631       return check_pkg_class_access (TYPE_NAME (class_type), cl);
6632     }
6633   else
6634     return (seen_once < 0 ? 0 : seen_once); /* It's ok not to have found */
6635 }
6636
6637 /* Add package NAME to the list of package encountered so far. To
6638    speed up class lookup in do_resolve_class, we make sure a
6639    particular package is added only once.  */
6640
6641 static void
6642 register_package (name)
6643      tree name;
6644 {
6645   static struct hash_table _pht, *pht = NULL;
6646
6647   if (!pht)
6648     {
6649       hash_table_init (&_pht, hash_newfunc, 
6650                        java_hash_hash_tree_node, java_hash_compare_tree_node);
6651       pht = &_pht;
6652     }
6653   
6654   if (!hash_lookup (pht, (const hash_table_key) name, FALSE, NULL))
6655     {
6656       package_list = chainon (package_list, build_tree_list (name, NULL));
6657       hash_lookup (pht, (const hash_table_key) name, TRUE, NULL);
6658     }
6659 }
6660
6661 static tree
6662 resolve_package (pkg, next)
6663      tree pkg, *next;
6664 {
6665   tree current, acc;
6666   tree type_name = NULL_TREE;
6667   const char *name = IDENTIFIER_POINTER (EXPR_WFL_NODE (pkg));
6668
6669   /* The trick is to determine when the package name stops and were
6670      the name of something contained in the package starts. Then we
6671      return a fully qualified name of what we want to get. */
6672
6673   /* Do a quick search on well known package names */
6674   if (!strncmp (name, "java.lang.reflect", 17))
6675     {
6676       *next = 
6677         TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg))));
6678       type_name = lookup_package_type (name, 17);
6679     }
6680   else if (!strncmp (name, "java.lang", 9))
6681     {
6682       *next = TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg)));
6683       type_name = lookup_package_type (name, 9);
6684     }
6685
6686   /* If we found something here, return */
6687   if (type_name)
6688     return type_name; 
6689
6690   *next = EXPR_WFL_QUALIFICATION (pkg);
6691
6692   /* Try the current package. */
6693   if (ctxp->package && !strncmp (name, IDENTIFIER_POINTER (ctxp->package),  
6694                                  IDENTIFIER_LENGTH (ctxp->package)))
6695     {
6696       type_name = 
6697         lookup_package_type_and_set_next (name, 
6698                                           IDENTIFIER_LENGTH (ctxp->package), 
6699                                           next );
6700       if (type_name)
6701         return type_name;
6702     }
6703
6704   /* Search in imported package */
6705   for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
6706     {
6707       tree current_pkg_name = EXPR_WFL_NODE (TREE_PURPOSE (current));
6708       int len = IDENTIFIER_LENGTH (current_pkg_name);
6709       if (!strncmp (name, IDENTIFIER_POINTER (current_pkg_name), len))
6710         {
6711           tree left, dummy;
6712           
6713           breakdown_qualified (&left, &dummy, current_pkg_name);
6714           len = IDENTIFIER_LENGTH (left);
6715           type_name = lookup_package_type_and_set_next (name, len, next);
6716           if (type_name)
6717             break;
6718         }
6719     }
6720
6721   /* Try to progressively construct a type name */
6722   if (TREE_CODE (pkg) == EXPR_WITH_FILE_LOCATION)
6723     for (acc = NULL_TREE, current = EXPR_WFL_QUALIFICATION (pkg); 
6724          current; current = TREE_CHAIN (current))
6725       {
6726         acc = merge_qualified_name (acc, EXPR_WFL_NODE (QUAL_WFL (current)));
6727         if ((type_name = resolve_no_layout (acc, NULL_TREE)))
6728           {
6729             type_name = acc;
6730             /* resolve_package should be used in a loop, hence we
6731                point at this one to naturally process the next one at
6732                the next iteration. */
6733             *next = current;
6734             break;
6735           }
6736       }
6737   return type_name;
6738 }
6739
6740 static tree
6741 lookup_package_type_and_set_next (name, len, next)
6742      const char *name;
6743      int len;
6744      tree *next;
6745 {
6746   const char *ptr;
6747   tree type_name = lookup_package_type (name, len);
6748
6749   if (!type_name)
6750     return NULL;
6751   
6752   ptr = IDENTIFIER_POINTER (type_name);
6753   while (ptr && (ptr = strchr (ptr, '.'))) 
6754     {
6755       *next = TREE_CHAIN (*next);
6756       ptr++;
6757     }
6758   return type_name;
6759 }
6760
6761 static tree
6762 lookup_package_type (name, from)
6763      const char *name;
6764      int from;
6765 {
6766   char subname [128];
6767   const char *sub = &name[from+1];
6768   while (*sub != '.' && *sub)
6769     sub++;
6770   strncpy (subname, name, sub-name);
6771   subname [sub-name] = '\0';
6772   return get_identifier (subname);
6773 }
6774
6775 /* Check that CLASS_NAME refers to a PUBLIC class. Return 0 if no
6776    access violations were found, 1 otherwise.  */
6777
6778 static int
6779 check_pkg_class_access (class_name, cl)
6780      tree class_name;
6781      tree cl;
6782 {
6783   tree type;
6784
6785   if (!QUALIFIED_P (class_name) || !IDENTIFIER_CLASS_VALUE (class_name))
6786     return 0;
6787
6788   if (!(type = TREE_TYPE (IDENTIFIER_CLASS_VALUE (class_name))))
6789     return 0;
6790
6791   if (!CLASS_PUBLIC (TYPE_NAME (type)))
6792     {
6793       /* Access to a private class within the same package is
6794          allowed. */
6795       tree l, r;
6796       breakdown_qualified (&l, &r, class_name);
6797       if (l == ctxp->package)
6798         return 0;
6799
6800       parse_error_context 
6801         (cl, "Can't access %s `%s'. Only public classes and interfaces in other packages can be accessed",
6802          (CLASS_INTERFACE (TYPE_NAME (type)) ? "interface" : "class"),
6803          IDENTIFIER_POINTER (class_name));
6804       return 1;
6805     }
6806   return 0;
6807 }
6808
6809 /* Local variable declaration. */
6810
6811 static void
6812 declare_local_variables (modifier, type, vlist)
6813      int modifier;
6814      tree type;
6815      tree vlist;
6816 {
6817   tree decl, current, saved_type;
6818   tree type_wfl = NULL_TREE;
6819   int must_chain = 0;
6820   int final_p = 0;
6821
6822   /* Push a new block if statements were seen between the last time we
6823      pushed a block and now. Keep a cound of block to close */
6824   if (BLOCK_EXPR_BODY (GET_CURRENT_BLOCK (current_function_decl)))
6825     {
6826       tree body = GET_CURRENT_BLOCK (current_function_decl);
6827       tree b = enter_block ();
6828       BLOCK_EXPR_ORIGIN (b) = body;
6829     }
6830
6831   if (modifier)
6832     {
6833       int i;
6834       for (i = 0; i <= 10; i++) if (1 << i & modifier) break;
6835       if (modifier == ACC_FINAL)
6836         final_p = 1;
6837       else 
6838         {
6839           parse_error_context 
6840             (ctxp->modifier_ctx [i], 
6841              "Only `final' is allowed as a local variables modifier");
6842           return;
6843         }
6844     }
6845
6846   /* Obtain an incomplete type if TYPE is not complete. TYPE_WFL will
6847      hold the TYPE value if a new incomplete has to be created (as
6848      opposed to being found already existing and reused). */
6849   SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
6850
6851   /* If TYPE is fully resolved and we don't have a reference, make one */
6852   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
6853
6854   /* Go through all the declared variables */
6855   for (current = vlist, saved_type = type; current;
6856        current = TREE_CHAIN (current), type = saved_type)
6857     {
6858       tree other, real_type;
6859       tree wfl  = TREE_PURPOSE (current);
6860       tree name = EXPR_WFL_NODE (wfl);
6861       tree init = TREE_VALUE (current);
6862
6863       /* Process NAME, as it may specify extra dimension(s) for it */
6864       type = build_array_from_name (type, type_wfl, name, &name);
6865
6866       /* Variable redefinition check */
6867       if ((other = lookup_name_in_blocks (name)))
6868         {
6869           variable_redefinition_error (wfl, name, TREE_TYPE (other),
6870                                        DECL_SOURCE_LINE (other));
6871           continue;
6872         }
6873
6874       /* Type adjustment. We may have just readjusted TYPE because
6875          the variable specified more dimensions. Make sure we have
6876          a reference if we can and don't have one already. */
6877       PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
6878
6879       real_type = GET_REAL_TYPE (type);
6880       /* Never layout this decl. This will be done when its scope
6881          will be entered */
6882       decl = build_decl (VAR_DECL, name, real_type);
6883       LOCAL_FINAL (decl) = final_p;
6884       BLOCK_CHAIN_DECL (decl);
6885       
6886       /* If doing xreferencing, replace the line number with the WFL
6887          compound value */
6888       if (flag_emit_xref)
6889         DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (wfl);
6890       
6891       /* Don't try to use an INIT statement when an error was found */
6892       if (init && java_error_count)
6893         init = NULL_TREE;
6894       
6895       /* Add the initialization function to the current function's code */
6896       if (init)
6897         {
6898           /* Name might have been readjusted */
6899           EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = name;
6900           MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
6901           java_method_add_stmt (current_function_decl,
6902                                 build_debugable_stmt (EXPR_WFL_LINECOL (init),
6903                                                       init));
6904         }
6905     
6906       /* Setup dependency the type of the decl */
6907       if (must_chain)
6908         {
6909           jdep *dep;
6910           register_incomplete_type (JDEP_VARIABLE, type_wfl, decl, type);
6911           dep = CLASSD_LAST (ctxp->classd_list);
6912           JDEP_GET_PATCH (dep) = &TREE_TYPE (decl);
6913         }
6914     }
6915   SOURCE_FRONTEND_DEBUG (("Defined locals"));
6916 }
6917
6918 /* Called during parsing. Build decls from argument list.  */
6919
6920 static void
6921 source_start_java_method (fndecl)
6922      tree fndecl;
6923 {
6924   tree tem;
6925   tree parm_decl;
6926   int i;
6927
6928   if (!fndecl)
6929     return;
6930
6931   current_function_decl = fndecl;
6932
6933   /* New scope for the function */
6934   enter_block ();
6935   for (tem = TYPE_ARG_TYPES (TREE_TYPE (fndecl)), i = 0;
6936        tem != end_params_node; tem = TREE_CHAIN (tem), i++)
6937     {
6938       tree type = TREE_VALUE (tem);
6939       tree name = TREE_PURPOSE (tem);
6940       
6941       /* If type is incomplete. Create an incomplete decl and ask for
6942          the decl to be patched later */
6943       if (INCOMPLETE_TYPE_P (type))
6944         {
6945           jdep *jdep;
6946           tree real_type = GET_REAL_TYPE (type);
6947           parm_decl = build_decl (PARM_DECL, name, real_type);
6948           type = obtain_incomplete_type (type);
6949           register_incomplete_type (JDEP_PARM, NULL_TREE, NULL_TREE, type);
6950           jdep = CLASSD_LAST (ctxp->classd_list);
6951           JDEP_MISC (jdep) = name;
6952           JDEP_GET_PATCH (jdep) = &TREE_TYPE (parm_decl);
6953         }
6954       else
6955         parm_decl = build_decl (PARM_DECL, name, type);
6956
6957       /* Remember if a local variable was declared final (via its
6958          TREE_LIST of type/name.) Set LOCAL_FINAL accordingly. */
6959       if (ARG_FINAL_P (tem))
6960         LOCAL_FINAL (parm_decl) = 1;
6961
6962       BLOCK_CHAIN_DECL (parm_decl);
6963     }
6964   tem = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
6965   BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl)) =
6966     nreverse (tem);
6967   DECL_ARG_SLOT_COUNT (current_function_decl) = i;
6968   DECL_MAX_LOCALS (current_function_decl) = i;
6969 }
6970
6971 /* Called during parsing. Creates an artificial method declaration.  */
6972
6973 static tree
6974 create_artificial_method (class, flags, type, name, args)
6975      tree class;
6976      int flags;
6977      tree type, name, args;
6978 {
6979   tree mdecl;
6980
6981   java_parser_context_save_global ();
6982   lineno = 0;                                                               
6983   mdecl = make_node (FUNCTION_TYPE);                                
6984   TREE_TYPE (mdecl) = type;
6985   TYPE_ARG_TYPES (mdecl) = args;
6986   mdecl = add_method (class, flags, name, build_java_signature (mdecl)); 
6987   java_parser_context_restore_global ();
6988   DECL_ARTIFICIAL (mdecl) = 1;                                      
6989   return mdecl;
6990 }
6991
6992 /* Starts the body if an artifical method.  */
6993
6994 static void
6995 start_artificial_method_body (mdecl)
6996      tree mdecl;
6997 {
6998   DECL_SOURCE_LINE (mdecl) = 1;
6999   DECL_SOURCE_LINE_MERGE (mdecl, 1);
7000   source_start_java_method (mdecl);
7001   enter_block ();
7002 }
7003
7004 static void
7005 end_artificial_method_body (mdecl)
7006      tree mdecl;
7007 {
7008   BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)) = exit_block ();
7009   exit_block ();
7010 }
7011
7012 /* Called during expansion. Push decls formerly built from argument
7013    list so they're usable during expansion. */
7014
7015 static void
7016 expand_start_java_method (fndecl)
7017      tree fndecl;
7018 {
7019   tree tem, *ptr;
7020
7021   current_function_decl = fndecl;
7022
7023   if (! quiet_flag)
7024     fprintf (stderr, " [%s.", lang_printable_name (DECL_CONTEXT (fndecl), 0));
7025   announce_function (fndecl);
7026   if (! quiet_flag)
7027     fprintf (stderr, "]");
7028
7029   pushlevel (1);                /* Prepare for a parameter push */
7030   ptr = &DECL_ARGUMENTS (fndecl);
7031   tem  = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
7032   while (tem)
7033     {
7034       tree next = TREE_CHAIN (tem);
7035       tree type = TREE_TYPE (tem);
7036       if (PROMOTE_PROTOTYPES
7037           && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
7038           && INTEGRAL_TYPE_P (type))
7039         type = integer_type_node;
7040       DECL_ARG_TYPE (tem) = type;
7041       layout_decl (tem, 0);
7042       pushdecl (tem);
7043       *ptr = tem;
7044       ptr = &TREE_CHAIN (tem);
7045       tem = next;
7046     }
7047   *ptr = NULL_TREE;
7048   pushdecl_force_head (DECL_ARGUMENTS (fndecl));
7049   lineno = DECL_SOURCE_LINE_FIRST (fndecl);
7050 }
7051
7052 /* Terminate a function and expand its body.  */
7053
7054 static void
7055 source_end_java_method ()
7056 {
7057   tree fndecl = current_function_decl;
7058   int flag_asynchronous_exceptions = asynchronous_exceptions;
7059
7060   if (!fndecl)
7061     return;
7062
7063   java_parser_context_save_global ();
7064   lineno = ctxp->last_ccb_indent1;
7065
7066   /* Set EH language codes */
7067   java_set_exception_lang_code ();
7068
7069   /* Turn function bodies with only a NOP expr null, so they don't get
7070      generated at all and we won't get warnings when using the -W
7071      -Wall flags. */
7072   if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) == empty_stmt_node)
7073     BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) = NULL_TREE;
7074
7075   /* Generate function's code */
7076   if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl))
7077       && ! flag_emit_class_files
7078       && ! flag_emit_xref)
7079     expand_expr_stmt (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)));
7080
7081   /* pop out of its parameters */
7082   pushdecl_force_head (DECL_ARGUMENTS (fndecl));
7083   poplevel (1, 0, 1);
7084   BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
7085
7086   /* Generate rtl for function exit.  */
7087   if (! flag_emit_class_files && ! flag_emit_xref)
7088     {
7089       lineno = DECL_SOURCE_LINE_LAST (fndecl);
7090       /* Emit catch-finally clauses */
7091       emit_handlers ();
7092       expand_function_end (input_filename, lineno, 0);
7093
7094       /* FIXME: If the current method contains any exception handlers,
7095          force asynchronous_exceptions: this is necessary because signal
7096          handlers in libjava may throw exceptions.  This is far from being
7097          a perfect solution, but it's better than doing nothing at all.*/
7098       if (catch_clauses)
7099         asynchronous_exceptions = 1;
7100
7101       /* Run the optimizers and output assembler code for this function. */
7102       rest_of_compilation (fndecl);
7103     }
7104
7105   current_function_decl = NULL_TREE;
7106   permanent_allocation (1);
7107   java_parser_context_restore_global ();
7108   asynchronous_exceptions = flag_asynchronous_exceptions;
7109 }
7110
7111 /* Record EXPR in the current function block. Complements compound
7112    expression second operand if necessary.  */
7113
7114 tree
7115 java_method_add_stmt (fndecl, expr)
7116      tree fndecl, expr;
7117 {
7118   if (!GET_CURRENT_BLOCK (fndecl))
7119     return NULL_TREE;
7120   return add_stmt_to_block (GET_CURRENT_BLOCK (fndecl), NULL_TREE, expr);
7121 }
7122
7123 static tree
7124 add_stmt_to_block (b, type, stmt)
7125      tree b, type, stmt;
7126 {
7127   tree body = BLOCK_EXPR_BODY (b), c;
7128   
7129   if (java_error_count)
7130     return body;
7131     
7132   if ((c = add_stmt_to_compound (body, type, stmt)) == body)
7133     return body;
7134
7135   BLOCK_EXPR_BODY (b) = c;
7136   TREE_SIDE_EFFECTS (c) = 1;
7137   return c;
7138 }
7139
7140 /* Add STMT to EXISTING if possible, otherwise create a new
7141    COMPOUND_EXPR and add STMT to it. */
7142
7143 static tree
7144 add_stmt_to_compound (existing, type, stmt)
7145      tree existing, type, stmt;
7146 {
7147   if (existing)
7148     return build (COMPOUND_EXPR, type, existing, stmt);
7149   else
7150     return stmt;
7151 }
7152
7153 /* Hold THIS for the scope of the current public method decl.  */
7154 static tree current_this;
7155
7156 void java_layout_seen_class_methods ()
7157 {
7158   tree previous_list = all_class_list;
7159   tree end = NULL_TREE;
7160   tree current;
7161
7162   while (1)
7163     {
7164       for (current = previous_list; 
7165            current != end; current = TREE_CHAIN (current))
7166         layout_class_methods (TREE_TYPE (TREE_VALUE (current)));
7167       
7168       if (previous_list != all_class_list)
7169         {
7170           end = previous_list;
7171           previous_list = all_class_list;
7172         }
7173       else
7174         break;
7175     }
7176 }
7177
7178 void
7179 java_reorder_fields ()
7180 {
7181   static tree stop_reordering = NULL_TREE;
7182
7183   tree current;
7184   for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
7185     {
7186       current_class = TREE_TYPE (TREE_VALUE (current));
7187
7188       if (current_class == stop_reordering)
7189         break;
7190
7191       /* Reverse the fields, but leave the dummy field in front.
7192          Fields are already ordered for Object and Class */
7193       if (TYPE_FIELDS (current_class) && current_class != object_type_node
7194           && current_class != class_type_node)
7195       {
7196         /* If the dummy field is there, reverse the right fields and
7197            just layout the type for proper fields offset */
7198         if (!DECL_NAME (TYPE_FIELDS (current_class)))
7199           {
7200             tree fields = TYPE_FIELDS (current_class);
7201             TREE_CHAIN (fields) = nreverse (TREE_CHAIN (fields));
7202             TYPE_SIZE (current_class) = NULL_TREE;
7203           }
7204         /* We don't have a dummy field, we need to layout the class,
7205            after having reversed the fields */
7206         else
7207           {
7208             TYPE_FIELDS (current_class) = 
7209               nreverse (TYPE_FIELDS (current_class));
7210             TYPE_SIZE (current_class) = NULL_TREE;
7211           }
7212       }
7213     }
7214   stop_reordering = TREE_TYPE (TREE_VALUE (ctxp->gclass_list));
7215 }
7216
7217 /* Layout the methods of all classes loaded in one way on an
7218    other. Check methods of source parsed classes. Then reorder the
7219    fields and layout the classes or the type of all source parsed
7220    classes */
7221
7222 void
7223 java_layout_classes ()
7224 {
7225   tree current;
7226   int save_error_count = java_error_count;
7227
7228   /* Layout the methods of all classes seen so far */
7229   java_layout_seen_class_methods ();
7230   java_parse_abort_on_error ();
7231   all_class_list = NULL_TREE;
7232
7233   /* Then check the methods of all parsed classes */
7234   for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
7235     if (CLASS_FROM_SOURCE_P (TREE_TYPE (TREE_VALUE (current))))
7236       CHECK_METHODS (TREE_VALUE (current));
7237   java_parse_abort_on_error ();
7238
7239   for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
7240     {
7241       current_class = TREE_TYPE (TREE_VALUE (current));
7242       layout_class (current_class);
7243
7244       /* From now on, the class is considered completely loaded */
7245       CLASS_LOADED_P (current_class) = 1;
7246
7247       /* Error reported by the caller */
7248       if (java_error_count)
7249         return;
7250     }
7251
7252   /* We might have reloaded classes durign the process of laying out
7253      classes for code generation. We must layout the methods of those
7254      late additions, as constructor checks might use them */
7255   java_layout_seen_class_methods ();
7256   java_parse_abort_on_error ();
7257 }
7258
7259 /* Expand methods in the current set of classes rememebered for
7260    generation.  */
7261
7262 static void
7263 java_complete_expand_classes ()
7264 {
7265   tree current;
7266
7267   do_not_fold = flag_emit_xref;
7268
7269   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
7270     if (!INNER_CLASS_DECL_P (current))
7271       java_complete_expand_class (current);
7272 }
7273
7274 /* Expand the methods found in OUTER, starting first by OUTER's inner
7275    classes, if any.  */
7276
7277 static void
7278 java_complete_expand_class (outer)
7279      tree outer;
7280 {
7281   tree inner_list;
7282
7283   set_nested_class_simple_name_value (outer, 1); /* Set */
7284
7285   /* We need to go after all inner classes and start expanding them,
7286      starting with most nested ones. We have to do that because nested
7287      classes might add functions to outer classes */
7288
7289   for (inner_list = DECL_INNER_CLASS_LIST (outer);
7290        inner_list; inner_list = TREE_CHAIN (inner_list))
7291     java_complete_expand_class (TREE_PURPOSE (inner_list));
7292
7293   java_complete_expand_methods (outer);
7294   set_nested_class_simple_name_value (outer, 0); /* Reset */
7295 }
7296
7297 /* Expand methods registered in CLASS_DECL. The general idea is that
7298    we expand regular methods first. This allows us get an estimate on
7299    how outer context local alias fields are really used so we can add
7300    to the constructor just enough code to initialize them properly (it
7301    also lets us generate $finit$ correctly.) Then we expand the
7302    constructors and then <clinit>.  */
7303
7304 static void
7305 java_complete_expand_methods (class_decl)
7306      tree class_decl;
7307 {
7308   tree clinit, finit, decl, first_decl;
7309
7310   current_class = TREE_TYPE (class_decl);
7311
7312   /* Initialize a new constant pool */
7313   init_outgoing_cpool ();
7314
7315   /* Pre-expand <clinit> to figure whether we really need it or
7316      not. If we do need it, we pre-expand the static fields so they're
7317      ready to be used somewhere else. <clinit> will be fully expanded
7318      after we processed the constructors. */
7319   first_decl = TYPE_METHODS (current_class);
7320   clinit = maybe_generate_pre_expand_clinit (current_class);
7321
7322   /* Then generate $finit$ (if we need to) because constructor will
7323    try to use it.*/
7324   if (TYPE_FINIT_STMT_LIST (current_class))
7325     {
7326       finit = generate_finit (current_class);
7327       java_complete_expand_method (finit);
7328     }
7329
7330   /* Now do the constructors */
7331   for (decl = first_decl ; !java_error_count && decl; decl = TREE_CHAIN (decl))
7332     {
7333       int no_body;
7334
7335       if (!DECL_CONSTRUCTOR_P (decl))
7336         continue;
7337       
7338       no_body = !DECL_FUNCTION_BODY (decl);
7339       /* Don't generate debug info on line zero when expanding a
7340          generated constructor. */
7341       if (no_body)
7342         restore_line_number_status (1);
7343
7344       java_complete_expand_method (decl);
7345       
7346       if (no_body)
7347         restore_line_number_status (0);
7348     }
7349
7350   /* First, do the ordinary methods. */
7351   for (decl = first_decl; decl; decl = TREE_CHAIN (decl))
7352     {
7353       /* Skip abstract or native methods -- but do handle native
7354          methods when generating JNI stubs.  */
7355       if (METHOD_ABSTRACT (decl)
7356           || (! flag_jni && METHOD_NATIVE (decl))
7357           || DECL_CONSTRUCTOR_P (decl) || DECL_CLINIT_P (decl))
7358         continue;
7359
7360       if (METHOD_NATIVE (decl))
7361         {
7362           tree body = build_jni_stub (decl);
7363           BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (decl)) = body;
7364         }
7365
7366       java_complete_expand_method (decl);
7367     }
7368
7369   /* If there is indeed a <clinit>, fully expand it now */
7370   if (clinit)
7371     {
7372       /* Prevent the use of `this' inside <clinit> */
7373       ctxp->explicit_constructor_p = 1;
7374       java_complete_expand_method (clinit);
7375       ctxp->explicit_constructor_p = 0;
7376     }
7377   
7378   /* We might have generated a class$ that we now want to expand */
7379   if (TYPE_DOT_CLASS (current_class))
7380     java_complete_expand_method (TYPE_DOT_CLASS (current_class));
7381
7382   /* Now verify constructor circularity (stop after the first one we
7383      prove wrong.) */
7384   if (!CLASS_INTERFACE (class_decl))
7385     for (decl = TYPE_METHODS (current_class); decl; decl = TREE_CHAIN (decl))
7386       if (DECL_CONSTRUCTOR_P (decl) 
7387           && verify_constructor_circularity (decl, decl))
7388         break;
7389
7390   /* Save the constant pool. We'll need to restore it later. */
7391   TYPE_CPOOL (current_class) = outgoing_cpool;
7392 }
7393
7394 /* Hold a list of catch clauses list. The first element of this list is
7395    the list of the catch clauses of the currently analysed try block. */
7396 static tree currently_caught_type_list;
7397
7398 /* Attempt to create <clinit>. Pre-expand static fields so they can be
7399    safely used in some other methods/constructors.  */
7400
7401 static tree
7402 maybe_generate_pre_expand_clinit (class_type)
7403      tree class_type;
7404 {
7405   tree current, mdecl;
7406
7407   if (!TYPE_CLINIT_STMT_LIST (class_type))
7408     return NULL_TREE;
7409
7410   /* Go through all static fields and pre expand them */
7411   for (current = TYPE_FIELDS (class_type); current; 
7412        current = TREE_CHAIN (current))
7413     if (FIELD_STATIC (current))
7414       build_field_ref (NULL_TREE, class_type, DECL_NAME (current));
7415
7416   /* Then build the <clinit> method */
7417   mdecl = create_artificial_method (class_type, ACC_STATIC, void_type_node,
7418                                     clinit_identifier_node, end_params_node);
7419   layout_class_method (class_type, CLASSTYPE_SUPER (class_type),
7420                        mdecl, NULL_TREE);
7421   start_artificial_method_body (mdecl);
7422
7423   /* We process the list of assignment we produced as the result of
7424      the declaration of initialized static field and add them as
7425      statement to the <clinit> method. */
7426   for (current = TYPE_CLINIT_STMT_LIST (class_type); current;
7427        current = TREE_CHAIN (current))
7428     {
7429       tree stmt = current;
7430       /* We build the assignment expression that will initialize the
7431          field to its value. There are strict rules on static
7432          initializers (8.5). FIXME */
7433       if (TREE_CODE (stmt) != BLOCK)
7434         stmt = build_debugable_stmt (EXPR_WFL_LINECOL (stmt), stmt);
7435       java_method_add_stmt (mdecl, stmt);
7436     }
7437
7438   end_artificial_method_body (mdecl);
7439
7440   /* Now we want to place <clinit> as the last method (because we need
7441      it at least for interface so that it doesn't interfere with the
7442      dispatch table based lookup. */
7443   if (TREE_CHAIN (TYPE_METHODS (class_type)))
7444     {
7445       current = TREE_CHAIN (TYPE_METHODS (class_type));
7446       TYPE_METHODS (class_type) = current;
7447
7448       while (TREE_CHAIN (current))
7449         current = TREE_CHAIN (current);
7450
7451       TREE_CHAIN (current) = mdecl;
7452       TREE_CHAIN (mdecl) = NULL_TREE;
7453     }
7454
7455   return mdecl;
7456 }
7457
7458 /* See whether we could get rid of <clinit>. Criteria are: all static
7459    final fields have constant initial values and the body of <clinit>
7460    is empty. Return 1 if <clinit> was discarded, 0 otherwise. */
7461
7462 static int
7463 maybe_yank_clinit (mdecl)
7464      tree mdecl;
7465 {
7466   tree type, current;
7467   tree fbody, bbody;
7468   
7469   if (!DECL_CLINIT_P (mdecl))
7470     return 0;
7471   
7472   /* If the body isn't empty, then we keep <clinit> */
7473   fbody = DECL_FUNCTION_BODY (mdecl);
7474   if ((bbody = BLOCK_EXPR_BODY (fbody)))
7475     bbody = BLOCK_EXPR_BODY (bbody);
7476   if (bbody && bbody != empty_stmt_node)
7477     return 0;
7478   
7479   type = DECL_CONTEXT (mdecl);
7480   current = TYPE_FIELDS (type);
7481
7482   for (current = (current ? TREE_CHAIN (current) : current); 
7483        current; current = TREE_CHAIN (current))
7484     if (!(FIELD_STATIC (current) && FIELD_FINAL (current)
7485           && DECL_INITIAL (current) && TREE_CONSTANT (DECL_INITIAL (current))))
7486       break;
7487
7488   if (current)
7489     return 0;
7490
7491   /* Get rid of <clinit> in the class' list of methods */
7492   if (TYPE_METHODS (type) == mdecl)
7493     TYPE_METHODS (type) = TREE_CHAIN (mdecl);
7494   else
7495     for (current = TYPE_METHODS (type); current; 
7496          current = TREE_CHAIN (current))
7497       if (TREE_CHAIN (current) == mdecl)
7498         {
7499           TREE_CHAIN (current) = TREE_CHAIN (mdecl);
7500           break;
7501         }
7502
7503   return 1;
7504 }
7505
7506
7507 /* Complete and expand a method.  */
7508
7509 static void
7510 java_complete_expand_method (mdecl)
7511      tree mdecl;
7512 {
7513   int yank_clinit = 0;
7514
7515   current_function_decl = mdecl;
7516   /* Fix constructors before expanding them */
7517   if (DECL_CONSTRUCTOR_P (mdecl))
7518     fix_constructors (mdecl);
7519   
7520   /* Expand functions that have a body */
7521   if (DECL_FUNCTION_BODY (mdecl))
7522     {
7523       tree fbody = DECL_FUNCTION_BODY (mdecl);
7524       tree block_body = BLOCK_EXPR_BODY (fbody);
7525       tree exception_copy = NULL_TREE;
7526       expand_start_java_method (mdecl);
7527       build_result_decl (mdecl);
7528
7529       current_this 
7530         = (!METHOD_STATIC (mdecl) ? 
7531            BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl)) : NULL_TREE);
7532
7533       /* Purge the `throws' list of unchecked exceptions. If we're
7534          doing xref, save a copy of the list and re-install it
7535          later. */
7536       if (flag_emit_xref)
7537         exception_copy = copy_list (DECL_FUNCTION_THROWS (mdecl));
7538
7539       purge_unchecked_exceptions (mdecl);
7540
7541       /* Install exceptions thrown with `throws' */
7542       PUSH_EXCEPTIONS (DECL_FUNCTION_THROWS (mdecl));
7543
7544       if (block_body != NULL_TREE)
7545         {
7546           block_body = java_complete_tree (block_body);
7547
7548           if (! flag_emit_xref && ! METHOD_NATIVE (mdecl))
7549             check_for_initialization (block_body);
7550           ctxp->explicit_constructor_p = 0;
7551         }
7552
7553       BLOCK_EXPR_BODY (fbody) = block_body;
7554
7555       /* If we saw a return but couldn't evaluate it properly, we'll
7556          have an error_mark_node here. */
7557       if (block_body != error_mark_node
7558           && (block_body == NULL_TREE || CAN_COMPLETE_NORMALLY (block_body))
7559           && TREE_CODE (TREE_TYPE (TREE_TYPE (mdecl))) != VOID_TYPE
7560           && !flag_emit_xref)
7561         missing_return_error (current_function_decl);
7562
7563       /* Check wether we could just get rid of clinit, now the picture
7564          is complete. */
7565       if (!(yank_clinit = maybe_yank_clinit (mdecl)))
7566         complete_start_java_method (mdecl); 
7567       
7568       /* Don't go any further if we've found error(s) during the
7569          expansion */
7570       if (!java_error_count && !yank_clinit)
7571         source_end_java_method ();
7572       else
7573         {
7574           if (java_error_count)
7575             pushdecl_force_head (DECL_ARGUMENTS (mdecl));
7576           poplevel (1, 0, 1);
7577         }
7578
7579       /* Pop the exceptions and sanity check */
7580       POP_EXCEPTIONS();
7581       if (currently_caught_type_list)
7582         fatal ("Exception list non empty - java_complete_expand_method");
7583
7584       if (flag_emit_xref)
7585         DECL_FUNCTION_THROWS (mdecl) = exception_copy;
7586     }
7587 }
7588
7589 \f
7590
7591 /* This section of the code deals with accessing enclosing context
7592    fields either directly by using the relevant access to this$<n> or
7593    by invoking an access method crafted for that purpose.  */
7594
7595 /* Build the necessary access from an inner class to an outer
7596    class. This routine could be optimized to cache previous result
7597    (decl, current_class and returned access).  When an access method
7598    needs to be generated, it always takes the form of a read. It might
7599    be later turned into a write by calling outer_field_access_fix.  */
7600
7601 static tree
7602 build_outer_field_access (id, decl)
7603      tree id, decl;
7604 {
7605   tree access = NULL_TREE;
7606   tree ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class)));
7607
7608   /* If decl's class is the direct outer class of the current_class,
7609      build the access as `this$<n>.<field>'. Not that we will break
7610      the `private' barrier if we're not emitting bytecodes. */
7611   if (ctx == DECL_CONTEXT (decl) 
7612       && (!FIELD_PRIVATE (decl) || !flag_emit_class_files ))
7613     {
7614       tree thisn = build_current_thisn (current_class);
7615       access = make_qualified_primary (build_wfl_node (thisn), 
7616                                        id, EXPR_WFL_LINECOL (id));
7617     }
7618   /* Otherwise, generate access methods to outer this and access the
7619      field (either using an access method or by direct access.) */
7620   else
7621     {
7622       int lc = EXPR_WFL_LINECOL (id);
7623
7624       /* Now we chain the required number of calls to the access$0 to
7625          get a hold to the enclosing instance we need, and the we
7626          build the field access. */
7627       access = build_access_to_thisn (ctx, DECL_CONTEXT (decl), lc);
7628
7629       /* If the field is private and we're generating bytecode, then
7630          we generate an access method */
7631       if (FIELD_PRIVATE (decl) && flag_emit_class_files )
7632         {
7633           tree name = build_outer_field_access_methods (decl);
7634           access = build_outer_field_access_expr (lc, DECL_CONTEXT (decl),
7635                                                   name, access, NULL_TREE);
7636         }
7637       /* Otherwise we use `access$(this$<j>). ... access$(this$<i>).<field>'.
7638          Once again we break the `private' access rule from a foreign
7639          class. */
7640       else
7641         access = make_qualified_primary (access, id, lc);
7642     }
7643   return resolve_expression_name (access, NULL);
7644 }
7645
7646 /* Return a non zero value if NODE describes an outer field inner
7647    access.  */
7648
7649 static int
7650 outer_field_access_p (type, decl)
7651     tree type, decl;
7652 {
7653   if (!INNER_CLASS_TYPE_P (type) 
7654       || TREE_CODE (decl) != FIELD_DECL
7655       || DECL_CONTEXT (decl) == type)
7656     return 0;
7657
7658   for (type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))); ;
7659        type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))))
7660     {
7661       if (type == DECL_CONTEXT (decl))
7662         return 1;
7663       if (!DECL_CONTEXT (TYPE_NAME (type)))
7664         break;
7665     }
7666
7667   return 0;
7668 }
7669
7670 /* Return a non zero value if NODE represents an outer field inner
7671    access that was been already expanded. As a side effect, it returns
7672    the name of the field being accessed and the argument passed to the
7673    access function, suitable for a regeneration of the access method
7674    call if necessary. */
7675
7676 static int
7677 outer_field_expanded_access_p (node, name, arg_type, arg)
7678     tree node, *name, *arg_type, *arg;
7679 {
7680   int identified = 0;
7681
7682   if (TREE_CODE (node) != CALL_EXPR)
7683     return 0;
7684
7685   /* Well, gcj generates slightly different tree nodes when compiling
7686      to native or bytecodes. It's the case for function calls. */
7687
7688   if (flag_emit_class_files 
7689       && TREE_CODE (node) == CALL_EXPR
7690       && OUTER_FIELD_ACCESS_IDENTIFIER_P (DECL_NAME (TREE_OPERAND (node, 0))))
7691     identified = 1;
7692   else if (!flag_emit_class_files)
7693     {
7694       node = TREE_OPERAND (node, 0);
7695       
7696       if (node && TREE_OPERAND (node, 0)
7697           && TREE_CODE (TREE_OPERAND (node, 0)) == ADDR_EXPR)
7698         {
7699           node = TREE_OPERAND (node, 0);
7700           if (TREE_OPERAND (node, 0)
7701               && TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL
7702               && (OUTER_FIELD_ACCESS_IDENTIFIER_P 
7703                   (DECL_NAME (TREE_OPERAND (node, 0)))))
7704             identified = 1;
7705         }
7706     }
7707
7708   if (identified && name && arg_type && arg)
7709     {
7710       tree argument = TREE_OPERAND (node, 1);
7711       *name = DECL_NAME (TREE_OPERAND (node, 0));
7712       *arg_type = TREE_TYPE (TREE_TYPE (TREE_VALUE (argument)));
7713       *arg = TREE_VALUE (argument);
7714     }
7715   return identified;
7716 }
7717
7718 /* Detect in NODE an outer field read access from an inner class and
7719    transform it into a write with RHS as an argument. This function is
7720    called from the java_complete_lhs when an assignment to a LHS can
7721    be identified. */
7722
7723 static tree
7724 outer_field_access_fix (wfl, node, rhs)
7725     tree wfl, node, rhs;
7726 {
7727   tree name, arg_type, arg;
7728   
7729   if (outer_field_expanded_access_p (node, &name, &arg_type, &arg))
7730     {
7731       /* At any rate, check whether we're trying to assign a value to
7732          a final. */
7733       tree accessed = (JDECL_P (node) ? node : 
7734                        (TREE_CODE (node) == COMPONENT_REF ? 
7735                         TREE_OPERAND (node, 1) : node));
7736       if (check_final_assignment (accessed, wfl))
7737         return error_mark_node;
7738   
7739       node = build_outer_field_access_expr (EXPR_WFL_LINECOL (wfl), 
7740                                             arg_type, name, arg, rhs);
7741       return java_complete_tree (node);
7742     }
7743   return NULL_TREE;
7744 }
7745
7746 /* Construct the expression that calls an access method:
7747      <type>.access$<n>(<arg1> [, <arg2>]); 
7748
7749    ARG2 can be NULL and will be omitted in that case. It will denote a
7750    read access.  */
7751
7752 static tree
7753 build_outer_field_access_expr (lc, type, access_method_name, arg1, arg2)
7754     int lc;
7755     tree type, access_method_name, arg1, arg2;
7756 {
7757   tree args, cn, access;
7758
7759   args = arg1 ? arg1 : 
7760     build_wfl_node (build_current_thisn (current_class));
7761   args = build_tree_list (NULL_TREE, args);
7762
7763   if (arg2)
7764     args = tree_cons (NULL_TREE, arg2, args);
7765
7766   access = build_method_invocation (build_wfl_node (access_method_name), args);
7767   cn = build_wfl_node (DECL_NAME (TYPE_NAME (type)));
7768   return make_qualified_primary (cn, access, lc);
7769 }
7770
7771 static tree
7772 build_new_access_id ()
7773 {
7774   static int access_n_counter = 1;
7775   char buffer [128];
7776
7777   sprintf (buffer, "access$%d", access_n_counter++);
7778   return get_identifier (buffer);
7779 }
7780
7781 /* Create the static access functions for the outer field DECL. We define a
7782    read:
7783      TREE_TYPE (<field>) access$<n> (DECL_CONTEXT (<field>) inst$) {
7784        return inst$.field;
7785      }
7786    and a write access:
7787      TREE_TYPE (<field>) access$<n> (DECL_CONTEXT (<field>) inst$,
7788                                      TREE_TYPE (<field>) value$) {
7789        return inst$.field = value$;
7790      }
7791    We should have a usage flags on the DECL so we can lazily turn the ones
7792    we're using for code generation. FIXME.
7793 */
7794
7795 static tree
7796 build_outer_field_access_methods (decl)
7797     tree decl;
7798 {
7799   tree id, args, stmt, mdecl;
7800   
7801   /* Check point, to be removed. FIXME */
7802   if (FIELD_INNER_ACCESS (decl) 
7803       && TREE_CODE (FIELD_INNER_ACCESS (decl)) != IDENTIFIER_NODE)
7804     abort ();
7805
7806   if (FIELD_INNER_ACCESS (decl))
7807     return FIELD_INNER_ACCESS (decl);
7808
7809   push_obstacks (&permanent_obstack, &permanent_obstack);
7810
7811   /* Create the identifier and a function named after it. */
7812   id = build_new_access_id ();
7813
7814   /* The identifier is marked as bearing the name of a generated write
7815      access function for outer field accessed from inner classes. */
7816   OUTER_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
7817
7818   /* Create the read access */
7819   args = build_tree_list (inst_id, build_pointer_type (DECL_CONTEXT (decl)));
7820   TREE_CHAIN (args) = end_params_node;
7821   stmt = make_qualified_primary (build_wfl_node (inst_id),
7822                                  build_wfl_node (DECL_NAME (decl)), 0);
7823   stmt = build_return (0, stmt);
7824   mdecl = build_outer_field_access_method (DECL_CONTEXT (decl), 
7825                                            TREE_TYPE (decl), id, args, stmt);
7826   DECL_FUNCTION_ACCESS_DECL (mdecl) = decl;
7827
7828   /* Create the write access method */
7829   args = build_tree_list (inst_id, build_pointer_type (DECL_CONTEXT (decl)));
7830   TREE_CHAIN (args) = build_tree_list (wpv_id, TREE_TYPE (decl));
7831   TREE_CHAIN (TREE_CHAIN (args)) = end_params_node;
7832   stmt = make_qualified_primary (build_wfl_node (inst_id),
7833                                  build_wfl_node (DECL_NAME (decl)), 0);
7834   stmt = build_return (0, build_assignment (ASSIGN_TK, 0, stmt,
7835                                             build_wfl_node (wpv_id)));
7836
7837   mdecl = build_outer_field_access_method (DECL_CONTEXT (decl), 
7838                                            TREE_TYPE (decl), id, args, stmt);
7839   DECL_FUNCTION_ACCESS_DECL (mdecl) = decl;
7840   pop_obstacks ();
7841
7842   /* Return the access name */
7843   return FIELD_INNER_ACCESS (decl) = id;
7844 }
7845
7846 /* Build an field access method NAME.  */
7847
7848 static tree 
7849 build_outer_field_access_method (class, type, name, args, body)
7850     tree class, type, name, args, body;
7851 {
7852   tree saved_current_function_decl, mdecl;
7853
7854   /* Create the method */
7855   mdecl = create_artificial_method (class, ACC_STATIC, type, name, args);
7856   fix_method_argument_names (args, mdecl);
7857   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
7858
7859   /* Attach the method body. */
7860   saved_current_function_decl = current_function_decl;
7861   start_artificial_method_body (mdecl);
7862   java_method_add_stmt (mdecl, body);
7863   end_artificial_method_body (mdecl);
7864   current_function_decl = saved_current_function_decl;
7865
7866   return mdecl;
7867 }
7868
7869 \f
7870 /* This section deals with building access function necessary for
7871    certain kinds of method invocation from inner classes.  */
7872
7873 static tree
7874 build_outer_method_access_method (decl)
7875     tree decl;
7876 {
7877   tree saved_current_function_decl, mdecl;
7878   tree args = NULL_TREE, call_args = NULL_TREE;
7879   tree carg, id, body, class;
7880   char buffer [80];
7881   int parm_id_count = 0;
7882
7883   /* Test this abort with an access to a private field */
7884   if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), "access$"))
7885     abort ();
7886
7887   /* Check the cache first */
7888   if (DECL_FUNCTION_INNER_ACCESS (decl))
7889     return DECL_FUNCTION_INNER_ACCESS (decl);
7890
7891   class = DECL_CONTEXT (decl);
7892
7893   /* Obtain an access identifier and mark it */
7894   id = build_new_access_id ();
7895   OUTER_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
7896
7897   push_obstacks (&permanent_obstack, &permanent_obstack);
7898
7899   carg = TYPE_ARG_TYPES (TREE_TYPE (decl));
7900   /* Create the arguments, as much as the original */
7901   for (; carg && carg != end_params_node; 
7902        carg = TREE_CHAIN (carg))
7903     {
7904       sprintf (buffer, "write_parm_value$%d", parm_id_count++);
7905       args = chainon (args, build_tree_list (get_identifier (buffer), 
7906                                              TREE_VALUE (carg)));
7907     }
7908   args = chainon (args, end_params_node);
7909
7910   /* Create the method */
7911   mdecl = create_artificial_method (class, ACC_STATIC, 
7912                                     TREE_TYPE (TREE_TYPE (decl)), id, args);
7913   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
7914   /* There is a potential bug here. We should be able to use
7915      fix_method_argument_names, but then arg names get mixed up and
7916      eventually a constructor will have its this$0 altered and the
7917      outer context won't be assignment properly. The test case is
7918      stub.java FIXME */
7919   TYPE_ARG_TYPES (TREE_TYPE (mdecl)) = args;
7920
7921   /* Attach the method body. */
7922   saved_current_function_decl = current_function_decl;
7923   start_artificial_method_body (mdecl);
7924
7925   /* The actual method invocation uses the same args. When invoking a
7926      static methods that way, we don't want to skip the first
7927      argument. */
7928   carg = args;
7929   if (!METHOD_STATIC (decl))
7930     carg = TREE_CHAIN (carg);
7931   for (; carg && carg != end_params_node; carg = TREE_CHAIN (carg))
7932     call_args = tree_cons (NULL_TREE, build_wfl_node (TREE_PURPOSE (carg)),
7933                            call_args);
7934
7935   body = build_method_invocation (build_wfl_node (DECL_NAME (decl)), 
7936                                   call_args);
7937   if (!METHOD_STATIC (decl))
7938     body = make_qualified_primary (build_wfl_node (TREE_PURPOSE (args)), 
7939                                    body, 0);
7940   if (TREE_TYPE (TREE_TYPE (decl)) != void_type_node)
7941     body = build_return (0, body);
7942   java_method_add_stmt (mdecl,body);
7943   end_artificial_method_body (mdecl);
7944   current_function_decl = saved_current_function_decl;
7945   pop_obstacks ();
7946
7947   /* Back tag the access function so it know what it accesses */
7948   DECL_FUNCTION_ACCESS_DECL (decl) = mdecl;
7949
7950   /* Tag the current method so it knows it has an access generated */
7951   return DECL_FUNCTION_INNER_ACCESS (decl) = mdecl;
7952 }
7953
7954 \f
7955 /* This section of the code deals with building expressions to access
7956    the enclosing instance of an inner class. The enclosing instance is
7957    kept in a generated field called this$<n>, with <n> being the
7958    inner class nesting level (starting from 0.)  */
7959     
7960 /* Build an access to a given this$<n>, possibly by chaining access
7961    call to others. Access methods to this$<n> are build on the fly if
7962    necessary */
7963
7964 static tree
7965 build_access_to_thisn (from, to, lc)
7966      tree from, to;
7967      int lc;
7968 {
7969   tree access = NULL_TREE;
7970
7971   while (from != to)
7972     {
7973       tree access0_wfl, cn;
7974
7975       maybe_build_thisn_access_method (from);
7976       access0_wfl = build_wfl_node (access0_identifier_node);
7977       cn = build_wfl_node (DECL_NAME (TYPE_NAME (from)));
7978       EXPR_WFL_LINECOL (access0_wfl) = lc;
7979       
7980       if (!access)
7981         {
7982           access = build_current_thisn (current_class);
7983           access = build_wfl_node (access);
7984         }
7985       access = build_tree_list (NULL_TREE, access);
7986       access = build_method_invocation (access0_wfl, access);
7987       access = make_qualified_primary (cn, access, lc);
7988       
7989       from = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (from)));
7990     }
7991   return access;
7992 }
7993
7994 /* Build an access function to the this$<n> local to TYPE. NULL_TREE
7995    is returned if nothing needs to be generated. Otherwise, the method
7996    generated and a method decl is returned.  
7997
7998    NOTE: These generated methods should be declared in a class file
7999    attribute so that they can't be referred to directly.  */
8000
8001 static tree
8002 maybe_build_thisn_access_method (type)
8003     tree type;
8004 {
8005   tree mdecl, args, stmt, rtype;
8006   tree saved_current_function_decl;
8007
8008   /* If TYPE is a top-level class, no access method is required.
8009      If there already is such an access method, bail out. */
8010   if (CLASS_ACCESS0_GENERATED_P (type) || !INNER_CLASS_TYPE_P (type))
8011     return NULL_TREE;
8012
8013   /* We generate the method. The method looks like:
8014      static <outer_of_type> access$0 (<type> inst$) { return inst$.this$<n>; }
8015   */
8016   push_obstacks (&permanent_obstack, &permanent_obstack);
8017   args = build_tree_list (inst_id, build_pointer_type (type));
8018   TREE_CHAIN (args) = end_params_node;
8019   rtype = build_pointer_type (TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))));
8020   mdecl = create_artificial_method (type, ACC_STATIC, rtype,
8021                                     access0_identifier_node, args);
8022   fix_method_argument_names (args, mdecl);
8023   layout_class_method (type, NULL_TREE, mdecl, NULL_TREE);
8024   stmt = build_current_thisn (type);
8025   stmt = make_qualified_primary (build_wfl_node (inst_id), 
8026                                  build_wfl_node (stmt), 0);
8027   stmt = build_return (0, stmt);
8028
8029   saved_current_function_decl = current_function_decl;
8030   start_artificial_method_body (mdecl);
8031   java_method_add_stmt (mdecl, stmt);
8032   end_artificial_method_body (mdecl);
8033   current_function_decl = saved_current_function_decl;
8034   pop_obstacks ();
8035
8036   CLASS_ACCESS0_GENERATED_P (type) = 1;
8037
8038   return mdecl;
8039 }
8040
8041 /* Craft an correctly numbered `this$<n>'string. this$0 is used for
8042    the first level of innerclassing. this$1 for the next one, etc...
8043    This function can be invoked with TYPE to NULL, available and then
8044    has to count the parser context.  */
8045
8046 static tree
8047 build_current_thisn (type)
8048     tree type;
8049 {
8050   static int saved_i = -1;
8051   static tree saved_thisn = NULL_TREE;
8052
8053   tree decl;
8054   char buffer [80];
8055   int i = 0;
8056
8057   if (type)
8058     {
8059       static tree saved_type = NULL_TREE;
8060       static int saved_type_i = 0;
8061
8062       if (type == saved_type)
8063         i = saved_type_i;
8064       else
8065         {
8066           for (i = -1, decl = DECL_CONTEXT (TYPE_NAME (type)); 
8067                decl; decl = DECL_CONTEXT (decl), i++)
8068             ;
8069       
8070           saved_type = type;
8071           saved_type_i = i;
8072         }
8073     }
8074   else
8075     i = list_length (GET_CPC_LIST ())-2;
8076
8077   if (i == saved_i)
8078     return saved_thisn;
8079     
8080   sprintf (buffer, "this$%d", i);
8081   saved_i = i;
8082   saved_thisn = get_identifier (buffer);
8083   return saved_thisn;
8084 }
8085
8086 /* Return the assignement to the hidden enclosing context `this$<n>'
8087    by the second incoming parameter to the innerclass constructor. The
8088    form used is `this.this$<n> = this$<n>;'.  */
8089
8090 static tree
8091 build_thisn_assign ()
8092 {
8093   if (current_class && PURE_INNER_CLASS_TYPE_P (current_class))
8094     {
8095       tree thisn = build_current_thisn (current_class);
8096       tree lhs = make_qualified_primary (build_wfl_node (this_identifier_node),
8097                                          build_wfl_node (thisn), 0);
8098       tree rhs = build_wfl_node (thisn);
8099       EXPR_WFL_SET_LINECOL (lhs, lineno, 0);
8100       return build_assignment (ASSIGN_TK, EXPR_WFL_LINECOL (lhs), lhs, rhs);
8101     }
8102   return NULL_TREE;
8103 }
8104
8105 \f
8106 /* Building the synthetic `class$' used to implement the `.class' 1.1
8107    extension for non primitive types. This method looks like:
8108
8109     static Class class$(String type) throws NoClassDefFoundError
8110     {
8111       try {return (java.lang.Class.forName (String));}
8112       catch (ClassNotFoundException e) {
8113         throw new NoClassDefFoundError(e.getMessage());}
8114     } */
8115
8116 static tree
8117 build_dot_class_method (class)
8118      tree class;
8119 {
8120 #define BWF(S) build_wfl_node (get_identifier ((S)))
8121 #define MQN(X,Y) make_qualified_name ((X), (Y), 0)
8122   tree args, tmp, saved_current_function_decl, mdecl;
8123   tree stmt, throw_stmt, catch, catch_block, try_block;
8124   tree catch_clause_param;
8125   tree class_not_found_exception, no_class_def_found_error;
8126
8127   static tree get_message_wfl, type_parm_wfl;
8128
8129   if (!get_message_wfl)
8130     {
8131       get_message_wfl = build_wfl_node (get_identifier ("getMessage"));
8132       type_parm_wfl = build_wfl_node (get_identifier ("type$"));
8133     }
8134
8135   /* Build the arguments */
8136   args = build_tree_list (get_identifier ("type$"),
8137                           build_pointer_type (string_type_node));
8138   TREE_CHAIN (args) = end_params_node;
8139
8140   /* Build the qualified name java.lang.Class.forName */
8141   tmp = MQN (MQN (MQN (BWF ("java"), 
8142                        BWF ("lang")), BWF ("Class")), BWF ("forName"));
8143
8144   /* For things we have to catch and throw */
8145   class_not_found_exception = 
8146     lookup_class (get_identifier ("java.lang.ClassNotFoundException"));
8147   no_class_def_found_error = 
8148     lookup_class (get_identifier ("java.lang.NoClassDefFoundError"));
8149   load_class (class_not_found_exception, 1);
8150   load_class (no_class_def_found_error, 1);
8151
8152   /* Create the "class$" function */
8153   mdecl = create_artificial_method (class, ACC_STATIC, 
8154                                     build_pointer_type (class_type_node),
8155                                     get_identifier ("class$"), args);
8156   DECL_FUNCTION_THROWS (mdecl) = build_tree_list (NULL_TREE,
8157                                                   no_class_def_found_error);
8158   
8159   /* We start by building the try block. We need to build:
8160        return (java.lang.Class.forName (type)); */
8161   stmt = build_method_invocation (tmp, 
8162                                   build_tree_list (NULL_TREE, type_parm_wfl));
8163   stmt = build_return (0, stmt);
8164   /* Put it in a block. That's the try block */
8165   try_block = build_expr_block (stmt, NULL_TREE);
8166
8167   /* Now onto the catch block. We start by building the expression
8168      throwing a new exception: 
8169        throw new NoClassDefFoundError (_.getMessage); */
8170   throw_stmt = make_qualified_name (build_wfl_node (wpv_id), 
8171                                     get_message_wfl, 0);
8172   throw_stmt = build_method_invocation (throw_stmt, NULL_TREE);
8173   
8174   /* Build new NoClassDefFoundError (_.getMessage) */
8175   throw_stmt = build_new_invocation 
8176     (build_wfl_node (get_identifier ("NoClassDefFoundError")),
8177      build_tree_list (build_pointer_type (string_type_node), throw_stmt));
8178
8179   /* Build the throw, (it's too early to use BUILD_THROW) */
8180   throw_stmt = build1 (THROW_EXPR, NULL_TREE, throw_stmt);
8181
8182   /* Build the catch block to encapsulate all this. We begin by
8183      building an decl for the catch clause parameter and link it to
8184      newly created block, the catch block. */
8185   catch_clause_param = 
8186     build_decl (VAR_DECL, wpv_id, 
8187                 build_pointer_type (class_not_found_exception));
8188   catch_block = build_expr_block (NULL_TREE, catch_clause_param);
8189   
8190   /* We initialize the variable with the exception handler. */
8191   catch = build (MODIFY_EXPR, NULL_TREE, catch_clause_param,
8192                  soft_exceptioninfo_call_node);
8193   add_stmt_to_block (catch_block, NULL_TREE, catch);
8194
8195   /* We add the statement throwing the new exception */
8196   add_stmt_to_block (catch_block, NULL_TREE, throw_stmt);
8197
8198   /* Build a catch expression for all this */
8199   catch_block = build1 (CATCH_EXPR, NULL_TREE, catch_block);
8200
8201   /* Build the try/catch sequence */
8202   stmt = build_try_statement (0, try_block, catch_block);
8203
8204   fix_method_argument_names (args, mdecl);
8205   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
8206   saved_current_function_decl = current_function_decl;
8207   start_artificial_method_body (mdecl);
8208   java_method_add_stmt (mdecl, stmt);
8209   end_artificial_method_body (mdecl);
8210   current_function_decl = saved_current_function_decl;
8211   TYPE_DOT_CLASS (class) = mdecl;
8212
8213   return mdecl;
8214 }
8215
8216 static tree
8217 build_dot_class_method_invocation (name)
8218      tree name;
8219 {
8220   tree s = make_node (STRING_CST);
8221   TREE_STRING_LENGTH (s) = IDENTIFIER_LENGTH (name);
8222   TREE_STRING_POINTER (s) = obstack_alloc (expression_obstack,
8223                                            TREE_STRING_LENGTH (s)+1);
8224   strcpy (TREE_STRING_POINTER (s), IDENTIFIER_POINTER (name));
8225   return build_method_invocation (build_wfl_node (get_identifier ("class$")),
8226                                   build_tree_list (NULL_TREE, s));
8227 }
8228
8229 /* This section of the code deals with constructor.  */
8230
8231 /* Craft a body for default constructor. Patch existing constructor
8232    bodies with call to super() and field initialization statements if
8233    necessary.  */
8234
8235 static void
8236 fix_constructors (mdecl)
8237      tree mdecl;
8238 {
8239   tree body = DECL_FUNCTION_BODY (mdecl);
8240   tree thisn_assign, compound = NULL_TREE;
8241   tree class_type = DECL_CONTEXT (mdecl);
8242
8243   if (!body)
8244     {
8245       /* It is an error for the compiler to generate a default
8246          constructor if the superclass doesn't have a constructor that
8247          takes no argument, or the same args for an anonymous class */
8248       if (verify_constructor_super (mdecl))
8249         {
8250           tree sclass_decl = TYPE_NAME (CLASSTYPE_SUPER (class_type));
8251           tree save = DECL_NAME (mdecl);
8252           const char *n = IDENTIFIER_POINTER (DECL_NAME (sclass_decl));
8253           DECL_NAME (mdecl) = DECL_NAME (sclass_decl);
8254           parse_error_context
8255             (lookup_cl (TYPE_NAME (class_type)), 
8256              "No constructor matching `%s' found in class `%s'",
8257              lang_printable_name (mdecl, 0), n);
8258           DECL_NAME (mdecl) = save;
8259         }
8260       
8261       /* The constructor body must be crafted by hand. It's the
8262          constructor we defined when we realize we didn't have the
8263          CLASSNAME() constructor */
8264       start_artificial_method_body (mdecl);
8265       
8266       /* We don't generate a super constructor invocation if we're
8267          compiling java.lang.Object. build_super_invocation takes care
8268          of that. */
8269       compound = java_method_add_stmt (mdecl, build_super_invocation (mdecl));
8270
8271       /* Insert the instance initializer block right here, after the
8272          super invocation. */
8273       add_instance_initializer (mdecl);
8274
8275       /* Insert an assignment to the this$<n> hidden field, if
8276          necessary */
8277       if ((thisn_assign = build_thisn_assign ()))
8278         java_method_add_stmt (mdecl, thisn_assign);
8279
8280       end_artificial_method_body (mdecl);
8281     }
8282   /* Search for an explicit constructor invocation */
8283   else 
8284     {
8285       int found = 0;
8286       tree main_block = BLOCK_EXPR_BODY (body);
8287       
8288       while (body)
8289         switch (TREE_CODE (body))
8290           {
8291           case CALL_EXPR:
8292             found = CALL_EXPLICIT_CONSTRUCTOR_P (body);
8293             body = NULL_TREE;
8294             break;
8295           case COMPOUND_EXPR:
8296           case EXPR_WITH_FILE_LOCATION:
8297             body = TREE_OPERAND (body, 0);
8298             break;
8299           case BLOCK:
8300             body = BLOCK_EXPR_BODY (body);
8301             break;
8302           default:
8303             found = 0;
8304             body = NULL_TREE;
8305           }
8306       /* The constructor is missing an invocation of super() */
8307       if (!found)
8308         compound = add_stmt_to_compound (compound, NULL_TREE,
8309                                          build_super_invocation (mdecl));
8310       
8311       /* Insert the instance initializer block right here, after the
8312          super invocation. */
8313       add_instance_initializer (mdecl);
8314
8315       /* Generate the assignment to this$<n>, if necessary */
8316       if ((thisn_assign = build_thisn_assign ()))
8317         compound = add_stmt_to_compound (compound, NULL_TREE, thisn_assign);
8318
8319       /* Fix the constructor main block if we're adding extra stmts */
8320       if (compound)
8321         {
8322           compound = add_stmt_to_compound (compound, NULL_TREE,
8323                                            BLOCK_EXPR_BODY (main_block));
8324           BLOCK_EXPR_BODY (main_block) = compound;
8325         }
8326     }
8327 }
8328
8329 /* Browse constructors in the super class, searching for a constructor
8330    that doesn't take any argument. Return 0 if one is found, 1
8331    otherwise.  If the current class is an anonymous inner class, look
8332    for something that has the same signature. */
8333
8334 static int
8335 verify_constructor_super (mdecl)
8336      tree mdecl;
8337 {
8338   tree class = CLASSTYPE_SUPER (current_class);
8339   int super_inner = PURE_INNER_CLASS_TYPE_P (class);
8340   tree sdecl;
8341
8342   if (!class)
8343     return 0;
8344
8345   if (ANONYMOUS_CLASS_P (current_class))
8346     {
8347       tree mdecl_arg_type;
8348       SKIP_THIS_AND_ARTIFICIAL_PARMS (mdecl_arg_type, mdecl);
8349       for (sdecl = TYPE_METHODS (class); sdecl; sdecl = TREE_CHAIN (sdecl))
8350         if (DECL_CONSTRUCTOR_P (sdecl))
8351           {
8352             tree arg_type = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (sdecl)));
8353             if (super_inner)
8354               arg_type = TREE_CHAIN (arg_type);
8355             for (; (arg_type != end_params_node 
8356                     && mdecl_arg_type != end_params_node);
8357                  arg_type = TREE_CHAIN (arg_type), 
8358                  mdecl_arg_type = TREE_CHAIN (mdecl_arg_type))
8359               if (TREE_VALUE (arg_type) != TREE_VALUE (mdecl_arg_type))
8360                 break;
8361
8362             if (arg_type == end_params_node && 
8363                 mdecl_arg_type == end_params_node)
8364               return 0;
8365           }
8366     }
8367   else
8368     {
8369       for (sdecl = TYPE_METHODS (class); sdecl; sdecl = TREE_CHAIN (sdecl))
8370         {
8371           tree arg = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (sdecl)));
8372           if (super_inner)
8373             arg = TREE_CHAIN (arg);
8374           if (DECL_CONSTRUCTOR_P (sdecl) && arg == end_params_node)
8375             return 0;
8376         }
8377     }
8378   return 1;
8379 }
8380
8381 /* Generate code for all context remembered for code generation.  */
8382
8383 void
8384 java_expand_classes ()
8385 {
8386   int save_error_count = 0;
8387   static struct parser_ctxt *saved_ctxp = NULL;
8388
8389   java_parse_abort_on_error ();
8390   if (!(ctxp = ctxp_for_generation))
8391     return;
8392   java_layout_classes ();
8393   java_parse_abort_on_error ();
8394
8395   saved_ctxp = ctxp_for_generation;
8396   for (; ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
8397     {
8398       ctxp = ctxp_for_generation;
8399       lang_init_source (2);            /* Error msgs have method prototypes */
8400       java_complete_expand_classes (); /* Complete and expand classes */
8401       java_parse_abort_on_error ();
8402     }
8403
8404   /* Find anonymous classes and expand their constructor, now they
8405      have been fixed. */
8406   for (ctxp_for_generation = saved_ctxp;
8407        ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
8408     {
8409       tree current;
8410       ctxp = ctxp_for_generation;
8411       for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
8412         {
8413           current_class = TREE_TYPE (current);
8414           if (ANONYMOUS_CLASS_P (current_class))
8415             {
8416               tree d;
8417               for (d = TYPE_METHODS (current_class); d; d = TREE_CHAIN (d))
8418                 {
8419                   if (DECL_CONSTRUCTOR_P (d))
8420                     {
8421                       restore_line_number_status (1);
8422                       reset_method_name (d);
8423                       java_complete_expand_method (d);
8424                       restore_line_number_status (0);
8425                       break;    /* We now there are no other ones */
8426                     }
8427                 }
8428             }
8429         }
8430     }
8431
8432   /* If we've found error at that stage, don't try to generate
8433      anything, unless we're emitting xrefs or checking the syntax only
8434      (but not using -fsyntax-only for the purpose of generating
8435      bytecode. */
8436   if (java_error_count && !flag_emit_xref 
8437       && (!flag_syntax_only && !flag_emit_class_files))
8438     return;
8439
8440   /* Now things are stable, go for generation of the class data. */
8441   for (ctxp_for_generation = saved_ctxp;
8442        ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
8443     {
8444       tree current;
8445       ctxp = ctxp_for_generation;
8446       for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
8447         {
8448           current_class = TREE_TYPE (current);
8449           outgoing_cpool = TYPE_CPOOL (current_class);
8450           if (flag_emit_class_files)
8451             write_classfile (current_class);
8452           if (flag_emit_xref)
8453             expand_xref (current_class);
8454           else if (! flag_syntax_only)
8455             finish_class ();
8456         }
8457     }
8458 }
8459
8460 /* Wrap non WFL PRIMARY around a WFL and set EXPR_WFL_QUALIFICATION to
8461    a tree list node containing RIGHT. Fore coming RIGHTs will be
8462    chained to this hook. LOCATION contains the location of the
8463    separating `.' operator.  */
8464
8465 static tree
8466 make_qualified_primary (primary, right, location)
8467      tree primary, right;
8468      int location;
8469 {
8470   tree wfl;
8471
8472   if (TREE_CODE (primary) != EXPR_WITH_FILE_LOCATION)
8473     wfl = build_wfl_wrap (primary, location);
8474   else
8475     {
8476       wfl = primary;
8477       /* If wfl wasn't qualified, we build a first anchor */
8478       if (!EXPR_WFL_QUALIFICATION (wfl))
8479         EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (wfl, NULL_TREE);
8480     }
8481
8482   /* And chain them */
8483   EXPR_WFL_LINECOL (right) = location;
8484   chainon (EXPR_WFL_QUALIFICATION (wfl), build_tree_list (right, NULL_TREE));
8485   PRIMARY_P (wfl) =  1;
8486   return wfl;
8487 }
8488
8489 /* Simple merge of two name separated by a `.' */
8490
8491 static tree
8492 merge_qualified_name (left, right)
8493      tree left, right;
8494 {
8495   tree node;
8496   if (!left && !right)
8497     return NULL_TREE;
8498
8499   if (!left)
8500     return right;
8501
8502   if (!right)
8503     return left;
8504
8505   obstack_grow (&temporary_obstack, IDENTIFIER_POINTER (left),
8506                 IDENTIFIER_LENGTH (left));
8507   obstack_1grow (&temporary_obstack, '.');
8508   obstack_grow0 (&temporary_obstack, IDENTIFIER_POINTER (right),
8509                  IDENTIFIER_LENGTH (right));
8510   node =  get_identifier (obstack_base (&temporary_obstack));
8511   obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
8512   QUALIFIED_P (node) = 1;
8513   return node;
8514 }
8515
8516 /* Merge the two parts of a qualified name into LEFT.  Set the
8517    location information of the resulting node to LOCATION, usually
8518    inherited from the location information of the `.' operator. */
8519
8520 static tree
8521 make_qualified_name (left, right, location)
8522      tree left, right;
8523      int location;
8524 {
8525 #ifdef USE_COMPONENT_REF
8526   tree node = build (COMPONENT_REF, NULL_TREE, left, right);
8527   EXPR_WFL_LINECOL (node) = location;
8528   return node;
8529 #else
8530   tree left_id = EXPR_WFL_NODE (left);
8531   tree right_id = EXPR_WFL_NODE (right);
8532   tree wfl, merge;
8533
8534   merge = merge_qualified_name (left_id, right_id);
8535
8536   /* Left wasn't qualified and is now qualified */
8537   if (!QUALIFIED_P (left_id))
8538     {
8539       tree wfl = build_expr_wfl (left_id, ctxp->filename, 0, 0);
8540       EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (left);
8541       EXPR_WFL_QUALIFICATION (left) = build_tree_list (wfl, NULL_TREE);
8542     }
8543   
8544   wfl = build_expr_wfl (right_id, ctxp->filename, 0, 0);
8545   EXPR_WFL_LINECOL (wfl) = location;
8546   chainon (EXPR_WFL_QUALIFICATION (left), build_tree_list (wfl, NULL_TREE));
8547
8548   EXPR_WFL_NODE (left) = merge;
8549   return left;
8550 #endif
8551 }
8552
8553 /* Extract the last identifier component of the qualified in WFL. The
8554    last identifier is removed from the linked list */
8555
8556 static tree
8557 cut_identifier_in_qualified (wfl)
8558      tree wfl;
8559 {
8560   tree q;
8561   tree previous = NULL_TREE;
8562   for (q = EXPR_WFL_QUALIFICATION (wfl); ; previous = q, q = TREE_CHAIN (q))
8563     if (!TREE_CHAIN (q))
8564       {
8565         if (!previous)
8566           fatal ("Operating on a non qualified qualified WFL - cut_identifier_in_qualified");
8567         TREE_CHAIN (previous) = NULL_TREE;
8568         return TREE_PURPOSE (q);
8569       }
8570 }
8571
8572 /* Resolve the expression name NAME. Return its decl.  */
8573
8574 static tree
8575 resolve_expression_name (id, orig)
8576      tree id;
8577      tree *orig;
8578 {
8579   tree name = EXPR_WFL_NODE (id);
8580   tree decl;
8581
8582   /* 6.5.5.1: Simple expression names */
8583   if (!PRIMARY_P (id) && !QUALIFIED_P (name))
8584     {
8585       /* 15.13.1: NAME can appear within the scope of a local variable
8586          declaration */
8587       if ((decl = IDENTIFIER_LOCAL_VALUE (name)))
8588         return decl;
8589
8590       /* 15.13.1: NAME can appear within a class declaration */
8591       else 
8592         {
8593           decl = lookup_field_wrapper (current_class, name);
8594           if (decl)
8595             {
8596               tree access = NULL_TREE;
8597               int fs = FIELD_STATIC (decl);
8598
8599               /* If we're accessing an outer scope local alias, make
8600                  sure we change the name of the field we're going to
8601                  build access to. */
8602               if (FIELD_LOCAL_ALIAS_USED (decl))
8603                 name = DECL_NAME (decl);
8604
8605               /* Instance variable (8.3.1.1) can't appear within
8606                  static method, static initializer or initializer for
8607                  a static variable. */
8608               if (!fs && METHOD_STATIC (current_function_decl))
8609                 {
8610                   static_ref_err (id, name, current_class);
8611                   return error_mark_node;
8612                 }
8613               /* Instance variables can't appear as an argument of
8614                  an explicit constructor invocation */
8615               if (!fs && ctxp->explicit_constructor_p)
8616                 {
8617                   parse_error_context
8618                     (id, "Can't reference `%s' before the superclass constructor has been called", IDENTIFIER_POINTER (name));
8619                   return error_mark_node;
8620                 }
8621
8622               /* If we're processing an inner class and we're trying
8623                  to access a field belonging to an outer class, build
8624                  the access to the field */
8625               if (!fs && outer_field_access_p (current_class, decl))
8626                 return build_outer_field_access (id, decl);
8627
8628               /* Otherwise build what it takes to access the field */
8629               access = build_field_ref ((fs ? NULL_TREE : current_this),
8630                                         DECL_CONTEXT (decl), name);
8631               if (fs && !flag_emit_class_files && !flag_emit_xref)
8632                 access = build_class_init (DECL_CONTEXT (access), access);
8633               /* We may be asked to save the real field access node */
8634               if (orig)
8635                 *orig = access;
8636               /* And we return what we got */
8637               return access;
8638             }
8639           /* Fall down to error report on undefined variable */
8640         }
8641     }
8642   /* 6.5.5.2 Qualified Expression Names */
8643   else
8644     {
8645       if (orig)
8646         *orig = NULL_TREE;
8647       qualify_ambiguous_name (id);
8648       /* 15.10.1 Field Access Using a Primary and/or Expression Name */
8649       /* 15.10.2: Accessing Superclass Members using super */
8650       return resolve_field_access (id, orig, NULL);
8651     }
8652
8653   /* We've got an error here */
8654   parse_error_context (id, "Undefined variable `%s'", 
8655                        IDENTIFIER_POINTER (name));
8656
8657   return error_mark_node;
8658 }
8659
8660 static void
8661 static_ref_err (wfl, field_id, class_type)
8662     tree wfl, field_id, class_type;
8663 {
8664   parse_error_context 
8665     (wfl, 
8666      "Can't make a static reference to nonstatic variable `%s' in class `%s'",
8667      IDENTIFIER_POINTER (field_id), 
8668      IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class_type))));
8669 }
8670
8671 /* 15.10.1 Field Acess Using a Primary and/or Expression Name.
8672    We return something suitable to generate the field access. We also
8673    return the field decl in FIELD_DECL and its type in FIELD_TYPE.  If
8674    recipient's address can be null. */
8675
8676 static tree
8677 resolve_field_access (qual_wfl, field_decl, field_type)
8678      tree qual_wfl;
8679      tree *field_decl, *field_type;
8680 {
8681   int is_static = 0;
8682   tree field_ref;
8683   tree decl, where_found, type_found;
8684
8685   if (resolve_qualified_expression_name (qual_wfl, &decl,
8686                                          &where_found, &type_found))
8687     return error_mark_node;
8688
8689   /* Resolve the LENGTH field of an array here */
8690   if (DECL_P (decl) && DECL_NAME (decl) == length_identifier_node 
8691       && TYPE_ARRAY_P (type_found) 
8692       && ! flag_emit_class_files && ! flag_emit_xref)
8693     {
8694       tree length = build_java_array_length_access (where_found);
8695       field_ref =
8696         build_java_arraynull_check (type_found, length, int_type_node);
8697
8698       /* In case we're dealing with a static array, we need to
8699          initialize its class before the array length can be fetched.
8700          It's also a good time to create a DECL_RTL for the field if
8701          none already exists, otherwise if the field was declared in a
8702          class found in an external file and hasn't been (and won't
8703          be) accessed for its value, none will be created. */
8704       if (TREE_CODE (where_found) == VAR_DECL && FIELD_STATIC (where_found))
8705         {
8706           build_static_field_ref (where_found);
8707           field_ref = build_class_init (DECL_CONTEXT (where_found), field_ref);
8708         }
8709     }
8710   /* We might have been trying to resolve field.method(). In which
8711      case, the resolution is over and decl is the answer */
8712   else if (JDECL_P (decl) && IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)) == decl)
8713     field_ref = decl;
8714   else if (JDECL_P (decl))
8715     {
8716       int static_final_found = 0;
8717       if (!type_found)
8718         type_found = DECL_CONTEXT (decl);
8719       is_static = JDECL_P (decl) && FIELD_STATIC (decl);
8720       if (FIELD_FINAL (decl) 
8721           && JPRIMITIVE_TYPE_P (TREE_TYPE (decl))
8722           && DECL_INITIAL (decl))
8723         {
8724           field_ref = java_complete_tree (DECL_INITIAL (decl));
8725           static_final_found = 1;
8726         }
8727       else
8728         field_ref = build_field_ref ((is_static && !flag_emit_xref? 
8729                                       NULL_TREE : where_found), 
8730                                      type_found, DECL_NAME (decl));
8731       if (field_ref == error_mark_node)
8732         return error_mark_node;
8733       if (is_static && !static_final_found 
8734           && !flag_emit_class_files && !flag_emit_xref)
8735         field_ref = build_class_init (DECL_CONTEXT (decl), field_ref);
8736     }
8737   else
8738     field_ref = decl;
8739
8740   if (field_decl)
8741     *field_decl = decl;
8742   if (field_type)
8743     *field_type = (QUAL_DECL_TYPE (decl) ? 
8744                    QUAL_DECL_TYPE (decl) : TREE_TYPE (decl));
8745   return field_ref;
8746 }
8747
8748 /* If NODE is an access to f static field, strip out the class
8749    initialization part and return the field decl, otherwise, return
8750    NODE. */
8751
8752 static tree
8753 strip_out_static_field_access_decl (node)
8754     tree node;
8755 {
8756   if (TREE_CODE (node) == COMPOUND_EXPR)
8757     {
8758       tree op1 = TREE_OPERAND (node, 1);
8759       if (TREE_CODE (op1) == COMPOUND_EXPR)
8760          {
8761            tree call = TREE_OPERAND (op1, 0);
8762            if (TREE_CODE (call) == CALL_EXPR
8763                && TREE_CODE (TREE_OPERAND (call, 0)) == ADDR_EXPR
8764                && TREE_OPERAND (TREE_OPERAND (call, 0), 0)
8765                == soft_initclass_node)
8766              return TREE_OPERAND (op1, 1);
8767          }
8768       else if (JDECL_P (op1))
8769         return op1;
8770     }
8771   return node;
8772 }
8773
8774 /* 6.5.5.2: Qualified Expression Names */
8775
8776 static int
8777 resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
8778      tree wfl;
8779      tree *found_decl, *type_found, *where_found;
8780 {
8781   int from_type = 0;            /* Field search initiated from a type */
8782   int from_super = 0, from_cast = 0, from_qualified_this = 0;
8783   int previous_call_static = 0;
8784   int is_static;
8785   tree decl = NULL_TREE, type = NULL_TREE, q;
8786   /* For certain for of inner class instantiation */
8787   tree saved_current, saved_this;               
8788 #define RESTORE_THIS_AND_CURRENT_CLASS                          \
8789   { current_class = saved_current; current_this = saved_this;}
8790
8791   *type_found = *where_found = NULL_TREE;
8792
8793   for (q = EXPR_WFL_QUALIFICATION (wfl); q; q = TREE_CHAIN (q))
8794     {
8795       tree qual_wfl = QUAL_WFL (q);
8796       tree ret_decl;            /* for EH checking */
8797       int location;             /* for EH checking */
8798
8799       /* 15.10.1 Field Access Using a Primary */
8800       switch (TREE_CODE (qual_wfl))
8801         {
8802         case CALL_EXPR:
8803         case NEW_CLASS_EXPR:
8804           /* If the access to the function call is a non static field,
8805              build the code to access it. */
8806           if (JDECL_P (decl) && !FIELD_STATIC (decl))
8807             {
8808               decl = maybe_access_field (decl, *where_found, 
8809                                          DECL_CONTEXT (decl));
8810               if (decl == error_mark_node)
8811                 return 1;
8812             }
8813
8814           /* And code for the function call */
8815           if (complete_function_arguments (qual_wfl))
8816             return 1;
8817
8818           /* We might have to setup a new current class and a new this
8819              for the search of an inner class, relative to the type of
8820              a expression resolved as `decl'. The current values are
8821              saved and restored shortly after */
8822           saved_current = current_class;
8823           saved_this = current_this;
8824           if (decl && TREE_CODE (qual_wfl) == NEW_CLASS_EXPR)
8825             {
8826               current_class = type;
8827               current_this = decl;
8828             }
8829
8830           if (from_super && TREE_CODE (qual_wfl) == CALL_EXPR)
8831             CALL_USING_SUPER (qual_wfl) = 1;
8832           location = (TREE_CODE (qual_wfl) == CALL_EXPR ?
8833                       EXPR_WFL_LINECOL (TREE_OPERAND (qual_wfl, 0)) : 0);
8834           *where_found = patch_method_invocation (qual_wfl, decl, type, 
8835                                                   &is_static, &ret_decl);
8836           if (*where_found == error_mark_node)
8837             {
8838               RESTORE_THIS_AND_CURRENT_CLASS;
8839               return 1;
8840             }
8841           *type_found = type = QUAL_DECL_TYPE (*where_found);
8842
8843           /* If we're creating an inner class instance, check for that
8844              an enclosing instance is in scope */
8845           if (TREE_CODE (qual_wfl) == NEW_CLASS_EXPR
8846               && INNER_ENCLOSING_SCOPE_CHECK (type))
8847             {
8848               parse_error_context 
8849                 (qual_wfl, "No enclosing instance for inner class `%s' is in scope%s",
8850                  lang_printable_name (type, 0),
8851                  (!current_this ? "" :
8852                   "; an explicit one must be provided when creating this inner class"));
8853               RESTORE_THIS_AND_CURRENT_CLASS;
8854               return 1;
8855             }
8856
8857           /* In case we had to change then to resolve a inner class
8858              instantiation using a primary qualified by a `new' */
8859           RESTORE_THIS_AND_CURRENT_CLASS;
8860
8861           /* EH check */
8862           if (location)
8863             check_thrown_exceptions (location, ret_decl);
8864
8865           /* If the previous call was static and this one is too,
8866              build a compound expression to hold the two (because in
8867              that case, previous function calls aren't transported as
8868              forcoming function's argument. */
8869           if (previous_call_static && is_static)
8870             {
8871               decl = build (COMPOUND_EXPR, type, decl, *where_found);
8872               TREE_SIDE_EFFECTS (decl) = 1;
8873             }
8874           else
8875             {
8876               previous_call_static = is_static;
8877               decl = *where_found;
8878             }
8879           from_type = 0;
8880           continue;
8881
8882         case NEW_ARRAY_EXPR:
8883         case NEW_ANONYMOUS_ARRAY_EXPR:
8884           *where_found = decl = java_complete_tree (qual_wfl);
8885           if (decl == error_mark_node)
8886             return 1;
8887           *type_found = type = QUAL_DECL_TYPE (decl);
8888           CLASS_LOADED_P (type) = 1;
8889           continue;
8890
8891         case CONVERT_EXPR:
8892           *where_found = decl = java_complete_tree (qual_wfl);
8893           if (decl == error_mark_node)
8894             return 1;
8895           *type_found = type = QUAL_DECL_TYPE (decl);
8896           from_cast = 1;
8897           continue;
8898
8899         case CONDITIONAL_EXPR:
8900         case STRING_CST:
8901         case MODIFY_EXPR:
8902           *where_found = decl = java_complete_tree (qual_wfl);
8903           if (decl == error_mark_node)
8904             return 1;
8905           *type_found = type = QUAL_DECL_TYPE (decl);
8906           continue;
8907
8908         case ARRAY_REF:
8909           /* If the access to the function call is a non static field,
8910              build the code to access it. */
8911           if (JDECL_P (decl) && !FIELD_STATIC (decl))
8912             {
8913               decl = maybe_access_field (decl, *where_found, type);
8914               if (decl == error_mark_node)
8915                 return 1;
8916             }
8917           /* And code for the array reference expression */
8918           decl = java_complete_tree (qual_wfl);
8919           if (decl == error_mark_node)
8920             return 1;
8921           type = QUAL_DECL_TYPE (decl);
8922           continue;
8923
8924         case PLUS_EXPR:
8925           if ((decl = java_complete_tree (qual_wfl)) == error_mark_node)
8926             return 1;
8927           if ((type = patch_string (decl)))
8928             decl = type;
8929           *where_found = QUAL_RESOLUTION (q) = decl;
8930           *type_found = type = TREE_TYPE (decl);
8931           break;
8932
8933         case CLASS_LITERAL:
8934           if ((decl = java_complete_tree (qual_wfl)) == error_mark_node)
8935             return 1;
8936           *where_found = QUAL_RESOLUTION (q) = decl;
8937           *type_found = type = TREE_TYPE (decl);
8938           break;
8939
8940         default:
8941           /* Fix for -Wall Just go to the next statement. Don't
8942              continue */
8943           break;
8944         }
8945
8946       /* If we fall here, we weren't processing a (static) function call. */
8947       previous_call_static = 0;
8948
8949       /* It can be the keyword THIS */
8950       if (EXPR_WFL_NODE (qual_wfl) == this_identifier_node)
8951         {
8952           if (!current_this)
8953             {
8954               parse_error_context 
8955                 (wfl, "Keyword `this' used outside allowed context");
8956               return 1;
8957             }
8958           if (ctxp->explicit_constructor_p)
8959             {
8960               parse_error_context (wfl, "Can't reference `this' before the superclass constructor has been called");
8961               return 1;
8962             }
8963           /* We have to generate code for intermediate acess */
8964           if (!from_type || TREE_TYPE (TREE_TYPE (current_this)) == type)
8965             {
8966               *where_found = decl = current_this;
8967               *type_found = type = QUAL_DECL_TYPE (decl);
8968             }
8969           /* We're trying to access the this from somewhere else... */
8970           else
8971             {
8972               *where_found = decl = build_current_thisn (type);
8973               from_qualified_this = 1;
8974             }
8975
8976           from_type = 0;
8977           continue;
8978         }
8979
8980       /* 15.10.2 Accessing Superclass Members using SUPER */
8981       if (EXPR_WFL_NODE (qual_wfl) == super_identifier_node)
8982         {
8983           tree node;
8984           /* Check on the restricted use of SUPER */
8985           if (METHOD_STATIC (current_function_decl)
8986               || current_class == object_type_node)
8987             {
8988               parse_error_context 
8989                 (wfl, "Keyword `super' used outside allowed context");
8990               return 1;
8991             }
8992           /* Otherwise, treat SUPER as (SUPER_CLASS)THIS */
8993           node = build_cast (EXPR_WFL_LINECOL (qual_wfl), 
8994                              CLASSTYPE_SUPER (current_class),
8995                              build_this (EXPR_WFL_LINECOL (qual_wfl)));
8996           *where_found = decl = java_complete_tree (node);
8997           if (decl == error_mark_node)
8998             return 1;
8999           *type_found = type = QUAL_DECL_TYPE (decl);
9000           from_super = from_type = 1;
9001           continue;
9002         }
9003
9004       /* 15.13.1: Can't search for field name in packages, so we
9005          assume a variable/class name was meant. */
9006       if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
9007         {
9008           tree name = resolve_package (wfl, &q);
9009           if (name)
9010             {
9011               tree list;
9012               *where_found = decl = resolve_no_layout (name, qual_wfl);
9013               /* We want to be absolutely sure that the class is laid
9014                  out. We're going to search something inside it. */
9015               *type_found = type = TREE_TYPE (decl);
9016               layout_class (type);
9017               from_type = 1;
9018
9019               /* Fix them all the way down, if any are left. */
9020               if (q)
9021                 {
9022                   list = TREE_CHAIN (q);
9023                   while (list)
9024                     {
9025                       RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (list)) = 1;
9026                       RESOLVE_PACKAGE_NAME_P (QUAL_WFL (list)) = 0;
9027                       list = TREE_CHAIN (list);
9028                     }
9029                 }
9030             }
9031           else
9032             {
9033               if (from_super || from_cast)
9034                 parse_error_context 
9035                   ((from_cast ? qual_wfl : wfl),
9036                    "No variable `%s' defined in class `%s'",
9037                    IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
9038                    lang_printable_name (type, 0));
9039               else
9040                 parse_error_context
9041                   (qual_wfl, "Undefined variable or class name: `%s'",
9042                    IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)));
9043               return 1;
9044             }
9045         }
9046
9047       /* We have a type name. It's been already resolved when the
9048          expression was qualified. */
9049       else if (RESOLVE_TYPE_NAME_P (qual_wfl))
9050         {
9051           if (!(decl = QUAL_RESOLUTION (q)))
9052             return 1;           /* Error reported already */
9053
9054           /* Sneak preview. If next we see a `new', we're facing a
9055              qualification with resulted in a type being selected
9056              instead of a field.  Report the error */
9057           if(TREE_CHAIN (q) 
9058              && TREE_CODE (TREE_PURPOSE (TREE_CHAIN (q))) == NEW_CLASS_EXPR)
9059             {
9060               parse_error_context (qual_wfl, "Undefined variable `%s'",
9061                                    IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
9062               return 1;
9063             }
9064
9065           if (not_accessible_p (TREE_TYPE (decl), decl, 0))
9066             {
9067               parse_error_context 
9068                 (qual_wfl, "Can't access %s field `%s.%s' from `%s'",
9069                  java_accstring_lookup (get_access_flags_from_decl (decl)),
9070                  GET_TYPE_NAME (type),
9071                  IDENTIFIER_POINTER (DECL_NAME (decl)),
9072                  IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
9073               return 1;
9074             }
9075           check_deprecation (qual_wfl, decl);
9076
9077           type = TREE_TYPE (decl);
9078           from_type = 1;
9079         }
9080       /* We resolve and expression name */
9081       else 
9082         {
9083           tree field_decl = NULL_TREE;
9084
9085           /* If there exists an early resolution, use it. That occurs
9086              only once and we know that there are more things to
9087              come. Don't do that when processing something after SUPER
9088              (we need more thing to be put in place below */
9089           if (!from_super && QUAL_RESOLUTION (q))
9090             {
9091               decl = QUAL_RESOLUTION (q);
9092               if (!type)
9093                 {
9094                   if (TREE_CODE (decl) == FIELD_DECL && !FIELD_STATIC (decl))
9095                     {
9096                       if (current_this)
9097                         *where_found = current_this;
9098                       else
9099                         {
9100                           static_ref_err (qual_wfl, DECL_NAME (decl),
9101                                           current_class);
9102                           return 1;
9103                         }
9104                     }
9105                   else
9106                     {
9107                       *where_found = TREE_TYPE (decl);
9108                       if (TREE_CODE (*where_found) == POINTER_TYPE)
9109                         *where_found = TREE_TYPE (*where_found);
9110                     }
9111                 }
9112             }
9113
9114           /* We have to search for a field, knowing the type of its
9115              container. The flag FROM_TYPE indicates that we resolved
9116              the last member of the expression as a type name, which
9117              means that for the resolution of this field, we'll look
9118              for other errors than if it was resolved as a member of
9119              an other field. */
9120           else
9121             {
9122               int is_static;
9123               tree field_decl_type; /* For layout */
9124
9125               if (!from_type && !JREFERENCE_TYPE_P (type))
9126                 {
9127                   parse_error_context 
9128                     (qual_wfl, "Attempt to reference field `%s' in `%s %s'",
9129                      IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
9130                      lang_printable_name (type, 0),
9131                      IDENTIFIER_POINTER (DECL_NAME (field_decl)));
9132                   return 1;
9133                 }
9134               
9135               field_decl = lookup_field_wrapper (type,
9136                                                  EXPR_WFL_NODE (qual_wfl));
9137               if (field_decl == NULL_TREE)
9138                 {
9139                   parse_error_context 
9140                     (qual_wfl, "No variable `%s' defined in type `%s'",
9141                      IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)), 
9142                      GET_TYPE_NAME (type));
9143                   return 1;
9144                 }
9145               if (field_decl == error_mark_node)
9146                 return 1;
9147
9148               /* Layout the type of field_decl, since we may need
9149                  it. Don't do primitive types or loaded classes. The
9150                  situation of non primitive arrays may not handled
9151                  properly here. FIXME */
9152               if (TREE_CODE (TREE_TYPE (field_decl)) == POINTER_TYPE)
9153                 field_decl_type = TREE_TYPE (TREE_TYPE (field_decl));
9154               else
9155                 field_decl_type = TREE_TYPE (field_decl);
9156               if (!JPRIMITIVE_TYPE_P (field_decl_type) 
9157                   && !CLASS_LOADED_P (field_decl_type)
9158                   && !TYPE_ARRAY_P (field_decl_type))
9159                 resolve_and_layout (field_decl_type, NULL_TREE);
9160               if (TYPE_ARRAY_P (field_decl_type))
9161                 CLASS_LOADED_P (field_decl_type) = 1;
9162               
9163               /* Check on accessibility here */
9164               if (not_accessible_p (type, field_decl, from_super))
9165                 {
9166                   parse_error_context 
9167                     (qual_wfl,
9168                      "Can't access %s field `%s.%s' from `%s'",
9169                      java_accstring_lookup 
9170                        (get_access_flags_from_decl (field_decl)),
9171                      GET_TYPE_NAME (type),
9172                      IDENTIFIER_POINTER (DECL_NAME (field_decl)),
9173                      IDENTIFIER_POINTER 
9174                        (DECL_NAME (TYPE_NAME (current_class))));
9175                   return 1;
9176                 }
9177               check_deprecation (qual_wfl, field_decl);
9178               
9179               /* There are things to check when fields are accessed
9180                  from type. There are no restrictions on a static
9181                  declaration of the field when it is accessed from an
9182                  interface */
9183               is_static = FIELD_STATIC (field_decl);
9184               if (!from_super && from_type 
9185                   && !TYPE_INTERFACE_P (type) 
9186                   && !is_static 
9187                   && (current_function_decl 
9188                       && METHOD_STATIC (current_function_decl)))
9189                 {
9190                   static_ref_err (qual_wfl, EXPR_WFL_NODE (qual_wfl), type);
9191                   return 1;
9192                 }
9193               from_cast = from_super = 0;
9194
9195               /* It's an access from a type but it isn't static, we
9196                  make it relative to `this'. */
9197               if (!is_static && from_type)
9198                 decl = current_this;
9199
9200               /* If we need to generate something to get a proper
9201                  handle on what this field is accessed from, do it
9202                  now. */
9203               if (!is_static)
9204                 {
9205                   decl = maybe_access_field (decl, *where_found, *type_found);
9206                   if (decl == error_mark_node)
9207                     return 1;
9208                 }
9209
9210               /* We want to keep the location were found it, and the type
9211                  we found. */
9212               *where_found = decl;
9213               *type_found = type;
9214
9215               /* Generate the correct expression for field access from
9216                  qualified this */
9217               if (from_qualified_this)
9218                 {
9219                   field_decl = build_outer_field_access (qual_wfl, field_decl);
9220                   from_qualified_this = 0;
9221                 }
9222
9223               /* This is the decl found and eventually the next one to
9224                  search from */
9225               decl = field_decl;
9226             }
9227           from_type = 0;
9228           type = QUAL_DECL_TYPE (decl);
9229
9230           /* Sneak preview. If decl is qualified by a `new', report
9231              the error here to be accurate on the peculiar construct */
9232           if (TREE_CHAIN (q) 
9233               && TREE_CODE (TREE_PURPOSE (TREE_CHAIN (q))) == NEW_CLASS_EXPR
9234               && !JREFERENCE_TYPE_P (type))
9235             {
9236               parse_error_context (qual_wfl, "Attempt to reference field `new' in a `%s'", 
9237                                    lang_printable_name (type, 0));
9238               return 1;
9239             }
9240         }
9241       /* `q' might have changed due to a after package resolution
9242          re-qualification */
9243       if (!q)
9244         break;
9245     }
9246   *found_decl = decl;
9247   return 0;
9248 }
9249
9250 /* 6.6 Qualified name and access control. Returns 1 if MEMBER (a decl)
9251    can't be accessed from REFERENCE (a record type). */
9252
9253 static int
9254 not_accessible_p (reference, member, from_super)
9255      tree reference, member;
9256      int from_super;
9257 {
9258   int access_flag = get_access_flags_from_decl (member);
9259
9260   /* Access always granted for members declared public */
9261   if (access_flag & ACC_PUBLIC)
9262     return 0;
9263   
9264   /* Check access on protected members */
9265   if (access_flag & ACC_PROTECTED)
9266     {
9267       /* Access granted if it occurs from within the package
9268          containing the class in which the protected member is
9269          declared */
9270       if (class_in_current_package (DECL_CONTEXT (member)))
9271         return 0;
9272
9273       /* If accessed with the form `super.member', then access is granted */
9274       if (from_super)
9275         return 0;
9276
9277       /* Otherwise, access is granted if occuring from the class where
9278          member is declared or a subclass of it */
9279       if (inherits_from_p (reference, DECL_CONTEXT (member)))
9280         return 0;
9281       return 1;
9282     }
9283
9284   /* Check access on private members. Access is granted only if it
9285      occurs from within the class in which it is declared. Exceptions
9286      are accesses from inner-classes. This section is probably not
9287      complete. FIXME */
9288   if (access_flag & ACC_PRIVATE)
9289     return (current_class == DECL_CONTEXT (member) ? 0 : 
9290             (INNER_CLASS_TYPE_P (current_class) ? 0 : 1));
9291
9292   /* Default access are permitted only when occuring within the
9293      package in which the type (REFERENCE) is declared. In other words,
9294      REFERENCE is defined in the current package */
9295   if (ctxp->package)
9296     return !class_in_current_package (reference);
9297
9298   /* Otherwise, access is granted */
9299   return 0;
9300 }
9301
9302 /* Test deprecated decl access.  */
9303 static void
9304 check_deprecation (wfl, decl)
9305      tree wfl, decl;
9306 {
9307   const char *file = DECL_SOURCE_FILE (decl);
9308   /* Complain if the field is deprecated and the file it was defined
9309      in isn't compiled at the same time the file which contains its
9310      use is */
9311   if (DECL_DEPRECATED (decl) 
9312       && !IS_A_COMMAND_LINE_FILENAME_P (get_identifier (file)))
9313     {
9314       char the [20];
9315       switch (TREE_CODE (decl))
9316         {
9317         case FUNCTION_DECL:
9318           strcpy (the, "method");
9319           break;
9320         case FIELD_DECL:
9321           strcpy (the, "field");
9322           break;
9323         case TYPE_DECL:
9324           strcpy (the, "class");
9325           break;
9326         default:
9327           fatal ("unexpected DECL code - check_deprecation");
9328         }
9329       parse_warning_context 
9330         (wfl, "The %s `%s' in class `%s' has been deprecated", 
9331          the, lang_printable_name (decl, 0),
9332          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)))));
9333     }
9334 }
9335
9336 /* Returns 1 if class was declared in the current package, 0 otherwise */
9337
9338 static int
9339 class_in_current_package (class)
9340      tree class;
9341 {
9342   static tree cache = NULL_TREE;
9343   int qualified_flag;
9344   tree left;
9345
9346   if (cache == class)
9347     return 1;
9348
9349   qualified_flag = QUALIFIED_P (DECL_NAME (TYPE_NAME (class)));
9350
9351   /* If the current package is empty and the name of CLASS is
9352      qualified, class isn't in the current package.  If there is a
9353      current package and the name of the CLASS is not qualified, class
9354      isn't in the current package */
9355   if ((!ctxp->package && qualified_flag) || (ctxp->package && !qualified_flag))
9356     return 0;
9357
9358   /* If there is not package and the name of CLASS isn't qualified,
9359      they belong to the same unnamed package */
9360   if (!ctxp->package && !qualified_flag)
9361     return 1;
9362
9363   /* Compare the left part of the name of CLASS with the package name */
9364   breakdown_qualified (&left, NULL, DECL_NAME (TYPE_NAME (class)));
9365   if (ctxp->package == left)
9366     {
9367       cache = class;
9368       return 1;
9369     }
9370   return 0;
9371 }
9372
9373 /* This function may generate code to access DECL from WHERE. This is
9374    done only if certain conditions meet.  */
9375
9376 static tree
9377 maybe_access_field (decl, where, type)
9378   tree decl, where, type;
9379 {
9380   if (TREE_CODE (decl) == FIELD_DECL && decl != current_this
9381       && !FIELD_STATIC (decl))
9382     decl = build_field_ref (where ? where : current_this, 
9383                             (type ? type : DECL_CONTEXT (decl)),
9384                             DECL_NAME (decl));
9385   return decl;
9386 }
9387
9388 /* Build a method invocation, by patching PATCH. If non NULL
9389    and according to the situation, PRIMARY and WHERE may be
9390    used. IS_STATIC is set to 1 if the invoked function is static. */
9391
9392 static tree
9393 patch_method_invocation (patch, primary, where, is_static, ret_decl)
9394      tree patch, primary, where;
9395      int *is_static;
9396      tree *ret_decl;
9397 {
9398   tree wfl = TREE_OPERAND (patch, 0);
9399   tree args = TREE_OPERAND (patch, 1);
9400   tree name = EXPR_WFL_NODE (wfl);
9401   tree list;
9402   int is_static_flag = 0;
9403   int is_super_init = 0;
9404   tree this_arg = NULL_TREE;
9405   
9406   /* Should be overriden if everything goes well. Otherwise, if
9407      something fails, it should keep this value. It stop the
9408      evaluation of a bogus assignment. See java_complete_tree,
9409      MODIFY_EXPR: for the reasons why we sometimes want to keep on
9410      evaluating an assignment */
9411   TREE_TYPE (patch) = error_mark_node;
9412
9413   /* Since lookup functions are messing with line numbers, save the
9414      context now.  */
9415   java_parser_context_save_global ();
9416
9417   /* 15.11.1: Compile-Time Step 1: Determine Class or Interface to Search */
9418
9419   /* Resolution of qualified name, excluding constructors */
9420   if (QUALIFIED_P (name) && !CALL_CONSTRUCTOR_P (patch))
9421     {
9422       tree identifier, identifier_wfl, type, resolved;
9423       /* Extract the last IDENTIFIER of the qualified
9424          expression. This is a wfl and we will use it's location
9425          data during error report. */
9426       identifier_wfl = cut_identifier_in_qualified (wfl);
9427       identifier = EXPR_WFL_NODE (identifier_wfl);
9428       
9429       /* Given the context, IDENTIFIER is syntactically qualified
9430          as a MethodName. We need to qualify what's before */
9431       qualify_ambiguous_name (wfl);
9432       resolved = resolve_field_access (wfl, NULL, NULL);
9433
9434       if (resolved == error_mark_node)
9435         PATCH_METHOD_RETURN_ERROR ();
9436
9437       type = GET_SKIP_TYPE (resolved);
9438       resolve_and_layout (type, NULL_TREE);
9439       
9440       if (JPRIMITIVE_TYPE_P (type))
9441         {
9442         parse_error_context
9443           (identifier_wfl,
9444           "Can't invoke a method on primitive type `%s'",
9445           IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
9446         PATCH_METHOD_RETURN_ERROR ();         
9447       }      
9448       
9449       list = lookup_method_invoke (0, identifier_wfl, type, identifier, args);
9450       args = nreverse (args);
9451
9452       /* We're resolving a call from a type */
9453       if (TREE_CODE (resolved) == TYPE_DECL)
9454         {
9455           if (CLASS_INTERFACE (resolved))
9456             {
9457               parse_error_context
9458                 (identifier_wfl,
9459                 "Can't make static reference to method `%s' in interface `%s'",
9460                  IDENTIFIER_POINTER (identifier), 
9461                  IDENTIFIER_POINTER (name));
9462               PATCH_METHOD_RETURN_ERROR ();
9463             }
9464           if (list && !METHOD_STATIC (list))
9465             {
9466               char *fct_name = xstrdup (lang_printable_name (list, 0));
9467               parse_error_context 
9468                 (identifier_wfl,
9469                  "Can't make static reference to method `%s %s' in class `%s'",
9470                  lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0), 
9471                  fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
9472               free (fct_name);
9473               PATCH_METHOD_RETURN_ERROR ();
9474             }
9475         }
9476       else
9477         this_arg = primary = resolved;
9478       
9479       /* IDENTIFIER_WFL will be used to report any problem further */
9480       wfl = identifier_wfl;
9481     }
9482   /* Resolution of simple names, names generated after a primary: or
9483      constructors */
9484   else
9485     {
9486       tree class_to_search = NULL_TREE;
9487       int lc;                   /* Looking for Constructor */
9488       
9489       /* We search constructor in their target class */
9490       if (CALL_CONSTRUCTOR_P (patch))
9491         {
9492           if (TREE_CODE (patch) == NEW_CLASS_EXPR)
9493             class_to_search = EXPR_WFL_NODE (wfl);
9494           else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) == 
9495                    this_identifier_node)
9496             class_to_search = NULL_TREE;
9497           else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) ==
9498                    super_identifier_node)
9499             {
9500               is_super_init = 1;
9501               if (CLASSTYPE_SUPER (current_class))
9502                 class_to_search = 
9503                   DECL_NAME (TYPE_NAME (CLASSTYPE_SUPER (current_class)));
9504               else
9505                 {
9506                   parse_error_context (wfl, "Can't invoke super constructor on java.lang.Object");
9507                   PATCH_METHOD_RETURN_ERROR ();
9508                 }
9509             }
9510
9511           /* Class to search is NULL if we're searching the current one */
9512           if (class_to_search)
9513             {
9514               class_to_search = resolve_and_layout (class_to_search, wfl);
9515
9516               if (!class_to_search)
9517                 {
9518                   parse_error_context 
9519                     (wfl, "Class `%s' not found in type declaration",
9520                      IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
9521                   PATCH_METHOD_RETURN_ERROR ();
9522                 }
9523               
9524               /* Can't instantiate an abstract class, but we can
9525                  invoke it's constructor. It's use within the `new'
9526                  context is denied here. */
9527               if (CLASS_ABSTRACT (class_to_search) 
9528                   && TREE_CODE (patch) == NEW_CLASS_EXPR)
9529                 {
9530                   parse_error_context 
9531                     (wfl, "Class `%s' is an abstract class. It can't be instantiated",
9532                      IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
9533                   PATCH_METHOD_RETURN_ERROR ();
9534                 }
9535
9536               class_to_search = TREE_TYPE (class_to_search);
9537             }
9538           else
9539             class_to_search = current_class;
9540           lc = 1;
9541         }
9542       /* This is a regular search in the local class, unless an
9543          alternate class is specified. */
9544       else
9545         {
9546           class_to_search = (where ? where : current_class);
9547           lc = 0;
9548         }
9549
9550       /* NAME is a simple identifier or comes from a primary. Search
9551          in the class whose declaration contain the method being
9552          invoked. */
9553       resolve_and_layout (class_to_search, NULL_TREE);
9554
9555       list = lookup_method_invoke (lc, wfl, class_to_search, name, args);
9556       /* Don't continue if no method were found, as the next statement
9557          can't be executed then. */
9558       if (!list)
9559         PATCH_METHOD_RETURN_ERROR ();
9560
9561       /* Check for static reference if non static methods */
9562       if (check_for_static_method_reference (wfl, patch, list, 
9563                                              class_to_search, primary))
9564         PATCH_METHOD_RETURN_ERROR ();
9565
9566       /* Check for inner classes creation from illegal contexts */
9567       if (lc && (INNER_CLASS_TYPE_P (class_to_search)
9568                  && !CLASS_STATIC (TYPE_NAME (class_to_search)))
9569           && INNER_ENCLOSING_SCOPE_CHECK (class_to_search))
9570         {
9571           parse_error_context 
9572             (wfl, "No enclosing instance for inner class `%s' is in scope%s",
9573              lang_printable_name (class_to_search, 0),
9574              (!current_this ? "" :
9575               "; an explicit one must be provided when creating this inner class"));
9576           PATCH_METHOD_RETURN_ERROR ();
9577         }
9578
9579       /* Non static methods are called with the current object extra
9580          argument. If patch a `new TYPE()', the argument is the value
9581          returned by the object allocator. If method is resolved as a
9582          primary, use the primary otherwise use the current THIS. */
9583       args = nreverse (args);
9584       if (TREE_CODE (patch) != NEW_CLASS_EXPR)
9585         {
9586           this_arg = primary ? primary : current_this;
9587
9588           /* If we're using an access method, things are different.
9589              There are two familly of cases:
9590
9591              1) We're not generating bytecodes:
9592
9593              - LIST is non static. It's invocation is transformed from
9594                x(a1,...,an) into this$<n>.x(a1,....an).
9595              - LIST is static. It's invocation is transformed from
9596                x(a1,...,an) into TYPE_OF(this$<n>).x(a1,....an)
9597
9598              2) We're generating bytecodes:
9599              
9600              - LIST is non static. It's invocation is transformed from
9601                x(a1,....,an) into access$<n>(this$<n>,a1,...,an).
9602              - LIST is static. It's invocation is transformed from
9603                x(a1,....,an) into TYPEOF(this$<n>).x(a1,....an).
9604
9605              Of course, this$<n> can be abitrary complex, ranging from
9606              this$0 (the immediate outer context) to 
9607              access$0(access$0(...(this$0))). 
9608              
9609              maybe_use_access_method returns a non zero value if the
9610              this_arg has to be moved into the (then generated) stub
9611              argument list. In the mean time, the selected function
9612              might have be replaced by a generated stub. */
9613           if (maybe_use_access_method (is_super_init, &list, &this_arg))
9614             args = tree_cons (NULL_TREE, this_arg, args);
9615         }
9616     }
9617
9618   /* Merge point of all resolution schemes. If we have nothing, this
9619      is an error, already signaled */
9620   if (!list) 
9621     PATCH_METHOD_RETURN_ERROR ();
9622
9623   /* Check accessibility, position the is_static flag, build and
9624      return the call */
9625   if (not_accessible_p (DECL_CONTEXT (current_function_decl), list, 0))
9626     {
9627       char *fct_name = xstrdup (lang_printable_name (list, 0));
9628       parse_error_context 
9629         (wfl, "Can't access %s method `%s %s.%s' from `%s'",
9630          java_accstring_lookup (get_access_flags_from_decl (list)),
9631          lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0), 
9632          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (list)))), 
9633          fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
9634       free (fct_name);
9635       PATCH_METHOD_RETURN_ERROR ();
9636     }
9637   check_deprecation (wfl, list);
9638
9639   /* If invoking a innerclass constructor, there are hidden parameters
9640      to pass */
9641   if (TREE_CODE (patch) == NEW_CLASS_EXPR 
9642       && PURE_INNER_CLASS_TYPE_P (DECL_CONTEXT (list)))
9643     {
9644       /* And make sure we add the accessed local variables to be saved
9645          in field aliases. */
9646       args = build_alias_initializer_parameter_list
9647         (AIPL_FUNCTION_CTOR_INVOCATION, DECL_CONTEXT (list), args, NULL);
9648
9649       /* We have to reverse things. Find out why. FIXME */
9650       if (ANONYMOUS_CLASS_P (DECL_CONTEXT (list)))
9651         args = nreverse (args);
9652       
9653       /* Secretely pass the current_this/primary as a second argument */
9654       if (primary || current_this)
9655         args = tree_cons (NULL_TREE, (primary ? primary : current_this), args);
9656       else
9657         args = tree_cons (NULL_TREE, integer_zero_node, args);
9658     }
9659
9660   /* This handles the situation where a constructor invocation needs
9661      to have an enclosing context passed as a second parameter (the
9662      constructor is one of an inner class. We extract it from the
9663      current function.  */
9664   if (is_super_init && PURE_INNER_CLASS_TYPE_P (DECL_CONTEXT (list)))
9665     {
9666       tree enclosing_decl = DECL_CONTEXT (TYPE_NAME (current_class));
9667       tree extra_arg;
9668
9669       if (ANONYMOUS_CLASS_P (current_class) || !DECL_CONTEXT (enclosing_decl))
9670         {
9671           extra_arg = DECL_FUNCTION_BODY (current_function_decl);
9672           extra_arg = TREE_CHAIN (BLOCK_EXPR_DECLS (extra_arg));
9673         }
9674       else
9675         {
9676           tree dest = TREE_TYPE (DECL_CONTEXT (enclosing_decl));
9677           extra_arg = 
9678             build_access_to_thisn (TREE_TYPE (enclosing_decl), dest, 0);
9679           extra_arg = java_complete_tree (extra_arg);
9680         }
9681       args = tree_cons (NULL_TREE, extra_arg, args);
9682     }
9683
9684   is_static_flag = METHOD_STATIC (list);
9685   if (! METHOD_STATIC (list) && this_arg != NULL_TREE)
9686     args = tree_cons (NULL_TREE, this_arg, args);
9687
9688   /* In the context of an explicit constructor invocation, we can't
9689      invoke any method relying on `this'. Exceptions are: we're
9690      invoking a static function, primary exists and is not the current
9691      this, we're creating a new object. */
9692   if (ctxp->explicit_constructor_p 
9693       && !is_static_flag 
9694       && (!primary || primary == current_this)
9695       && (TREE_CODE (patch) != NEW_CLASS_EXPR))
9696     {
9697       parse_error_context (wfl, "Can't reference `this' before the superclass constructor has been called");
9698       PATCH_METHOD_RETURN_ERROR ();
9699     }
9700   java_parser_context_restore_global ();
9701   if (is_static) 
9702     *is_static = is_static_flag;
9703   /* Sometimes, we want the decl of the selected method. Such as for
9704      EH checking */
9705   if (ret_decl)
9706     *ret_decl = list;
9707   patch = patch_invoke (patch, list, args);
9708   if (is_super_init && CLASS_HAS_FINIT_P (current_class))
9709     {
9710       tree finit_parms, finit_call;
9711       
9712       /* Prepare to pass hidden parameters to $finit$, if any. */
9713       finit_parms = build_alias_initializer_parameter_list 
9714         (AIPL_FUNCTION_FINIT_INVOCATION, current_class, NULL_TREE, NULL);
9715
9716       finit_call = 
9717         build_method_invocation (build_wfl_node (finit_identifier_node),
9718                                  finit_parms);
9719
9720       /* Generate the code used to initialize fields declared with an
9721          initialization statement and build a compound statement along
9722          with the super constructor invocation. */
9723       patch = build (COMPOUND_EXPR, void_type_node, patch,
9724                      java_complete_tree (finit_call));
9725       CAN_COMPLETE_NORMALLY (patch) = 1;
9726     }
9727   return patch;
9728 }
9729
9730 /* Check that we're not trying to do a static reference to a method in
9731    non static method. Return 1 if it's the case, 0 otherwise. */
9732
9733 static int
9734 check_for_static_method_reference (wfl, node, method, where, primary)
9735      tree wfl, node, method, where, primary;
9736 {
9737   if (METHOD_STATIC (current_function_decl) 
9738       && !METHOD_STATIC (method) && !primary && !CALL_CONSTRUCTOR_P (node))
9739     {
9740       char *fct_name = xstrdup (lang_printable_name (method, 0));
9741       parse_error_context 
9742         (wfl, "Can't make static reference to method `%s %s' in class `%s'", 
9743          lang_printable_name (TREE_TYPE (TREE_TYPE (method)), 0), fct_name,
9744          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (where))));
9745       free (fct_name);
9746       return 1;
9747     }
9748   return 0;
9749 }
9750
9751 /* Fix the invocation of *MDECL if necessary in the case of a
9752    invocation from an inner class. *THIS_ARG might be modified
9753    appropriately and an alternative access to *MDECL might be
9754    returned.  */
9755
9756 static int
9757 maybe_use_access_method (is_super_init, mdecl, this_arg)
9758      int is_super_init;
9759      tree *mdecl, *this_arg;
9760 {
9761   tree ctx;
9762   tree md = *mdecl, ta = *this_arg;
9763   int to_return = 0;
9764   int non_static_context = !METHOD_STATIC (md);
9765
9766   if (is_super_init 
9767       || DECL_CONTEXT (md) == current_class
9768       || !PURE_INNER_CLASS_TYPE_P (current_class) 
9769       || DECL_FINIT_P (md))
9770     return 0;
9771   
9772   /* If we're calling a method found in an enclosing class, generate
9773      what it takes to retrieve the right this. Don't do that if we're
9774      invoking a static method. */
9775
9776   if (non_static_context)
9777     {
9778       ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class)));
9779       if (ctx == DECL_CONTEXT (md))
9780         {
9781           ta = build_current_thisn (current_class);
9782           ta = build_wfl_node (ta);
9783         }
9784       else
9785         {
9786           tree type = ctx;
9787           while (type)
9788             {
9789               maybe_build_thisn_access_method (type);
9790               if (type == DECL_CONTEXT (md))
9791                 {
9792                   ta = build_access_to_thisn (ctx, type, 0);
9793                   break;
9794                 }
9795               type = (DECL_CONTEXT (TYPE_NAME (type)) ? 
9796                       TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))) : NULL_TREE);
9797             }
9798         }
9799       ta = java_complete_tree (ta);
9800     }
9801
9802   /* We might have to use an access method to get to MD. We can
9803      break the method access rule as far as we're not generating
9804      bytecode */
9805   if (METHOD_PRIVATE (md) && flag_emit_class_files)
9806     {
9807       md = build_outer_method_access_method (md);
9808       to_return = 1;
9809     }
9810
9811   *mdecl = md;
9812   *this_arg = ta;
9813
9814   /* Returnin a non zero value indicates we were doing a non static
9815      method invokation that is now a static invocation. It will have
9816      callee displace `this' to insert it in the regular argument
9817      list. */
9818   return (non_static_context && to_return);
9819 }
9820
9821 /* Patch an invoke expression METHOD and ARGS, based on its invocation
9822    mode.  */
9823
9824 static tree
9825 patch_invoke (patch, method, args)
9826      tree patch, method, args;
9827 {
9828   tree dtable, func;
9829   tree original_call, t, ta;
9830   tree cond = NULL_TREE;
9831
9832   /* Last step for args: convert build-in types. If we're dealing with
9833      a new TYPE() type call, the first argument to the constructor
9834      isn't found in the incoming argument list, but delivered by
9835      `new' */
9836   t = TYPE_ARG_TYPES (TREE_TYPE (method));
9837   if (TREE_CODE (patch) == NEW_CLASS_EXPR)
9838     t = TREE_CHAIN (t);
9839   for (ta = args; t != end_params_node && ta; 
9840        t = TREE_CHAIN (t), ta = TREE_CHAIN (ta))
9841     if (JPRIMITIVE_TYPE_P (TREE_TYPE (TREE_VALUE (ta))) &&
9842         TREE_TYPE (TREE_VALUE (ta)) != TREE_VALUE (t))
9843       TREE_VALUE (ta) = convert (TREE_VALUE (t), TREE_VALUE (ta));
9844
9845   /* Resolve unresolved returned type isses */
9846   t = TREE_TYPE (TREE_TYPE (method));
9847   if (TREE_CODE (t) == POINTER_TYPE && !CLASS_LOADED_P (TREE_TYPE (t)))
9848     resolve_and_layout (TREE_TYPE (t), NULL);
9849
9850   if (flag_emit_class_files || flag_emit_xref)
9851     func = method;
9852   else
9853     {
9854       tree signature = build_java_signature (TREE_TYPE (method));
9855       switch (invocation_mode (method, CALL_USING_SUPER (patch)))
9856         {
9857         case INVOKE_VIRTUAL:
9858           dtable = invoke_build_dtable (0, args);
9859           func = build_invokevirtual (dtable, method);
9860           break;
9861
9862         case INVOKE_NONVIRTUAL:
9863           /* If the object for the method call is null, we throw an
9864              exception.  We don't do this if the object is the current
9865              method's `this'.  In other cases we just rely on an
9866              optimization pass to eliminate redundant checks.  */
9867           if (TREE_VALUE (args) != current_this)
9868             {
9869               /* We use a SAVE_EXPR here to make sure we only evaluate
9870                  the new `self' expression once.  */
9871               tree save_arg = save_expr (TREE_VALUE (args));
9872               TREE_VALUE (args) = save_arg;
9873               cond = build (EQ_EXPR, boolean_type_node, save_arg,
9874                             null_pointer_node);
9875             }
9876           /* Fall through.  */
9877
9878         case INVOKE_SUPER:
9879         case INVOKE_STATIC:
9880           func = build_known_method_ref (method, TREE_TYPE (method),
9881                                          DECL_CONTEXT (method),
9882                                          signature, args);
9883           break;
9884
9885         case INVOKE_INTERFACE:
9886           dtable = invoke_build_dtable (1, args);
9887           func = build_invokeinterface (dtable, method);
9888           break;
9889
9890         default:
9891           fatal ("internal error - unknown invocation_mode result");
9892         }
9893
9894       /* Ensure self_type is initialized, (invokestatic). FIXME */
9895       func = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (method)), func);
9896     }
9897
9898   TREE_TYPE (patch) = TREE_TYPE (TREE_TYPE (method));
9899   TREE_OPERAND (patch, 0) = func;
9900   TREE_OPERAND (patch, 1) = args;
9901   original_call = patch;
9902
9903   /* We're processing a `new TYPE ()' form. New is called and its
9904      returned value is the first argument to the constructor. We build
9905      a COMPOUND_EXPR and use saved expression so that the overall NEW
9906      expression value is a pointer to a newly created and initialized
9907      class. */
9908   if (TREE_CODE (original_call) == NEW_CLASS_EXPR)
9909     {
9910       tree class = DECL_CONTEXT (method);
9911       tree c1, saved_new, size, new;
9912       if (flag_emit_class_files || flag_emit_xref)
9913         {
9914           TREE_TYPE (patch) = build_pointer_type (class);
9915           return patch;
9916         }
9917       if (!TYPE_SIZE (class))
9918         safe_layout_class (class);
9919       size = size_in_bytes (class);
9920       new = build (CALL_EXPR, promote_type (class),
9921                    build_address_of (alloc_object_node),
9922                    tree_cons (NULL_TREE, build_class_ref (class),
9923                               build_tree_list (NULL_TREE, 
9924                                                size_in_bytes (class))),
9925                    NULL_TREE);
9926       saved_new = save_expr (new);
9927       c1 = build_tree_list (NULL_TREE, saved_new);
9928       TREE_CHAIN (c1) = TREE_OPERAND (original_call, 1);
9929       TREE_OPERAND (original_call, 1) = c1;
9930       TREE_SET_CODE (original_call, CALL_EXPR);
9931       patch = build (COMPOUND_EXPR, TREE_TYPE (new), patch, saved_new);
9932     }
9933
9934   /* If COND is set, then we are building a check to see if the object
9935      is NULL.  */
9936   if (cond != NULL_TREE)
9937     {
9938       /* We have to make the `then' branch a compound expression to
9939          make the types turn out right.  This seems bizarre.  */
9940       patch = build (COND_EXPR, TREE_TYPE (patch), cond,
9941                      build (COMPOUND_EXPR, TREE_TYPE (patch),
9942                             build (CALL_EXPR, void_type_node,
9943                                    build_address_of (soft_nullpointer_node),
9944                                    NULL_TREE, NULL_TREE),
9945                             (FLOAT_TYPE_P (TREE_TYPE (patch))
9946                              ? build_real (TREE_TYPE (patch), dconst0)
9947                              : build1 (CONVERT_EXPR, TREE_TYPE (patch),
9948                                        integer_zero_node))),
9949                      patch);
9950       TREE_SIDE_EFFECTS (patch) = 1;
9951     }
9952
9953   return patch;
9954 }
9955
9956 static int
9957 invocation_mode (method, super)
9958      tree method;
9959      int super;
9960 {
9961   int access = get_access_flags_from_decl (method);
9962
9963   if (super)
9964     return INVOKE_SUPER;
9965
9966   if (access & ACC_STATIC)
9967     return INVOKE_STATIC;
9968
9969   /* We have to look for a constructor before we handle nonvirtual
9970      calls; otherwise the constructor will look nonvirtual.  */
9971   if (DECL_CONSTRUCTOR_P (method))
9972     return INVOKE_STATIC;
9973
9974   if (access & ACC_FINAL || access & ACC_PRIVATE)
9975     return INVOKE_NONVIRTUAL;
9976
9977   if (CLASS_FINAL (TYPE_NAME (DECL_CONTEXT (method))))
9978     return INVOKE_NONVIRTUAL;
9979
9980   if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))))
9981     return INVOKE_INTERFACE;
9982
9983   return INVOKE_VIRTUAL;
9984 }
9985
9986 /* Retrieve a refined list of matching methods. It covers the step
9987    15.11.2 (Compile-Time Step 2) */
9988
9989 static tree
9990 lookup_method_invoke (lc, cl, class, name, arg_list)
9991      int lc;
9992      tree cl;
9993      tree class, name, arg_list;
9994 {
9995   tree atl = end_params_node;           /* Arg Type List */
9996   tree method, signature, list, node;
9997   const char *candidates;               /* Used for error report */
9998   char *dup;
9999
10000   /* Fix the arguments */
10001   for (node = arg_list; node; node = TREE_CHAIN (node))
10002     {
10003       tree current_arg = TREE_TYPE (TREE_VALUE (node));
10004       /* Non primitive type may have to be resolved */
10005       if (!JPRIMITIVE_TYPE_P (current_arg))
10006         resolve_and_layout (current_arg, NULL_TREE);
10007       /* And promoted */
10008       if (TREE_CODE (current_arg) == RECORD_TYPE)
10009         current_arg = promote_type (current_arg);
10010       atl = tree_cons (NULL_TREE, current_arg, atl);
10011     }
10012
10013   /* Presto. If we're dealing with an anonymous class and a
10014      constructor call, generate the right constructor now, since we
10015      know the arguments' types. */
10016
10017   if (lc && ANONYMOUS_CLASS_P (class))
10018     craft_constructor (TYPE_NAME (class), atl);
10019
10020   /* Find all candidates and then refine the list, searching for the
10021      most specific method. */
10022   list = find_applicable_accessible_methods_list (lc, class, name, atl);
10023   list = find_most_specific_methods_list (list);
10024   if (list && !TREE_CHAIN (list))
10025     return TREE_VALUE (list);
10026
10027   /* Issue an error. List candidates if any. Candidates are listed
10028      only if accessible (non accessible methods may end-up here for
10029      the sake of a better error report). */
10030   candidates = NULL;
10031   if (list)
10032     {
10033       tree current;
10034       obstack_grow (&temporary_obstack, ". Candidates are:\n", 18);
10035       for (current = list; current; current = TREE_CHAIN (current))
10036         {
10037           tree cm = TREE_VALUE (current);
10038           char string [4096];
10039           if (!cm || not_accessible_p (class, cm, 0))
10040             continue;
10041           sprintf 
10042             (string, "  `%s' in `%s'%s",
10043              get_printable_method_name (cm),
10044              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (cm)))),
10045              (TREE_CHAIN (current) ? "\n" : ""));
10046           obstack_grow (&temporary_obstack, string, strlen (string));
10047         }
10048       obstack_1grow (&temporary_obstack, '\0');
10049       candidates = obstack_finish (&temporary_obstack);
10050     }
10051   /* Issue the error message */
10052   method = make_node (FUNCTION_TYPE);
10053   TYPE_ARG_TYPES (method) = atl;
10054   signature = build_java_argument_signature (method);
10055   dup = xstrdup (lang_printable_name (class, 0));
10056   parse_error_context (cl, "Can't find %s `%s(%s)' in type `%s'%s",
10057                        (lc ? "constructor" : "method"),
10058                        (lc ? dup : IDENTIFIER_POINTER (name)),
10059                        IDENTIFIER_POINTER (signature), dup,
10060                        (candidates ? candidates : ""));
10061   free (dup);
10062   return NULL_TREE;
10063 }
10064
10065 /* 15.11.2.1: Find Methods that are Applicable and Accessible. LC is 1
10066    when we're looking for a constructor. */
10067
10068 static tree
10069 find_applicable_accessible_methods_list (lc, class, name, arglist)
10070      int lc;
10071      tree class, name, arglist;
10072 {
10073   static int object_done = 0;
10074   tree list = NULL_TREE, all_list = NULL_TREE;
10075
10076   if (!CLASS_LOADED_P (class) && !CLASS_FROM_SOURCE_P (class))
10077     {
10078       load_class (class, 1);
10079       safe_layout_class (class);
10080     }
10081
10082   /* Search interfaces */
10083   if (TREE_CODE (TYPE_NAME (class)) == TYPE_DECL 
10084       && CLASS_INTERFACE (TYPE_NAME (class)))
10085     {
10086       static struct hash_table t, *searched_interfaces = NULL;
10087       static int search_not_done = 0;
10088       int i, n;
10089       tree basetype_vec = TYPE_BINFO_BASETYPES (class);
10090
10091       /* Search in the hash table, otherwise create a new one if
10092          necessary and insert the new entry. */
10093
10094       if (searched_interfaces)
10095         {
10096           if (hash_lookup (searched_interfaces, 
10097                            (const hash_table_key) class, FALSE, NULL))
10098             return NULL;
10099         }
10100       else
10101         {
10102           hash_table_init (&t, hash_newfunc, java_hash_hash_tree_node,
10103                            java_hash_compare_tree_node);
10104           searched_interfaces = &t;
10105         }
10106
10107       hash_lookup (searched_interfaces, 
10108                    (const hash_table_key) class, TRUE, NULL);
10109
10110       search_applicable_methods_list (lc, TYPE_METHODS (class), 
10111                                       name, arglist, &list, &all_list);
10112       n = TREE_VEC_LENGTH (basetype_vec);
10113       for (i = 1; i < n; i++)
10114         {
10115           tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
10116           tree rlist;
10117
10118           search_not_done++;
10119           rlist = find_applicable_accessible_methods_list (lc,  t, name, 
10120                                                            arglist);
10121           list = chainon (rlist, list);
10122           search_not_done--;
10123         }
10124
10125       /* We're done. Reset the searched interfaces list and finally search
10126          java.lang.Object */
10127       if (!search_not_done)
10128         {  
10129           if (!object_done)
10130             search_applicable_methods_list (lc, 
10131                                             TYPE_METHODS (object_type_node),
10132                                             name, arglist, &list, &all_list);
10133           hash_table_free (searched_interfaces);
10134           searched_interfaces = NULL;  
10135         }
10136     }
10137   /* Search classes */
10138   else
10139     {
10140       tree sc = class;
10141       int seen_inner_class = 0;
10142       search_applicable_methods_list (lc, TYPE_METHODS (class), 
10143                                       name, arglist, &list, &all_list);
10144
10145       /* We must search all interfaces of this class */
10146       if (!lc)
10147       {
10148         tree basetype_vec = TYPE_BINFO_BASETYPES (sc);
10149         int n = TREE_VEC_LENGTH (basetype_vec), i;
10150         object_done = 1;
10151         for (i = 1; i < n; i++)
10152           {
10153             tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
10154             if (t != object_type_node)
10155               {
10156                 tree rlist
10157                   = find_applicable_accessible_methods_list (lc, t,
10158                                                              name, arglist);
10159                 list = chainon (rlist, list);
10160               }
10161           }
10162         object_done = 0;
10163       }
10164
10165       /* Search enclosing context of inner classes before looking
10166          ancestors up. */
10167       while (!lc && INNER_CLASS_TYPE_P (class))
10168         {
10169           tree rlist;
10170           seen_inner_class = 1;
10171           class = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class)));
10172           rlist = find_applicable_accessible_methods_list (lc, class, 
10173                                                            name, arglist);
10174           list = chainon (rlist, list);
10175         }
10176
10177       if (!lc && seen_inner_class 
10178           && TREE_TYPE (DECL_CONTEXT (TYPE_NAME (sc))) == CLASSTYPE_SUPER (sc))
10179         class = CLASSTYPE_SUPER (sc);
10180       else
10181         class = sc;
10182
10183       for (class = (lc ? NULL_TREE : CLASSTYPE_SUPER (class)); 
10184         class; class = CLASSTYPE_SUPER (class))
10185        search_applicable_methods_list (lc, TYPE_METHODS (class), 
10186                                        name, arglist, &list, &all_list);
10187     }
10188
10189   /* Either return the list obtained or all selected (but
10190      inaccessible) methods for better error report. */
10191   return (!list ? all_list : list);
10192 }
10193
10194 /* Effectively search for the approriate method in method */
10195
10196 static void 
10197 search_applicable_methods_list (lc, method, name, arglist, list, all_list)
10198      int lc;
10199      tree method, name, arglist;
10200      tree *list, *all_list;
10201 {
10202   for (; method; method = TREE_CHAIN (method))
10203     {
10204       /* When dealing with constructor, stop here, otherwise search
10205          other classes */
10206       if (lc && !DECL_CONSTRUCTOR_P (method))
10207         continue;
10208       else if (!lc && (DECL_CONSTRUCTOR_P (method) 
10209                        || (GET_METHOD_NAME (method) != name)))
10210         continue;
10211           
10212       if (argument_types_convertible (method, arglist))
10213         {
10214           /* Retain accessible methods only */
10215           if (!not_accessible_p (DECL_CONTEXT (current_function_decl), 
10216                                  method, 0))
10217             *list = tree_cons (NULL_TREE, method, *list);
10218           else
10219             /* Also retain all selected method here */
10220             *all_list = tree_cons (NULL_TREE, method, *list);
10221         }
10222     }
10223 }    
10224
10225 /* 15.11.2.2 Choose the Most Specific Method */
10226
10227 static tree
10228 find_most_specific_methods_list (list)
10229      tree list;
10230 {
10231   int max = 0;
10232   int abstract, candidates;
10233   tree current, new_list = NULL_TREE;
10234   for (current = list; current; current = TREE_CHAIN (current))
10235     {
10236       tree method;
10237       DECL_SPECIFIC_COUNT (TREE_VALUE (current)) = 0;
10238
10239       for (method = list; method; method = TREE_CHAIN (method))
10240         {
10241           /* Don't test a method against itself */
10242           if (method == current)
10243             continue;
10244
10245           /* Compare arguments and location where method where declared */
10246           if (argument_types_convertible (TREE_VALUE (method), 
10247                                           TREE_VALUE (current))
10248               && valid_method_invocation_conversion_p 
10249                    (DECL_CONTEXT (TREE_VALUE (method)), 
10250                     DECL_CONTEXT (TREE_VALUE (current))))
10251             {
10252               int v = ++DECL_SPECIFIC_COUNT (TREE_VALUE (current));
10253               max = (v > max ? v : max);
10254             }
10255         }
10256     }
10257
10258   /* Review the list and select the maximally specific methods */
10259   for (current = list, abstract = -1, candidates = -1;
10260        current; current = TREE_CHAIN (current))
10261     if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
10262       {
10263         new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
10264         abstract += (METHOD_ABSTRACT (TREE_VALUE (current)) ? 1 : 0);
10265         candidates++;
10266       }
10267
10268   /* If we have several and they're all abstract, just pick the
10269      closest one. */
10270   if (candidates > 0 && (candidates == abstract))
10271     {
10272       new_list = nreverse (new_list);
10273       TREE_CHAIN (new_list) = NULL_TREE;
10274     }
10275
10276   /* We have several, we couldn't find a most specific, all but one are
10277      abstract, we pick the only non abstract one. */
10278   if (candidates > 0 && !max && (candidates == abstract+1))
10279     {
10280       for (current = new_list; current; current = TREE_CHAIN (current))
10281         if (!METHOD_ABSTRACT (TREE_VALUE (current)))
10282           {
10283             TREE_CHAIN (current) = NULL_TREE;
10284             new_list = current;
10285           }
10286     }
10287
10288   /* If we can't find one, lower expectations and try to gather multiple
10289      maximally specific methods */
10290   while (!new_list && max)
10291     {
10292       while (--max > 0)
10293         {
10294           if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
10295             new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
10296         }
10297     }
10298
10299   return new_list;
10300 }
10301
10302 /* Make sure that the type of each M2_OR_ARGLIST arguments can be
10303    converted by method invocation conversion (5.3) to the type of the
10304    corresponding parameter of M1. Implementation expects M2_OR_ARGLIST
10305    to change less often than M1. */
10306
10307 static int
10308 argument_types_convertible (m1, m2_or_arglist)
10309     tree m1, m2_or_arglist;
10310 {
10311   static tree m2_arg_value = NULL_TREE;
10312   static tree m2_arg_cache = NULL_TREE;
10313
10314   register tree m1_arg, m2_arg;
10315
10316   SKIP_THIS_AND_ARTIFICIAL_PARMS (m1_arg, m1)
10317
10318   if (m2_arg_value == m2_or_arglist)
10319     m2_arg = m2_arg_cache;
10320   else
10321     {
10322       /* M2_OR_ARGLIST can be a function DECL or a raw list of
10323          argument types */
10324       if (m2_or_arglist && TREE_CODE (m2_or_arglist) == FUNCTION_DECL)
10325         {
10326           m2_arg = TYPE_ARG_TYPES (TREE_TYPE (m2_or_arglist));
10327           if (!METHOD_STATIC (m2_or_arglist))
10328             m2_arg = TREE_CHAIN (m2_arg);
10329         }
10330       else
10331         m2_arg = m2_or_arglist;
10332
10333       m2_arg_value = m2_or_arglist;
10334       m2_arg_cache = m2_arg;
10335     }
10336
10337   while (m1_arg != end_params_node && m2_arg != end_params_node)
10338     {
10339       resolve_and_layout (TREE_VALUE (m1_arg), NULL_TREE);
10340       if (!valid_method_invocation_conversion_p (TREE_VALUE (m1_arg),
10341                                                  TREE_VALUE (m2_arg)))
10342         break;
10343       m1_arg = TREE_CHAIN (m1_arg);
10344       m2_arg = TREE_CHAIN (m2_arg);
10345     }
10346   return m1_arg == end_params_node && m2_arg == end_params_node;
10347 }
10348
10349 /* Qualification routines */
10350
10351 static void
10352 qualify_ambiguous_name (id)
10353      tree id;
10354 {
10355   tree qual, qual_wfl, name = NULL_TREE, decl, ptr_type = NULL_TREE,
10356     saved_current_class;
10357   int again, super_found = 0, this_found = 0, new_array_found = 0;
10358   int code;
10359
10360   /* We first qualify the first element, then derive qualification of
10361      others based on the first one. If the first element is qualified
10362      by a resolution (field or type), this resolution is stored in the
10363      QUAL_RESOLUTION of the qual element being examined. We need to
10364      save the current_class since the use of SUPER might change the
10365      its value. */
10366   saved_current_class = current_class;
10367   qual = EXPR_WFL_QUALIFICATION (id);
10368   do {
10369
10370     /* Simple qualified expression feature a qual_wfl that is a
10371        WFL. Expression derived from a primary feature more complicated
10372        things like a CALL_EXPR. Expression from primary need to be
10373        worked out to extract the part on which the qualification will
10374        take place. */
10375     qual_wfl = QUAL_WFL (qual);
10376     switch (TREE_CODE (qual_wfl))
10377       {
10378       case CALL_EXPR:
10379         qual_wfl = TREE_OPERAND (qual_wfl, 0);
10380         if (TREE_CODE (qual_wfl) != EXPR_WITH_FILE_LOCATION)
10381           {
10382             qual = EXPR_WFL_QUALIFICATION (qual_wfl);
10383             qual_wfl = QUAL_WFL (qual);
10384           }
10385         break;
10386       case NEW_ARRAY_EXPR:
10387       case NEW_ANONYMOUS_ARRAY_EXPR:
10388         qual = TREE_CHAIN (qual);
10389         again = new_array_found = 1;
10390         continue;
10391       case CONVERT_EXPR:
10392         break;
10393       case NEW_CLASS_EXPR:
10394         qual_wfl = TREE_OPERAND (qual_wfl, 0);
10395         break;
10396       case ARRAY_REF:
10397         while (TREE_CODE (qual_wfl) == ARRAY_REF)
10398           qual_wfl = TREE_OPERAND (qual_wfl, 0);
10399         break;
10400       case STRING_CST:
10401         qual = TREE_CHAIN (qual);
10402         qual_wfl = QUAL_WFL (qual);
10403         break;
10404       case CLASS_LITERAL:
10405         qual = TREE_CHAIN (qual);
10406         qual_wfl = QUAL_WFL (qual);
10407       break;
10408       default:
10409         /* Fix for -Wall. Just break doing nothing */
10410         break;
10411       }
10412
10413     ptr_type = current_class;
10414     again = 0;
10415     code = TREE_CODE (qual_wfl);
10416
10417     /* Pos evaluation: non WFL leading expression nodes */
10418     if (code == CONVERT_EXPR
10419         && TREE_CODE (TREE_TYPE (qual_wfl)) == EXPR_WITH_FILE_LOCATION)
10420       name = EXPR_WFL_NODE (TREE_TYPE (qual_wfl));
10421
10422     else if (code == INTEGER_CST)
10423       name = qual_wfl;
10424     
10425     else if ((code == ARRAY_REF || code == CALL_EXPR || code == MODIFY_EXPR) &&
10426              TREE_CODE (TREE_OPERAND (qual_wfl, 0)) == EXPR_WITH_FILE_LOCATION)
10427       name = EXPR_WFL_NODE (TREE_OPERAND (qual_wfl, 0));
10428
10429     else if (code == TREE_LIST)
10430       name = EXPR_WFL_NODE (TREE_PURPOSE (qual_wfl));
10431
10432     else if (code == STRING_CST || code == CONDITIONAL_EXPR 
10433              || code == PLUS_EXPR)
10434       {
10435         qual = TREE_CHAIN (qual);
10436         qual_wfl = QUAL_WFL (qual);
10437         again = 1;
10438       }
10439     else 
10440       {
10441         name = EXPR_WFL_NODE (qual_wfl);
10442         if (!name)
10443           {
10444             qual = EXPR_WFL_QUALIFICATION (qual_wfl);
10445             again = 1;
10446           }
10447       }
10448
10449     /* If we have a THIS (from a primary), we set the context accordingly */
10450     if (name == this_identifier_node)
10451       {
10452         qual = TREE_CHAIN (qual);
10453         qual_wfl = QUAL_WFL (qual);
10454         if (TREE_CODE (qual_wfl) == CALL_EXPR)
10455           again = 1;
10456         else
10457           name = EXPR_WFL_NODE (qual_wfl);
10458         this_found = 1;
10459       }
10460     /* If we have a SUPER, we set the context accordingly */
10461     if (name == super_identifier_node)
10462       {
10463         current_class = CLASSTYPE_SUPER (ptr_type);
10464         /* Check that there is such a thing as a super class. If not,
10465            return.  The error will be caught later on, during the
10466            resolution */
10467         if (!current_class)
10468           {
10469             current_class = saved_current_class;
10470             return;
10471           }
10472         qual = TREE_CHAIN (qual);
10473         /* Do one more interation to set things up */
10474         super_found = again = 1;
10475       }
10476   } while (again);
10477   
10478   /* If name appears within the scope of a local variable declaration
10479      or parameter declaration, then it is an expression name. We don't
10480      carry this test out if we're in the context of the use of SUPER
10481      or THIS */
10482   if (!this_found && !super_found 
10483       && TREE_CODE (name) != STRING_CST && TREE_CODE (name) != INTEGER_CST
10484       && (decl = IDENTIFIER_LOCAL_VALUE (name)))
10485     {
10486       RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
10487       QUAL_RESOLUTION (qual) = decl;
10488     }
10489
10490   /* If within the class/interface NAME was found to be used there
10491      exists a (possibly inherited) field named NAME, then this is an
10492      expression name. If we saw a NEW_ARRAY_EXPR before and want to
10493      address length, it is OK. */
10494   else if ((decl = lookup_field_wrapper (ptr_type, name))
10495            || (new_array_found && name == length_identifier_node))
10496     {
10497       RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
10498       QUAL_RESOLUTION (qual) = (new_array_found ? NULL_TREE : decl);
10499     }
10500
10501   /* We reclassify NAME as yielding to a type name resolution if:
10502      - NAME is a class/interface declared within the compilation
10503        unit containing NAME,
10504      - NAME is imported via a single-type-import declaration,
10505      - NAME is declared in an another compilation unit of the package
10506        of the compilation unit containing NAME,
10507      - NAME is declared by exactly on type-import-on-demand declaration
10508      of the compilation unit containing NAME. 
10509      - NAME is actually a STRING_CST. */
10510   else if (TREE_CODE (name) == STRING_CST || TREE_CODE (name) == INTEGER_CST
10511            || (decl = resolve_and_layout (name, NULL_TREE)))
10512     {
10513       RESOLVE_TYPE_NAME_P (qual_wfl) = 1;
10514       QUAL_RESOLUTION (qual) = decl;
10515     }
10516
10517   /* Method call, array references and cast are expression name */
10518   else if (TREE_CODE (QUAL_WFL (qual)) == CALL_EXPR
10519            || TREE_CODE (QUAL_WFL (qual)) == ARRAY_REF
10520            || TREE_CODE (QUAL_WFL (qual)) == CONVERT_EXPR)
10521     RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
10522
10523   /* Check here that NAME isn't declared by more than one
10524      type-import-on-demand declaration of the compilation unit
10525      containing NAME. FIXME */
10526
10527   /* Otherwise, NAME is reclassified as a package name */
10528   else 
10529     RESOLVE_PACKAGE_NAME_P (qual_wfl) = 1;
10530
10531   /* Propagate the qualification accross other components of the
10532      qualified name */
10533   for (qual = TREE_CHAIN (qual); qual;
10534        qual_wfl = QUAL_WFL (qual), qual = TREE_CHAIN (qual))
10535     {
10536       if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
10537         RESOLVE_PACKAGE_NAME_P (QUAL_WFL (qual)) = 1;
10538       else 
10539         RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (qual)) = 1;
10540     }
10541
10542   /* Store the global qualification for the ambiguous part of ID back
10543      into ID fields */
10544   if (RESOLVE_EXPRESSION_NAME_P (qual_wfl))
10545     RESOLVE_EXPRESSION_NAME_P (id) = 1;
10546   else if (RESOLVE_TYPE_NAME_P (qual_wfl))
10547     RESOLVE_TYPE_NAME_P (id) = 1;
10548   else if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
10549     RESOLVE_PACKAGE_NAME_P (id) = 1;
10550
10551   /* Restore the current class */
10552   current_class = saved_current_class;
10553 }
10554
10555 static int
10556 breakdown_qualified (left, right, source)
10557     tree *left, *right, source;
10558 {
10559   char *p = IDENTIFIER_POINTER (source), *base;
10560   int   l = IDENTIFIER_LENGTH (source);
10561
10562   /* Breakdown NAME into REMAINDER . IDENTIFIER */
10563   base = p;
10564   p += (l-1);
10565   while (*p != '.' && p != base)
10566     p--;
10567
10568   /* We didn't find a '.'. Return an error */
10569   if (p == base)
10570     return 1;
10571
10572   *p = '\0';
10573   if (right)
10574     *right = get_identifier (p+1);
10575   *left = get_identifier (IDENTIFIER_POINTER (source));
10576   *p = '.';
10577   
10578   return 0;
10579 }
10580
10581 /* Patch tree nodes in a function body. When a BLOCK is found, push
10582    local variable decls if present.
10583    Same as java_complete_lhs, but does resolve static finals to values. */
10584
10585 static tree
10586 java_complete_tree (node)
10587      tree node;
10588 {
10589   node = java_complete_lhs (node);
10590   if (TREE_CODE (node) == VAR_DECL && FIELD_STATIC (node)
10591       && FIELD_FINAL (node) && DECL_INITIAL (node) != NULL_TREE
10592       && !flag_emit_xref)
10593     {
10594       tree value = DECL_INITIAL (node);
10595       DECL_INITIAL (node) = NULL_TREE;
10596       push_obstacks (&permanent_obstack, &permanent_obstack);
10597       value = fold_constant_for_init (value, node);
10598       pop_obstacks ();
10599       DECL_INITIAL (node) = value;
10600       if (value != NULL_TREE)
10601         {
10602           /* fold_constant_for_init sometimes widen the original type
10603              of the constant (i.e. byte to int.) It's not desirable,
10604              especially if NODE is a function argument. */
10605           if (TREE_CODE (value) == INTEGER_CST
10606               && TREE_TYPE (node) != TREE_TYPE (value))
10607             return convert (TREE_TYPE (node), value);
10608           else
10609             return value;
10610         }
10611     }
10612   return node;
10613 }
10614
10615 static tree
10616 java_stabilize_reference (node)
10617      tree node;
10618 {
10619   if (TREE_CODE (node) == COMPOUND_EXPR)
10620     {
10621       tree op0 = TREE_OPERAND (node, 0);
10622       tree op1 = TREE_OPERAND (node, 1);
10623       TREE_OPERAND (node, 0) = save_expr (op0);
10624       TREE_OPERAND (node, 1) = java_stabilize_reference (op1);
10625       return node;
10626     }
10627   return stabilize_reference (node);
10628 }
10629
10630 /* Patch tree nodes in a function body. When a BLOCK is found, push
10631    local variable decls if present.
10632    Same as java_complete_tree, but does not resolve static finals to values. */
10633
10634 static tree
10635 java_complete_lhs (node)
10636      tree node;
10637 {
10638   tree nn, cn, wfl_op1, wfl_op2, wfl_op3;
10639   int flag;
10640
10641   /* CONVERT_EXPR always has its type set, even though it needs to be
10642      worked out. */
10643   if (TREE_TYPE (node) && TREE_CODE (node) != CONVERT_EXPR)
10644     return node;
10645
10646   /* The switch block implements cases processing container nodes
10647      first.  Contained nodes are always written back. Leaves come
10648      next and return a value. */
10649   switch (TREE_CODE (node))
10650     {
10651     case BLOCK:
10652
10653       /* 1- Block section.
10654          Set the local values on decl names so we can identify them
10655          faster when they're referenced. At that stage, identifiers
10656          are legal so we don't check for declaration errors. */
10657       for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
10658         {
10659           DECL_CONTEXT (cn) = current_function_decl;
10660           IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = cn;
10661         }
10662       if (BLOCK_EXPR_BODY (node) == NULL_TREE)
10663           CAN_COMPLETE_NORMALLY (node) = 1;
10664       else
10665         {
10666           tree stmt = BLOCK_EXPR_BODY (node);
10667           tree *ptr;
10668           int error_seen = 0;
10669           if (TREE_CODE (stmt) == COMPOUND_EXPR)
10670             {
10671               /* Re-order from (((A; B); C); ...; Z) to 
10672                  (A; (B; (C ; (...; Z)))).
10673                  This makes it easier to scan the statements left-to-right
10674                  without using recursion (which might overflow the stack
10675                  if the block has many statements. */
10676               for (;;)
10677                 {
10678                   tree left = TREE_OPERAND (stmt, 0);
10679                   if (TREE_CODE (left) != COMPOUND_EXPR)
10680                     break;
10681                   TREE_OPERAND (stmt, 0) = TREE_OPERAND (left, 1);
10682                   TREE_OPERAND (left, 1) = stmt;
10683                   stmt = left;
10684                 }
10685               BLOCK_EXPR_BODY (node) = stmt;
10686             }
10687
10688           /* Now do the actual complete, without deep recursion for
10689              long blocks. */
10690           ptr = &BLOCK_EXPR_BODY (node);
10691           while (TREE_CODE (*ptr) == COMPOUND_EXPR
10692                  && TREE_OPERAND (*ptr, 1) != empty_stmt_node)
10693             {
10694               tree cur = java_complete_tree (TREE_OPERAND (*ptr, 0));
10695               tree *next = &TREE_OPERAND (*ptr, 1);
10696               TREE_OPERAND (*ptr, 0) = cur;
10697               if (cur == empty_stmt_node)
10698                 {
10699                   /* Optimization;  makes it easier to detect empty bodies.
10700                      Most useful for <clinit> with all-constant initializer. */
10701                   *ptr = *next;
10702                   continue;
10703                 }
10704               if (TREE_CODE (cur) == ERROR_MARK)
10705                 error_seen++;
10706               else if (! CAN_COMPLETE_NORMALLY (cur))
10707                 {
10708                   wfl_op2 = *next;
10709                   for (;;)
10710                     {
10711                       if (TREE_CODE (wfl_op2) == BLOCK)
10712                         wfl_op2 = BLOCK_EXPR_BODY (wfl_op2);
10713                       else if (TREE_CODE (wfl_op2) == COMPOUND_EXPR)
10714                         wfl_op2 = TREE_OPERAND (wfl_op2, 0);
10715                       else
10716                         break;
10717                     }
10718                   if (TREE_CODE (wfl_op2) != CASE_EXPR
10719                       && TREE_CODE (wfl_op2) != DEFAULT_EXPR)
10720                     unreachable_stmt_error (*ptr);
10721                 }
10722               ptr = next;
10723             }
10724           *ptr = java_complete_tree (*ptr);
10725
10726           if (TREE_CODE (*ptr) == ERROR_MARK || error_seen > 0)
10727             return error_mark_node;
10728           CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (*ptr);
10729         }
10730       /* Turn local bindings to null */
10731       for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
10732         IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = NULL_TREE;
10733
10734       TREE_TYPE (node) = void_type_node;
10735       break;
10736
10737       /* 2- They are expressions but ultimately deal with statements */
10738
10739     case THROW_EXPR:
10740       wfl_op1 = TREE_OPERAND (node, 0);
10741       COMPLETE_CHECK_OP_0 (node);
10742       /* 14.19 A throw statement cannot complete normally. */
10743       CAN_COMPLETE_NORMALLY (node) = 0;
10744       return patch_throw_statement (node, wfl_op1);
10745
10746     case SYNCHRONIZED_EXPR:
10747       wfl_op1 = TREE_OPERAND (node, 0);
10748       return patch_synchronized_statement (node, wfl_op1);
10749
10750     case TRY_EXPR:
10751       return patch_try_statement (node);
10752
10753     case TRY_FINALLY_EXPR:
10754       COMPLETE_CHECK_OP_0 (node);
10755       COMPLETE_CHECK_OP_1 (node);
10756       CAN_COMPLETE_NORMALLY (node)
10757         = (CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0))
10758            && CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)));
10759       TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 0));
10760       return node;
10761
10762     case CLEANUP_POINT_EXPR:
10763       COMPLETE_CHECK_OP_0 (node);
10764       TREE_TYPE (node) = void_type_node;
10765       CAN_COMPLETE_NORMALLY (node) = 
10766         CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
10767       return node;
10768
10769     case WITH_CLEANUP_EXPR:
10770       COMPLETE_CHECK_OP_0 (node);
10771       COMPLETE_CHECK_OP_2 (node);
10772       CAN_COMPLETE_NORMALLY (node) = 
10773         CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
10774       TREE_TYPE (node) = void_type_node;
10775       return node;
10776
10777     case LABELED_BLOCK_EXPR:
10778       PUSH_LABELED_BLOCK (node);
10779       if (LABELED_BLOCK_BODY (node))
10780         COMPLETE_CHECK_OP_1 (node);
10781       TREE_TYPE (node) = void_type_node;
10782       POP_LABELED_BLOCK ();
10783
10784       if (LABELED_BLOCK_BODY (node) == empty_stmt_node)
10785         {
10786           LABELED_BLOCK_BODY (node) = NULL_TREE;
10787           CAN_COMPLETE_NORMALLY (node) = 1;
10788         }
10789       else if (CAN_COMPLETE_NORMALLY (LABELED_BLOCK_BODY (node)))
10790         CAN_COMPLETE_NORMALLY (node) = 1;
10791       return node;
10792
10793     case EXIT_BLOCK_EXPR:
10794       /* We don't complete operand 1, because it's the return value of
10795          the EXIT_BLOCK_EXPR which doesn't exist it Java */
10796       return patch_bc_statement (node);
10797
10798     case CASE_EXPR:
10799       cn = java_complete_tree (TREE_OPERAND (node, 0));
10800       if (cn == error_mark_node)
10801         return cn;
10802
10803       /* First, the case expression must be constant. Values of final
10804          fields are accepted. */
10805       cn = fold (cn);
10806       if ((TREE_CODE (cn) == COMPOUND_EXPR || TREE_CODE (cn) == COMPONENT_REF)
10807           && JDECL_P (TREE_OPERAND (cn, 1))
10808           && FIELD_FINAL (TREE_OPERAND (cn, 1))
10809           && DECL_INITIAL (TREE_OPERAND (cn, 1)))
10810         {
10811           push_obstacks (&permanent_obstack, &permanent_obstack);
10812           cn = fold_constant_for_init (DECL_INITIAL (TREE_OPERAND (cn, 1)),
10813                                        TREE_OPERAND (cn, 1));
10814           pop_obstacks ();
10815         }
10816
10817       if (!TREE_CONSTANT (cn) && !flag_emit_xref)
10818         {
10819           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10820           parse_error_context (node, "Constant expression required");
10821           return error_mark_node;
10822         }
10823
10824       nn = ctxp->current_loop;
10825
10826       /* It must be assignable to the type of the switch expression. */
10827       if (!try_builtin_assignconv (NULL_TREE, 
10828                                    TREE_TYPE (TREE_OPERAND (nn, 0)), cn))
10829         {
10830           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10831           parse_error_context 
10832             (wfl_operator,
10833              "Incompatible type for case. Can't convert `%s' to `int'",
10834              lang_printable_name (TREE_TYPE (cn), 0));
10835           return error_mark_node;
10836         }
10837
10838       cn = fold (convert (int_type_node, cn));
10839
10840       /* Multiple instance of a case label bearing the same
10841          value is checked during code generation. The case
10842          expression is allright so far. */
10843       TREE_OPERAND (node, 0) = cn;
10844       TREE_TYPE (node) = void_type_node;
10845       CAN_COMPLETE_NORMALLY (node) = 1;
10846       TREE_SIDE_EFFECTS (node) = 1;
10847       break;
10848
10849     case DEFAULT_EXPR:
10850       nn = ctxp->current_loop;
10851       /* Only one default label is allowed per switch statement */
10852       if (SWITCH_HAS_DEFAULT (nn))
10853         {
10854           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10855           parse_error_context (wfl_operator, 
10856                                "Duplicate case label: `default'");
10857           return error_mark_node;
10858         }
10859       else
10860         SWITCH_HAS_DEFAULT (nn) = 1;
10861       TREE_TYPE (node) = void_type_node;
10862       TREE_SIDE_EFFECTS (node) = 1;
10863       CAN_COMPLETE_NORMALLY (node) = 1;
10864       break;
10865
10866     case SWITCH_EXPR:
10867     case LOOP_EXPR:
10868       PUSH_LOOP (node);
10869       /* Check whether the loop was enclosed in a labeled
10870          statement. If not, create one, insert the loop in it and
10871          return the node */
10872       nn = patch_loop_statement (node);
10873
10874       /* Anyways, walk the body of the loop */
10875       if (TREE_CODE (node) == LOOP_EXPR)
10876         TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
10877       /* Switch statement: walk the switch expression and the cases */
10878       else
10879         node = patch_switch_statement (node);
10880
10881       if (TREE_OPERAND (node, 0) == error_mark_node)
10882         nn = error_mark_node;
10883       else
10884         {
10885           TREE_TYPE (nn) = TREE_TYPE (node) = void_type_node;
10886           /* If we returned something different, that's because we
10887              inserted a label. Pop the label too. */
10888           if (nn != node)
10889             {
10890               if (CAN_COMPLETE_NORMALLY (node))
10891                 CAN_COMPLETE_NORMALLY (nn) = 1;
10892               POP_LABELED_BLOCK ();
10893             }
10894         }
10895       POP_LOOP ();
10896       return nn;
10897
10898     case EXIT_EXPR:
10899       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
10900       return patch_exit_expr (node);
10901
10902     case COND_EXPR:
10903       /* Condition */
10904       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
10905       if (TREE_OPERAND (node, 0) == error_mark_node)
10906         return error_mark_node;
10907       /* then-else branches */
10908       TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
10909       if (TREE_OPERAND (node, 1) == error_mark_node)
10910         return error_mark_node;
10911       TREE_OPERAND (node, 2) = java_complete_tree (TREE_OPERAND (node, 2));
10912       if (TREE_OPERAND (node, 2) == error_mark_node)
10913         return error_mark_node;
10914       return patch_if_else_statement (node);
10915       break;
10916
10917     case CONDITIONAL_EXPR:
10918       /* Condition */
10919       wfl_op1 = TREE_OPERAND (node, 0);
10920       COMPLETE_CHECK_OP_0 (node);
10921       wfl_op2 = TREE_OPERAND (node, 1);
10922       COMPLETE_CHECK_OP_1 (node);
10923       wfl_op3 = TREE_OPERAND (node, 2);
10924       COMPLETE_CHECK_OP_2 (node);
10925       return patch_conditional_expr (node, wfl_op1, wfl_op2);
10926
10927       /* 3- Expression section */
10928     case COMPOUND_EXPR:
10929       wfl_op2 = TREE_OPERAND (node, 1);
10930       TREE_OPERAND (node, 0) = nn = 
10931         java_complete_tree (TREE_OPERAND (node, 0));
10932       if (wfl_op2 == empty_stmt_node)
10933         CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (nn);
10934       else
10935         {
10936           if (! CAN_COMPLETE_NORMALLY (nn) && TREE_CODE (nn) != ERROR_MARK)
10937             {
10938               /* An unreachable condition in a do-while statement
10939                  is *not* (technically) an unreachable statement. */
10940               nn = wfl_op2;
10941               if (TREE_CODE (nn) == EXPR_WITH_FILE_LOCATION)
10942                 nn = EXPR_WFL_NODE (nn);
10943               if (TREE_CODE (nn) != EXIT_EXPR)
10944                 {
10945                   SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
10946                   parse_error_context (wfl_operator, "Unreachable statement");
10947                 }
10948             }
10949           TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
10950           if (TREE_OPERAND (node, 1) == error_mark_node)
10951             return error_mark_node;
10952           CAN_COMPLETE_NORMALLY (node)
10953             = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1));
10954         }
10955       TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 1));
10956       break;
10957
10958     case RETURN_EXPR:
10959       /* CAN_COMPLETE_NORMALLY (node) = 0; */
10960       return patch_return (node);
10961
10962     case EXPR_WITH_FILE_LOCATION:
10963       if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
10964           || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
10965         {
10966           tree wfl = node;
10967           node = resolve_expression_name (node, NULL);
10968           if (node == error_mark_node)
10969             return node;
10970           /* Keep line number information somewhere were it doesn't
10971              disrupt the completion process. */
10972           if (flag_emit_xref && TREE_CODE (node) != CALL_EXPR)
10973             {
10974               EXPR_WFL_NODE (wfl) = TREE_OPERAND (node, 1);
10975               TREE_OPERAND (node, 1) = wfl;
10976             }
10977           CAN_COMPLETE_NORMALLY (node) = 1;
10978         }
10979       else
10980         {
10981           tree body;
10982           int save_lineno = lineno;
10983           lineno = EXPR_WFL_LINENO (node);
10984           body = java_complete_tree (EXPR_WFL_NODE (node));
10985           lineno = save_lineno;
10986           EXPR_WFL_NODE (node) = body;
10987           TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (body);
10988           CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (body);
10989           if (body == empty_stmt_node)
10990             {
10991               /* Optimization;  makes it easier to detect empty bodies. */
10992               return body;
10993             }
10994           if (body == error_mark_node)
10995             {
10996               /* Its important for the evaluation of assignment that
10997                  this mark on the TREE_TYPE is propagated. */
10998               TREE_TYPE (node) = error_mark_node;
10999               return error_mark_node;
11000             }
11001           else
11002             TREE_TYPE (node) = TREE_TYPE (EXPR_WFL_NODE (node));
11003           
11004         }
11005       break;
11006
11007     case NEW_ARRAY_EXPR:
11008       /* Patch all the dimensions */
11009       flag = 0;
11010       for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
11011         {
11012           int location = EXPR_WFL_LINECOL (TREE_VALUE (cn));
11013           tree dim = convert (int_type_node, 
11014                               java_complete_tree (TREE_VALUE (cn)));
11015           if (dim == error_mark_node)
11016             {
11017               flag = 1;
11018               continue;
11019             }
11020           else
11021             {
11022               TREE_VALUE (cn) = dim;
11023               /* Setup the location of the current dimension, for
11024                  later error report. */
11025               TREE_PURPOSE (cn) = 
11026                 build_expr_wfl (NULL_TREE, input_filename, 0, 0);
11027               EXPR_WFL_LINECOL (TREE_PURPOSE (cn)) = location;
11028             }
11029         }
11030       /* They complete the array creation expression, if no errors
11031          were found. */
11032       CAN_COMPLETE_NORMALLY (node) = 1;
11033       return (flag ? error_mark_node
11034               : force_evaluation_order (patch_newarray (node)));
11035
11036     case NEW_ANONYMOUS_ARRAY_EXPR:
11037       /* Create the array type if necessary. */
11038       if (ANONYMOUS_ARRAY_DIMS_SIG (node))
11039         {
11040           tree type = ANONYMOUS_ARRAY_BASE_TYPE (node);
11041           if (!(type = resolve_type_during_patch (type)))
11042             return error_mark_node;
11043           type = build_array_from_name (type, NULL_TREE,
11044                                         ANONYMOUS_ARRAY_DIMS_SIG (node), NULL);
11045           ANONYMOUS_ARRAY_BASE_TYPE (node) = build_pointer_type (type);
11046         }
11047       node = patch_new_array_init (ANONYMOUS_ARRAY_BASE_TYPE (node),
11048                                    ANONYMOUS_ARRAY_INITIALIZER (node));
11049       if (node == error_mark_node)
11050         return error_mark_node;
11051       CAN_COMPLETE_NORMALLY (node) = 1;
11052       return node;
11053
11054     case NEW_CLASS_EXPR:
11055     case CALL_EXPR:
11056       /* Complete function's argument(s) first */
11057       if (complete_function_arguments (node))
11058         return error_mark_node;
11059       else
11060         {
11061           tree decl, wfl = TREE_OPERAND (node, 0);
11062           int in_this = CALL_THIS_CONSTRUCTOR_P (node);
11063
11064           node = patch_method_invocation (node, NULL_TREE, 
11065                                           NULL_TREE, 0, &decl);
11066           if (node == error_mark_node)
11067             return error_mark_node;
11068
11069           check_thrown_exceptions (EXPR_WFL_LINECOL (node), decl);
11070           /* If we call this(...), register signature and positions */
11071           if (in_this)
11072             DECL_CONSTRUCTOR_CALLS (current_function_decl) = 
11073               tree_cons (wfl, decl, 
11074                          DECL_CONSTRUCTOR_CALLS (current_function_decl));
11075           CAN_COMPLETE_NORMALLY (node) = 1;
11076           return force_evaluation_order (node);
11077         }
11078
11079     case MODIFY_EXPR:
11080       /* Save potential wfls */
11081       wfl_op1 = TREE_OPERAND (node, 0);
11082       TREE_OPERAND (node, 0) = nn = java_complete_lhs (wfl_op1);
11083       
11084       if (MODIFY_EXPR_FROM_INITIALIZATION_P (node)
11085           && TREE_CODE (nn) == VAR_DECL && TREE_STATIC (nn)
11086           && DECL_INITIAL (nn) != NULL_TREE)
11087         {
11088           tree value;
11089           
11090           push_obstacks (&permanent_obstack, &permanent_obstack);
11091           value = fold_constant_for_init (nn, nn);
11092           pop_obstacks ();
11093
11094           if (value != NULL_TREE)
11095             {
11096               tree type = TREE_TYPE (value);
11097               if (JPRIMITIVE_TYPE_P (type) || 
11098                   (type == string_ptr_type_node && ! flag_emit_class_files))
11099                 return empty_stmt_node;
11100             }
11101           DECL_INITIAL (nn) = NULL_TREE;
11102         }
11103       wfl_op2 = TREE_OPERAND (node, 1);
11104
11105       if (TREE_OPERAND (node, 0) == error_mark_node)
11106         return error_mark_node;
11107
11108       flag = COMPOUND_ASSIGN_P (wfl_op2);
11109       if (flag)
11110         {
11111           /* This might break when accessing outer field from inner
11112              class. TESTME, FIXME */
11113           tree lvalue = java_stabilize_reference (TREE_OPERAND (node, 0)); 
11114
11115           /* Hand stablize the lhs on both places */
11116           TREE_OPERAND (node, 0) = lvalue;
11117           TREE_OPERAND (TREE_OPERAND (node, 1), 0) = 
11118             (flag_emit_class_files ? lvalue : save_expr (lvalue));
11119
11120           /* 15.25.2.a: Left hand is not an array access. FIXME */
11121           /* Now complete the RHS. We write it back later on. */
11122           nn = java_complete_tree (TREE_OPERAND (node, 1));
11123
11124           if ((cn = patch_string (nn)))
11125             nn = cn;
11126
11127           /* The last part of the rewrite for E1 op= E2 is to have 
11128              E1 = (T)(E1 op E2), with T being the type of E1. */
11129           nn = java_complete_tree (build_cast (EXPR_WFL_LINECOL (wfl_op2), 
11130                                                TREE_TYPE (lvalue), nn));
11131
11132           /* 15.25.2.b: Left hand is an array access. FIXME */
11133         }
11134
11135       /* If we're about to patch a NEW_ARRAY_INIT, we call a special
11136          function to complete this RHS. Note that a NEW_ARRAY_INIT
11137          might have been already fully expanded if created as a result
11138          of processing an anonymous array initializer. We avoid doing
11139          the operation twice by testing whether the node already bears
11140          a type. */
11141       else if (TREE_CODE (wfl_op2) == NEW_ARRAY_INIT && !TREE_TYPE (wfl_op2))
11142         nn = patch_new_array_init (TREE_TYPE (TREE_OPERAND (node, 0)),
11143                                    TREE_OPERAND (node, 1));
11144       /* Otherwise we simply complete the RHS */
11145       else
11146         nn = java_complete_tree (TREE_OPERAND (node, 1));
11147
11148       if (nn == error_mark_node)
11149         return error_mark_node;
11150
11151       /* Write back the RHS as we evaluated it. */
11152       TREE_OPERAND (node, 1) = nn;
11153
11154       /* In case we're handling = with a String as a RHS, we need to
11155          produce a String out of the RHS (it might still be a
11156          STRING_CST or a StringBuffer at this stage */
11157       if ((nn = patch_string (TREE_OPERAND (node, 1))))
11158         TREE_OPERAND (node, 1) = nn;
11159
11160       if ((nn = outer_field_access_fix (wfl_op1, TREE_OPERAND (node, 0),
11161                                         TREE_OPERAND (node, 1))))
11162         {
11163           /* We return error_mark_node if outer_field_access_fix
11164              detects we write into a final. */
11165           if (nn == error_mark_node)
11166             return error_mark_node;
11167           node = nn;
11168         }
11169       else
11170         {
11171           node = patch_assignment (node, wfl_op1, wfl_op2);
11172           /* Reorganize the tree if necessary. */
11173           if (flag && (!JREFERENCE_TYPE_P (TREE_TYPE (node)) 
11174                        || JSTRING_P (TREE_TYPE (node))))
11175             node = java_refold (node);
11176         }
11177       
11178       CAN_COMPLETE_NORMALLY (node) = 1;
11179       return node;
11180
11181     case MULT_EXPR:
11182     case PLUS_EXPR:
11183     case MINUS_EXPR:
11184     case LSHIFT_EXPR:
11185     case RSHIFT_EXPR:
11186     case URSHIFT_EXPR:
11187     case BIT_AND_EXPR:
11188     case BIT_XOR_EXPR:
11189     case BIT_IOR_EXPR:
11190     case TRUNC_MOD_EXPR:
11191     case TRUNC_DIV_EXPR:
11192     case RDIV_EXPR:
11193     case TRUTH_ANDIF_EXPR:
11194     case TRUTH_ORIF_EXPR:
11195     case EQ_EXPR: 
11196     case NE_EXPR:
11197     case GT_EXPR:
11198     case GE_EXPR:
11199     case LT_EXPR:
11200     case LE_EXPR:
11201       /* Operands 0 and 1 are WFL in certain cases only. patch_binop
11202          knows how to handle those cases. */
11203       wfl_op1 = TREE_OPERAND (node, 0);
11204       wfl_op2 = TREE_OPERAND (node, 1);
11205
11206       CAN_COMPLETE_NORMALLY (node) = 1;
11207       /* Don't complete string nodes if dealing with the PLUS operand. */
11208       if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op1))
11209         {
11210           nn = java_complete_tree (wfl_op1);
11211           if (nn == error_mark_node)
11212             return error_mark_node;
11213
11214           TREE_OPERAND (node, 0) = nn;
11215         }
11216       if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op2))
11217         {
11218           nn = java_complete_tree (wfl_op2);
11219           if (nn == error_mark_node)
11220             return error_mark_node;
11221
11222           TREE_OPERAND (node, 1) = nn;
11223         }
11224       return force_evaluation_order (patch_binop (node, wfl_op1, wfl_op2));
11225
11226     case INSTANCEOF_EXPR:
11227       wfl_op1 = TREE_OPERAND (node, 0);
11228       COMPLETE_CHECK_OP_0 (node);
11229       if (flag_emit_xref)
11230         {
11231           TREE_TYPE (node) = boolean_type_node;
11232           return node;
11233         }
11234       return patch_binop (node, wfl_op1, TREE_OPERAND (node, 1));
11235
11236     case UNARY_PLUS_EXPR:
11237     case NEGATE_EXPR:
11238     case TRUTH_NOT_EXPR:
11239     case BIT_NOT_EXPR:
11240     case PREDECREMENT_EXPR:
11241     case PREINCREMENT_EXPR:
11242     case POSTDECREMENT_EXPR:
11243     case POSTINCREMENT_EXPR:
11244     case CONVERT_EXPR:
11245       /* There are cases were wfl_op1 is a WFL. patch_unaryop knows
11246          how to handle those cases. */
11247       wfl_op1 = TREE_OPERAND (node, 0);
11248       CAN_COMPLETE_NORMALLY (node) = 1;
11249       TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
11250       if (TREE_OPERAND (node, 0) == error_mark_node)
11251         return error_mark_node;
11252       node = patch_unaryop (node, wfl_op1);
11253       CAN_COMPLETE_NORMALLY (node) = 1;
11254       break;
11255
11256     case ARRAY_REF:
11257       /* There are cases were wfl_op1 is a WFL. patch_array_ref knows
11258          how to handle those cases. */
11259       wfl_op1 = TREE_OPERAND (node, 0);
11260       TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
11261       if (TREE_OPERAND (node, 0) == error_mark_node)
11262         return error_mark_node;
11263       if (!flag_emit_class_files && !flag_emit_xref)
11264         TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
11265       /* The same applies to wfl_op2 */
11266       wfl_op2 = TREE_OPERAND (node, 1);
11267       TREE_OPERAND (node, 1) = java_complete_tree (wfl_op2);
11268       if (TREE_OPERAND (node, 1) == error_mark_node)
11269         return error_mark_node;
11270       if (!flag_emit_class_files && !flag_emit_xref)
11271         TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1));
11272       return patch_array_ref (node);
11273
11274     case RECORD_TYPE:
11275       return node;;
11276
11277     case COMPONENT_REF:
11278       /* The first step in the re-write of qualified name handling.  FIXME.
11279          So far, this is only to support PRIMTYPE.class -> PRIMCLASS.TYPE. */
11280       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
11281       if (TREE_CODE (TREE_OPERAND (node, 0)) == RECORD_TYPE)
11282         {
11283           tree name = TREE_OPERAND (node, 1);
11284           tree field = lookup_field_wrapper (TREE_OPERAND (node, 0), name);
11285           if (field == NULL_TREE)
11286             {
11287               error ("missing static field `%s'", IDENTIFIER_POINTER (name));
11288               return error_mark_node;
11289             }
11290           if (! FIELD_STATIC (field))
11291             {
11292               error ("not a static field `%s'", IDENTIFIER_POINTER (name));
11293               return error_mark_node;
11294             }
11295           return field;
11296         }
11297       else
11298         fatal ("unimplemented java_complete_tree for COMPONENT_REF");
11299       break;
11300
11301     case THIS_EXPR:
11302       /* Can't use THIS in a static environment */
11303       if (!current_this)
11304         {
11305           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11306           parse_error_context (wfl_operator,
11307                                "Keyword `this' used outside allowed context");
11308           TREE_TYPE (node) = error_mark_node;
11309           return error_mark_node;
11310         }
11311       if (ctxp->explicit_constructor_p)
11312         {
11313           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11314           parse_error_context 
11315             (wfl_operator, "Can't reference `this' or `super' before the superclass constructor has been called");
11316           TREE_TYPE (node) = error_mark_node;
11317           return error_mark_node;
11318         }
11319       return current_this;
11320       
11321     case CLASS_LITERAL:
11322       CAN_COMPLETE_NORMALLY (node) = 1;
11323       node = patch_incomplete_class_ref (node);
11324       if (node == error_mark_node)
11325         return error_mark_node;
11326       break;
11327
11328     case INSTANCE_INITIALIZERS_EXPR:
11329       in_instance_initializer++;
11330       node = java_complete_tree (TREE_OPERAND (node, 0));
11331       in_instance_initializer--;
11332       if (node != error_mark_node)
11333         TREE_TYPE (node) = void_type_node;
11334       else
11335         return error_mark_node;
11336       break;
11337
11338     default:
11339       CAN_COMPLETE_NORMALLY (node) = 1;
11340       /* Ok: may be we have a STRING_CST or a crafted `StringBuffer'
11341          and it's time to turn it into the appropriate String object */
11342       if ((nn = patch_string (node)))
11343         node = nn;
11344       else
11345         fatal ("No case for tree code `%s' - java_complete_tree\n",
11346                tree_code_name [TREE_CODE (node)]);
11347     }
11348   return node;
11349 }
11350
11351 /* Complete function call's argument. Return a non zero value is an
11352    error was found.  */
11353
11354 static int
11355 complete_function_arguments (node)
11356      tree node;
11357 {
11358   int flag = 0;
11359   tree cn;
11360
11361   ctxp->explicit_constructor_p += (CALL_EXPLICIT_CONSTRUCTOR_P (node) ? 1 : 0);
11362   for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
11363     {
11364       tree wfl = TREE_VALUE (cn), parm, temp;
11365       parm = java_complete_tree (wfl);
11366
11367       if (parm == error_mark_node)
11368         {
11369           flag = 1;
11370           continue;
11371         }
11372       /* If have a string literal that we haven't transformed yet or a
11373          crafted string buffer, as a result of use of the the String
11374          `+' operator. Build `parm.toString()' and expand it. */
11375       if ((temp = patch_string (parm)))
11376         parm = temp;
11377       /* Inline PRIMTYPE.TYPE read access */
11378       parm = maybe_build_primttype_type_ref (parm, wfl);
11379
11380       TREE_VALUE (cn) = parm;
11381     }
11382   ctxp->explicit_constructor_p -= (CALL_EXPLICIT_CONSTRUCTOR_P (node) ? 1 : 0);
11383   return flag;
11384 }
11385
11386 /* Sometimes (for loops and variable initialized during their
11387    declaration), we want to wrap a statement around a WFL and turn it
11388    debugable.  */
11389
11390 static tree
11391 build_debugable_stmt (location, stmt)
11392     int location;
11393     tree stmt;
11394 {
11395   if (TREE_CODE (stmt) != EXPR_WITH_FILE_LOCATION)
11396     {
11397       stmt = build_expr_wfl (stmt, input_filename, 0, 0);
11398       EXPR_WFL_LINECOL (stmt) = location;
11399     }
11400   JAVA_MAYBE_GENERATE_DEBUG_INFO (stmt);
11401   return stmt;
11402 }
11403
11404 static tree
11405 build_expr_block (body, decls)
11406      tree body, decls;
11407 {
11408   tree node = make_node (BLOCK);
11409   BLOCK_EXPR_DECLS (node) = decls;
11410   BLOCK_EXPR_BODY (node) = body;
11411   if (body)
11412     TREE_TYPE (node) = TREE_TYPE (body);
11413   TREE_SIDE_EFFECTS (node) = 1;
11414   return node;
11415 }
11416
11417 /* Create a new function block and link it approriately to current
11418    function block chain */
11419
11420 static tree
11421 enter_block ()
11422 {
11423   return (enter_a_block (build_expr_block (NULL_TREE, NULL_TREE)));
11424 }
11425
11426 /* Link block B supercontext to the previous block. The current
11427    function DECL is used as supercontext when enter_a_block is called
11428    for the first time for a given function. The current function body
11429    (DECL_FUNCTION_BODY) is set to be block B.  */
11430
11431 static tree
11432 enter_a_block (b)
11433      tree b;
11434 {
11435   tree fndecl = current_function_decl; 
11436
11437   if (!fndecl) {
11438     BLOCK_SUPERCONTEXT (b) = current_static_block;
11439     current_static_block = b;
11440   }
11441
11442   else if (!DECL_FUNCTION_BODY (fndecl))
11443     {
11444       BLOCK_SUPERCONTEXT (b) = fndecl;
11445       DECL_FUNCTION_BODY (fndecl) = b;
11446     }
11447   else
11448     {
11449       BLOCK_SUPERCONTEXT (b) = DECL_FUNCTION_BODY (fndecl);
11450       DECL_FUNCTION_BODY (fndecl) = b;
11451     }
11452   return b;
11453 }
11454
11455 /* Exit a block by changing the current function body
11456    (DECL_FUNCTION_BODY) to the current block super context, only if
11457    the block being exited isn't the method's top level one.  */
11458
11459 static tree
11460 exit_block ()
11461 {
11462   tree b;
11463   if (current_function_decl)
11464     {
11465       b = DECL_FUNCTION_BODY (current_function_decl);
11466       if (BLOCK_SUPERCONTEXT (b) != current_function_decl)
11467         DECL_FUNCTION_BODY (current_function_decl) = BLOCK_SUPERCONTEXT (b);
11468     }
11469   else
11470     {
11471       b = current_static_block;
11472
11473       if (BLOCK_SUPERCONTEXT (b))
11474         current_static_block = BLOCK_SUPERCONTEXT (b);
11475     }
11476   return b;
11477 }
11478
11479 /* Lookup for NAME in the nested function's blocks, all the way up to
11480    the current toplevel one. It complies with Java's local variable
11481    scoping rules.  */
11482
11483 static tree
11484 lookup_name_in_blocks (name)
11485      tree name;
11486 {
11487   tree b = GET_CURRENT_BLOCK (current_function_decl);
11488
11489   while (b != current_function_decl)
11490     {
11491       tree current;
11492
11493       /* Paranoid sanity check. To be removed */
11494       if (TREE_CODE (b) != BLOCK)
11495         fatal ("non block expr function body - lookup_name_in_blocks");
11496
11497       for (current = BLOCK_EXPR_DECLS (b); current; 
11498            current = TREE_CHAIN (current))
11499         if (DECL_NAME (current) == name)
11500           return current;
11501       b = BLOCK_SUPERCONTEXT (b);
11502     }
11503   return NULL_TREE;
11504 }
11505
11506 static void
11507 maybe_absorb_scoping_blocks ()
11508 {
11509   while (BLOCK_EXPR_ORIGIN (GET_CURRENT_BLOCK (current_function_decl)))
11510     {
11511       tree b = exit_block ();
11512       java_method_add_stmt (current_function_decl, b);
11513       SOURCE_FRONTEND_DEBUG (("Absorbing scoping block at line %d", lineno));
11514     }
11515 }
11516
11517 \f
11518 /* This section of the source is reserved to build_* functions that
11519    are building incomplete tree nodes and the patch_* functions that
11520    are completing them.  */
11521
11522 /* Wrap a non WFL node around a WFL.  */
11523 static tree
11524 build_wfl_wrap (node, location)
11525     tree node;
11526     int location;
11527 {
11528   tree wfl, node_to_insert = node;
11529   
11530   /* We want to process THIS . xxx symbolicaly, to keep it consistent
11531      with the way we're processing SUPER. A THIS from a primary as a
11532      different form than a SUPER. Turn THIS into something symbolic */
11533   if (TREE_CODE (node) == THIS_EXPR)
11534     node_to_insert = wfl = build_wfl_node (this_identifier_node);
11535   else
11536     wfl = build_expr_wfl (NULL_TREE, ctxp->filename, 0, 0);
11537
11538   EXPR_WFL_LINECOL (wfl) = location;
11539   EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (node_to_insert, NULL_TREE);
11540   return wfl;
11541 }
11542
11543
11544 /* Build a super() constructor invocation. Returns empty_stmt_node if
11545    we're currently dealing with the class java.lang.Object. */
11546
11547 static tree
11548 build_super_invocation (mdecl)
11549      tree mdecl;
11550 {
11551   if (DECL_CONTEXT (mdecl) == object_type_node)
11552     return empty_stmt_node;
11553   else
11554     {
11555       tree super_wfl = build_wfl_node (super_identifier_node);
11556       tree a = NULL_TREE, t;
11557       /* If we're dealing with an anonymous class, pass the arguments
11558          of the crafted constructor along. */
11559       if (ANONYMOUS_CLASS_P (DECL_CONTEXT (mdecl)))
11560         {
11561           SKIP_THIS_AND_ARTIFICIAL_PARMS (t, mdecl);
11562           for (; t != end_params_node; t = TREE_CHAIN (t))
11563             a = tree_cons (NULL_TREE, build_wfl_node (TREE_PURPOSE (t)), a);
11564         }
11565       return build_method_invocation (super_wfl, a);
11566     }
11567 }
11568
11569 /* Build a SUPER/THIS qualified method invocation.  */
11570
11571 static tree
11572 build_this_super_qualified_invocation (use_this, name, args, lloc, rloc)
11573      int use_this;
11574      tree name, args;
11575      int lloc, rloc;
11576 {
11577   tree invok;
11578   tree wfl = 
11579     build_wfl_node (use_this ? this_identifier_node : super_identifier_node);
11580   EXPR_WFL_LINECOL (wfl) = lloc;
11581   invok = build_method_invocation (name, args);
11582   return make_qualified_primary (wfl, invok, rloc);
11583 }
11584
11585 /* Build an incomplete CALL_EXPR node. */
11586
11587 static tree
11588 build_method_invocation (name, args)
11589     tree name;
11590     tree args;
11591 {
11592   tree call = build (CALL_EXPR, NULL_TREE, name, args, NULL_TREE);
11593   TREE_SIDE_EFFECTS (call) = 1;
11594   EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
11595   return call;
11596 }
11597
11598 /* Build an incomplete new xxx(...) node. */
11599
11600 static tree
11601 build_new_invocation (name, args)
11602     tree name, args;
11603 {
11604   tree call = build (NEW_CLASS_EXPR, NULL_TREE, name, args, NULL_TREE);
11605   TREE_SIDE_EFFECTS (call) = 1;
11606   EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
11607   return call;
11608 }
11609
11610 /* Build an incomplete assignment expression. */
11611
11612 static tree
11613 build_assignment (op, op_location, lhs, rhs)
11614      int op, op_location;
11615      tree lhs, rhs;
11616 {
11617   tree assignment;
11618   /* Build the corresponding binop if we deal with a Compound
11619      Assignment operator. Mark the binop sub-tree as part of a
11620      Compound Assignment expression */
11621   if (op != ASSIGN_TK)
11622     {
11623       rhs = build_binop (BINOP_LOOKUP (op), op_location, lhs, rhs);
11624       COMPOUND_ASSIGN_P (rhs) = 1;
11625     }
11626   assignment = build (MODIFY_EXPR, NULL_TREE, lhs, rhs);
11627   TREE_SIDE_EFFECTS (assignment) = 1;
11628   EXPR_WFL_LINECOL (assignment) = op_location;
11629   return assignment;
11630 }
11631
11632 /* Print an INTEGER_CST node in a static buffer, and return the buffer. */
11633
11634 char *
11635 print_int_node (node)
11636     tree node;
11637 {
11638   static char buffer [80];
11639   if (TREE_CONSTANT_OVERFLOW (node))
11640     sprintf (buffer, "<overflow>");
11641     
11642   if (TREE_INT_CST_HIGH (node) == 0)
11643     sprintf (buffer, HOST_WIDE_INT_PRINT_UNSIGNED,
11644              TREE_INT_CST_LOW (node));
11645   else if (TREE_INT_CST_HIGH (node) == -1
11646            && TREE_INT_CST_LOW (node) != 0)
11647     {
11648       buffer [0] = '-';
11649       sprintf (&buffer [1], HOST_WIDE_INT_PRINT_UNSIGNED,
11650                -TREE_INT_CST_LOW (node));
11651     }
11652   else
11653     sprintf (buffer, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
11654              TREE_INT_CST_HIGH (node), TREE_INT_CST_LOW (node));
11655
11656   return buffer;
11657 }
11658
11659 /* Return 1 if an assignment to a FINAL is attempted in a non suitable
11660    context.  */
11661
11662 static int
11663 check_final_assignment (lvalue, wfl)
11664      tree lvalue, wfl;
11665 {
11666   if (TREE_CODE (lvalue) == COMPOUND_EXPR 
11667       && JDECL_P (TREE_OPERAND (lvalue, 1)))
11668     lvalue = TREE_OPERAND (lvalue, 1);
11669
11670   /* When generating class files, references to the `length' field
11671      look a bit different.  */
11672   if ((flag_emit_class_files
11673        && TREE_CODE (lvalue) == COMPONENT_REF
11674        && TYPE_ARRAY_P (TREE_TYPE (TREE_OPERAND (lvalue, 0)))
11675        && FIELD_FINAL (TREE_OPERAND (lvalue, 1)))
11676       || (TREE_CODE (lvalue) == FIELD_DECL
11677           && FIELD_FINAL (lvalue)
11678           && !DECL_CLINIT_P (current_function_decl)
11679           && !DECL_FINIT_P (current_function_decl)))
11680     {
11681       parse_error_context 
11682         (wfl, "Can't assign a value to the final variable `%s'",
11683          IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
11684       return 1;
11685     }
11686   return 0;
11687 }
11688
11689 /* Inline references to java.lang.PRIMTYPE.TYPE when accessed in
11690    read. This is needed to avoid circularities in the implementation
11691    of these fields in libjava. */
11692
11693 static tree
11694 maybe_build_primttype_type_ref (rhs, wfl)
11695     tree rhs, wfl;
11696 {
11697   tree to_return = NULL_TREE;
11698   tree rhs_type = TREE_TYPE (rhs);
11699   if (TREE_CODE (rhs) == COMPOUND_EXPR)
11700     {
11701       tree n = TREE_OPERAND (rhs, 1);
11702       if (TREE_CODE (n) == VAR_DECL 
11703           && DECL_NAME (n) == TYPE_identifier_node
11704           && rhs_type == class_ptr_type
11705           && TREE_CODE (EXPR_WFL_NODE (wfl)) == IDENTIFIER_NODE)
11706         {
11707           const char *self_name = IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl));
11708           if (!strncmp (self_name, "java.lang.", 10))
11709             to_return = build_primtype_type_ref (self_name);
11710         }
11711     }
11712   return (to_return ? to_return : rhs );
11713 }
11714
11715 /* 15.25 Assignment operators. */
11716
11717 static tree
11718 patch_assignment (node, wfl_op1, wfl_op2)
11719      tree node;
11720      tree wfl_op1;
11721      tree wfl_op2;
11722 {
11723   tree rhs = TREE_OPERAND (node, 1);
11724   tree lvalue = TREE_OPERAND (node, 0), llvalue;
11725   tree lhs_type = NULL_TREE, rhs_type, new_rhs = NULL_TREE;
11726   int error_found = 0;
11727   int lvalue_from_array = 0;
11728
11729   /* Can't assign to a (blank) final. */
11730   if (check_final_assignment (lvalue, wfl_op1))
11731     error_found = 1;
11732
11733   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11734
11735   /* Lhs can be a named variable */
11736   if (JDECL_P (lvalue))
11737     {
11738       lhs_type = TREE_TYPE (lvalue);
11739     }
11740   /* Or Lhs can be a array acccess. Should that be lvalue ? FIXME +
11741      comment on reason why */
11742   else if (TREE_CODE (wfl_op1) == ARRAY_REF)
11743     {
11744       lhs_type = TREE_TYPE (lvalue);
11745       lvalue_from_array = 1;
11746     }
11747   /* Or a field access */
11748   else if (TREE_CODE (lvalue) == COMPONENT_REF)
11749     lhs_type = TREE_TYPE (lvalue);
11750   /* Or a function return slot */
11751   else if (TREE_CODE (lvalue) == RESULT_DECL)
11752     lhs_type = TREE_TYPE (lvalue);
11753   /* Otherwise, we might want to try to write into an optimized static
11754      final, this is an of a different nature, reported further on. */
11755   else if (TREE_CODE (wfl_op1) == EXPR_WITH_FILE_LOCATION
11756            && resolve_expression_name (wfl_op1, &llvalue))
11757     {
11758       if (!error_found && check_final_assignment (llvalue, wfl_op1))
11759         {
11760           /* What we should do instead is resetting the all the flags
11761              previously set, exchange lvalue for llvalue and continue. */
11762           error_found = 1;
11763           return error_mark_node;
11764         }
11765       else 
11766         lhs_type = TREE_TYPE (lvalue);
11767     }
11768   else 
11769     {
11770       parse_error_context (wfl_op1, "Invalid left hand side of assignment");
11771       error_found = 1;
11772     }
11773
11774   rhs_type = TREE_TYPE (rhs);
11775   /* 5.1 Try the assignment conversion for builtin type. */
11776   new_rhs = try_builtin_assignconv (wfl_op1, lhs_type, rhs);
11777
11778   /* 5.2 If it failed, try a reference conversion */
11779   if (!new_rhs && (new_rhs = try_reference_assignconv (lhs_type, rhs)))
11780     lhs_type = promote_type (rhs_type);
11781
11782   /* 15.25.2 If we have a compound assignment, convert RHS into the
11783      type of the LHS */
11784   else if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
11785     new_rhs = convert (lhs_type, rhs);
11786
11787   /* Explicit cast required. This is an error */
11788   if (!new_rhs)
11789     {
11790       char *t1 = xstrdup (lang_printable_name (TREE_TYPE (rhs), 0));
11791       char *t2 = xstrdup (lang_printable_name (lhs_type, 0));
11792       tree wfl;
11793       char operation [32];      /* Max size known */
11794
11795       /* If the assignment is part of a declaration, we use the WFL of
11796          the declared variable to point out the error and call it a
11797          declaration problem. If the assignment is a genuine =
11798          operator, we call is a operator `=' problem, otherwise we
11799          call it an assignment problem. In both of these last cases,
11800          we use the WFL of the operator to indicate the error. */
11801
11802       if (MODIFY_EXPR_FROM_INITIALIZATION_P (node))
11803         {
11804           wfl = wfl_op1;
11805           strcpy (operation, "declaration");
11806         }
11807       else
11808         {
11809           wfl = wfl_operator;
11810           if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
11811             strcpy (operation, "assignment");
11812           else if (TREE_CODE (TREE_OPERAND (node, 0)) == RESULT_DECL)
11813             strcpy (operation, "`return'");
11814           else
11815             strcpy (operation, "`='");
11816         }
11817
11818       if (!valid_cast_to_p (rhs_type, lhs_type))
11819         parse_error_context
11820           (wfl, "Incompatible type for %s. Can't convert `%s' to `%s'",
11821            operation, t1, t2);
11822       else
11823         parse_error_context (wfl, "Incompatible type for %s. Explicit cast needed to convert `%s' to `%s'",
11824                              operation, t1, t2);
11825       free (t1); free (t2);
11826       error_found = 1;
11827     }
11828
11829   /* Inline read access to java.lang.PRIMTYPE.TYPE */
11830   if (new_rhs)
11831     new_rhs = maybe_build_primttype_type_ref (new_rhs, wfl_op2);
11832
11833   if (error_found)
11834     return error_mark_node;
11835
11836   /* 10.10: Array Store Exception runtime check */
11837   if (!flag_emit_class_files
11838       && !flag_emit_xref
11839       && lvalue_from_array 
11840       && JREFERENCE_TYPE_P (TYPE_ARRAY_ELEMENT (lhs_type)))
11841     {
11842       tree check;
11843       tree base = lvalue;
11844
11845       /* We need to retrieve the right argument for _Jv_CheckArrayStore */
11846       if (TREE_CODE (lvalue) == COMPOUND_EXPR)
11847         base = TREE_OPERAND (lvalue, 0);
11848       else
11849         {
11850           if (flag_bounds_check)
11851             base = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (base, 0), 1), 0);
11852           else
11853             base = TREE_OPERAND (TREE_OPERAND (base, 0), 0);
11854         }
11855
11856       /* Build the invocation of _Jv_CheckArrayStore */
11857       new_rhs = save_expr (new_rhs);
11858       check = build (CALL_EXPR, void_type_node,
11859                      build_address_of (soft_checkarraystore_node),
11860                      tree_cons (NULL_TREE, base,
11861                                 build_tree_list (NULL_TREE, new_rhs)),
11862                      NULL_TREE);
11863       TREE_SIDE_EFFECTS (check) = 1;
11864
11865       /* We have to decide on an insertion point */
11866       if (TREE_CODE (lvalue) == COMPOUND_EXPR)
11867         {
11868           tree t;
11869           if (flag_bounds_check)
11870             {
11871               t = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (lvalue, 1), 0), 0);
11872               TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (lvalue, 1), 0), 0) =
11873                 build (COMPOUND_EXPR, void_type_node, t, check);
11874             }
11875           else
11876             TREE_OPERAND (lvalue, 1) = build (COMPOUND_EXPR, lhs_type,
11877                                               check, TREE_OPERAND (lvalue, 1));
11878         }
11879       else 
11880         {
11881           /* Make sure the bound check will happen before the store check */
11882           if (flag_bounds_check)
11883             TREE_OPERAND (TREE_OPERAND (lvalue, 0), 0) =
11884               build (COMPOUND_EXPR, void_type_node,
11885                      TREE_OPERAND (TREE_OPERAND (lvalue, 0), 0), check);
11886           else
11887             lvalue = build (COMPOUND_EXPR, lhs_type, check, lvalue);
11888         }
11889     }
11890
11891   TREE_OPERAND (node, 0) = lvalue;
11892   TREE_OPERAND (node, 1) = new_rhs;
11893   TREE_TYPE (node) = lhs_type;
11894   return node;
11895 }
11896
11897 /* Check that type SOURCE can be cast into type DEST. If the cast
11898    can't occur at all, return 0 otherwise 1. This function is used to
11899    produce accurate error messages on the reasons why an assignment
11900    failed. */
11901
11902 static tree
11903 try_reference_assignconv (lhs_type, rhs)
11904      tree lhs_type, rhs;
11905 {
11906   tree new_rhs = NULL_TREE;
11907   tree rhs_type = TREE_TYPE (rhs);
11908
11909   if (!JPRIMITIVE_TYPE_P (rhs_type) && JREFERENCE_TYPE_P (lhs_type))
11910     {
11911       /* `null' may be assigned to any reference type */
11912       if (rhs == null_pointer_node)
11913         new_rhs = null_pointer_node;
11914       /* Try the reference assignment conversion */
11915       else if (valid_ref_assignconv_cast_p (rhs_type, lhs_type, 0))
11916         new_rhs = rhs;
11917       /* This is a magic assignment that we process differently */
11918       else if (rhs == soft_exceptioninfo_call_node)
11919         new_rhs = rhs;
11920     }
11921   return new_rhs;
11922 }
11923
11924 /* Check that RHS can be converted into LHS_TYPE by the assignment
11925    conversion (5.2), for the cases of RHS being a builtin type. Return
11926    NULL_TREE if the conversion fails or if because RHS isn't of a
11927    builtin type. Return a converted RHS if the conversion is possible.  */
11928
11929 static tree
11930 try_builtin_assignconv (wfl_op1, lhs_type, rhs)
11931      tree wfl_op1, lhs_type, rhs;
11932 {
11933   tree new_rhs = NULL_TREE;
11934   tree rhs_type = TREE_TYPE (rhs);
11935
11936   /* Zero accepted everywhere */
11937   if (TREE_CODE (rhs) == INTEGER_CST 
11938       && TREE_INT_CST_HIGH (rhs) == 0 && TREE_INT_CST_LOW (rhs) == 0
11939       && JPRIMITIVE_TYPE_P (rhs_type))
11940     new_rhs = convert (lhs_type, rhs);
11941
11942   /* 5.1.1 Try Identity Conversion,
11943      5.1.2 Try Widening Primitive Conversion */
11944   else if (valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type))
11945     new_rhs = convert (lhs_type, rhs);
11946
11947   /* Try a narrowing primitive conversion (5.1.3): 
11948        - expression is a constant expression of type int AND
11949        - variable is byte, short or char AND
11950        - The value of the expression is representable in the type of the 
11951          variable */
11952   else if (rhs_type == int_type_node && TREE_CONSTANT (rhs)
11953            && (lhs_type == byte_type_node || lhs_type == char_type_node
11954                || lhs_type == short_type_node))
11955     {
11956       if (int_fits_type_p (rhs, lhs_type))
11957         new_rhs = convert (lhs_type, rhs);
11958       else if (wfl_op1)         /* Might be called with a NULL */
11959         parse_warning_context 
11960           (wfl_op1, "Constant expression `%s' to wide for narrowing primitive conversion to `%s'", 
11961            print_int_node (rhs), lang_printable_name (lhs_type, 0));
11962       /* Reported a warning that will turn into an error further
11963          down, so we don't return */
11964     }
11965
11966   return new_rhs;
11967 }
11968
11969 /* Return 1 if RHS_TYPE can be converted to LHS_TYPE by identity
11970    conversion (5.1.1) or widening primitve conversion (5.1.2).  Return
11971    0 is the conversion test fails.  This implements parts the method
11972    invocation convertion (5.3).  */
11973
11974 static int
11975 valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type)
11976      tree lhs_type, rhs_type;
11977 {
11978   /* 5.1.1: This is the identity conversion part. */
11979   if (lhs_type == rhs_type)
11980     return 1;
11981
11982   /* Reject non primitive types */
11983   if (!JPRIMITIVE_TYPE_P (lhs_type) || !JPRIMITIVE_TYPE_P (rhs_type))
11984     return 0;
11985
11986   /* 5.1.2: widening primitive conversion. byte, even if it's smaller
11987      than a char can't be converted into a char. Short can't too, but
11988      the < test below takes care of that */
11989   if (lhs_type == char_type_node && rhs_type == byte_type_node)
11990     return 0;
11991
11992   /* Accept all promoted type here. Note, we can't use <= in the test
11993      below, because we still need to bounce out assignments of short
11994      to char and the likes */
11995   if (lhs_type == int_type_node
11996       && (rhs_type == promoted_byte_type_node
11997           || rhs_type == promoted_short_type_node
11998           || rhs_type == promoted_char_type_node
11999           || rhs_type == promoted_boolean_type_node))
12000     return 1;
12001
12002   /* From here, an integral is widened if its precision is smaller
12003      than the precision of the LHS or if the LHS is a floating point
12004      type, or the RHS is a float and the RHS a double. */
12005   if ((JINTEGRAL_TYPE_P (rhs_type) && JINTEGRAL_TYPE_P (lhs_type) 
12006        && (TYPE_PRECISION (rhs_type) < TYPE_PRECISION (lhs_type)))
12007       || (JINTEGRAL_TYPE_P (rhs_type) && JFLOAT_TYPE_P (lhs_type))
12008       || (rhs_type == float_type_node && lhs_type == double_type_node))
12009     return 1;
12010
12011   return 0;
12012 }
12013
12014 /* Check that something of SOURCE type can be assigned or cast to
12015    something of DEST type at runtime. Return 1 if the operation is
12016    valid, 0 otherwise. If CAST is set to 1, we're treating the case
12017    were SOURCE is cast into DEST, which borrows a lot of the
12018    assignment check. */
12019
12020 static int
12021 valid_ref_assignconv_cast_p (source, dest, cast)
12022      tree source;
12023      tree dest;
12024      int cast;
12025 {
12026   /* SOURCE or DEST might be null if not from a declared entity. */
12027   if (!source || !dest)
12028     return 0;
12029   if (JNULLP_TYPE_P (source))
12030     return 1;
12031   if (TREE_CODE (source) == POINTER_TYPE)
12032     source = TREE_TYPE (source);
12033   if (TREE_CODE (dest) == POINTER_TYPE)
12034     dest = TREE_TYPE (dest);
12035   /* Case where SOURCE is a class type */
12036   if (TYPE_CLASS_P (source))
12037     {
12038       if (TYPE_CLASS_P (dest))
12039         return  (source == dest 
12040                  || inherits_from_p (source, dest)
12041                  || enclosing_context_p (dest, source /*source, dest*/)
12042                  || (cast && inherits_from_p (dest, source)));
12043       if (TYPE_INTERFACE_P (dest))
12044         {
12045           /* If doing a cast and SOURCE is final, the operation is
12046              always correct a compile time (because even if SOURCE
12047              does not implement DEST, a subclass of SOURCE might). */
12048           if (cast && !CLASS_FINAL (TYPE_NAME (source)))
12049             return 1;
12050           /* Otherwise, SOURCE must implement DEST */
12051           return interface_of_p (dest, source);
12052         }
12053       /* DEST is an array, cast permited if SOURCE is of Object type */
12054       return (cast && source == object_type_node ? 1 : 0);
12055     }
12056   if (TYPE_INTERFACE_P (source))
12057     {
12058       if (TYPE_CLASS_P (dest))
12059         {
12060           /* If not casting, DEST must be the Object type */
12061           if (!cast)
12062             return dest == object_type_node;
12063           /* We're doing a cast. The cast is always valid is class
12064              DEST is not final, otherwise, DEST must implement SOURCE */
12065           else if (!CLASS_FINAL (TYPE_NAME (dest)))
12066             return 1;
12067           else
12068             return interface_of_p (source, dest);
12069         }
12070       if (TYPE_INTERFACE_P (dest))
12071         {
12072           /* If doing a cast, then if SOURCE and DEST contain method
12073              with the same signature but different return type, then
12074              this is a (compile time) error */
12075           if (cast)
12076             {
12077               tree method_source, method_dest;
12078               tree source_type;
12079               tree source_sig;
12080               tree source_name;
12081               for (method_source = TYPE_METHODS (source); method_source; 
12082                    method_source = TREE_CHAIN (method_source))
12083                 {
12084                   source_sig = 
12085                     build_java_argument_signature (TREE_TYPE (method_source));
12086                   source_type = TREE_TYPE (TREE_TYPE (method_source));
12087                   source_name = DECL_NAME (method_source);
12088                   for (method_dest = TYPE_METHODS (dest);
12089                        method_dest; method_dest = TREE_CHAIN (method_dest))
12090                     if (source_sig == 
12091                         build_java_argument_signature (TREE_TYPE (method_dest))
12092                         && source_name == DECL_NAME (method_dest)
12093                         && source_type != TREE_TYPE (TREE_TYPE (method_dest)))
12094                       return 0;
12095                 }
12096               return 1;
12097             }
12098           else
12099             return source == dest || interface_of_p (dest, source);
12100         }
12101       else                      /* Array */
12102         return (cast ? 
12103                 (DECL_NAME (TYPE_NAME (source)) == java_lang_cloneable) : 0);
12104     }
12105   if (TYPE_ARRAY_P (source))
12106     {
12107       if (TYPE_CLASS_P (dest))
12108         return dest == object_type_node;
12109       /* Can't cast an array to an interface unless the interface is
12110          java.lang.Cloneable */
12111       if (TYPE_INTERFACE_P (dest))
12112         return (DECL_NAME (TYPE_NAME (dest)) == java_lang_cloneable ? 1 : 0);
12113       else                      /* Arrays */
12114         {
12115           tree source_element_type = TYPE_ARRAY_ELEMENT (source);
12116           tree dest_element_type = TYPE_ARRAY_ELEMENT (dest);
12117           
12118           /* In case of severe errors, they turn out null */
12119           if (!dest_element_type || !source_element_type)
12120             return 0;
12121           if (source_element_type == dest_element_type)
12122             return 1;
12123           return valid_ref_assignconv_cast_p (source_element_type,
12124                                               dest_element_type, cast);
12125         }
12126       return 0;
12127     }
12128   return 0;
12129 }
12130
12131 static int
12132 valid_cast_to_p (source, dest)
12133      tree source;
12134      tree dest;
12135 {
12136   if (TREE_CODE (source) == POINTER_TYPE)
12137     source = TREE_TYPE (source);
12138   if (TREE_CODE (dest) == POINTER_TYPE)
12139     dest = TREE_TYPE (dest);
12140
12141   if (TREE_CODE (source) == RECORD_TYPE && TREE_CODE (dest) == RECORD_TYPE)
12142     return valid_ref_assignconv_cast_p (source, dest, 1);
12143
12144   else if (JNUMERIC_TYPE_P (source) && JNUMERIC_TYPE_P (dest))
12145     return 1;
12146
12147   return 0;
12148 }
12149
12150 /* Method invocation conversion test. Return 1 if type SOURCE can be
12151    converted to type DEST through the methond invocation conversion
12152    process (5.3) */
12153
12154 static tree
12155 do_unary_numeric_promotion (arg)
12156      tree arg;
12157 {
12158   tree type = TREE_TYPE (arg);
12159   if (TREE_CODE (type) == INTEGER_TYPE ? TYPE_PRECISION (type) < 32
12160       : TREE_CODE (type) == CHAR_TYPE)
12161     arg = convert (int_type_node, arg);
12162   return arg;
12163 }
12164
12165 /* Return a non zero value if SOURCE can be converted into DEST using
12166    the method invocation conversion rule (5.3).  */
12167 static int
12168 valid_method_invocation_conversion_p (dest, source)
12169      tree dest, source;
12170 {
12171   return ((JPRIMITIVE_TYPE_P (source) && JPRIMITIVE_TYPE_P (dest)
12172            && valid_builtin_assignconv_identity_widening_p (dest, source))
12173           || ((JREFERENCE_TYPE_P (source) || JNULLP_TYPE_P (source))
12174               && (JREFERENCE_TYPE_P (dest) || JNULLP_TYPE_P (dest))
12175               && valid_ref_assignconv_cast_p (source, dest, 0)));
12176 }
12177
12178 /* Build an incomplete binop expression. */
12179
12180 static tree
12181 build_binop (op, op_location, op1, op2)
12182      enum tree_code op;
12183      int op_location;
12184      tree op1, op2;
12185 {
12186   tree binop = build (op, NULL_TREE, op1, op2);
12187   TREE_SIDE_EFFECTS (binop) = 1;
12188   /* Store the location of the operator, for better error report. The
12189      string of the operator will be rebuild based on the OP value. */
12190   EXPR_WFL_LINECOL (binop) = op_location;
12191   return binop;
12192 }
12193
12194 /* Build the string of the operator retained by NODE. If NODE is part
12195    of a compound expression, add an '=' at the end of the string. This
12196    function is called when an error needs to be reported on an
12197    operator. The string is returned as a pointer to a static character
12198    buffer. */
12199
12200 static char *
12201 operator_string (node)
12202      tree node;
12203 {
12204 #define BUILD_OPERATOR_STRING(S)                                        \
12205   {                                                                     \
12206     sprintf (buffer, "%s%s", S, (COMPOUND_ASSIGN_P (node) ? "=" : "")); \
12207     return buffer;                                                      \
12208   }
12209   
12210   static char buffer [10];
12211   switch (TREE_CODE (node))
12212     {
12213     case MULT_EXPR: BUILD_OPERATOR_STRING ("*");
12214     case RDIV_EXPR: BUILD_OPERATOR_STRING ("/");
12215     case TRUNC_MOD_EXPR: BUILD_OPERATOR_STRING ("%");
12216     case PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
12217     case MINUS_EXPR: BUILD_OPERATOR_STRING ("-");
12218     case LSHIFT_EXPR: BUILD_OPERATOR_STRING ("<<");
12219     case RSHIFT_EXPR: BUILD_OPERATOR_STRING (">>");
12220     case URSHIFT_EXPR: BUILD_OPERATOR_STRING (">>>");
12221     case BIT_AND_EXPR: BUILD_OPERATOR_STRING ("&");
12222     case BIT_XOR_EXPR: BUILD_OPERATOR_STRING ("^");
12223     case BIT_IOR_EXPR: BUILD_OPERATOR_STRING ("|");
12224     case TRUTH_ANDIF_EXPR: BUILD_OPERATOR_STRING ("&&");
12225     case TRUTH_ORIF_EXPR: BUILD_OPERATOR_STRING ("||");
12226     case EQ_EXPR: BUILD_OPERATOR_STRING ("==");
12227     case NE_EXPR: BUILD_OPERATOR_STRING ("!=");
12228     case GT_EXPR: BUILD_OPERATOR_STRING (">");
12229     case GE_EXPR: BUILD_OPERATOR_STRING (">=");
12230     case LT_EXPR: BUILD_OPERATOR_STRING ("<");
12231     case LE_EXPR: BUILD_OPERATOR_STRING ("<=");
12232     case UNARY_PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
12233     case NEGATE_EXPR: BUILD_OPERATOR_STRING ("-");
12234     case TRUTH_NOT_EXPR: BUILD_OPERATOR_STRING ("!");
12235     case BIT_NOT_EXPR: BUILD_OPERATOR_STRING ("~");
12236     case PREINCREMENT_EXPR:     /* Fall through */
12237     case POSTINCREMENT_EXPR: BUILD_OPERATOR_STRING ("++");
12238     case PREDECREMENT_EXPR:     /* Fall through */
12239     case POSTDECREMENT_EXPR: BUILD_OPERATOR_STRING ("--");
12240     default:
12241       fatal ("unregistered operator %s - operator_string",
12242              tree_code_name [TREE_CODE (node)]);
12243     }
12244   return NULL;
12245 #undef BUILD_OPERATOR_STRING
12246 }
12247
12248 /* Return 1 if VAR_ACCESS1 is equivalent to VAR_ACCESS2.  */
12249
12250 static int
12251 java_decl_equiv (var_acc1, var_acc2)
12252      tree var_acc1, var_acc2;
12253 {
12254   if (JDECL_P (var_acc1))
12255     return (var_acc1 == var_acc2);
12256   
12257   return (TREE_CODE (var_acc1) == COMPONENT_REF
12258           && TREE_CODE (var_acc2) == COMPONENT_REF
12259           && TREE_OPERAND (TREE_OPERAND (var_acc1, 0), 0)
12260              == TREE_OPERAND (TREE_OPERAND (var_acc2, 0), 0)
12261           && TREE_OPERAND (var_acc1, 1) == TREE_OPERAND (var_acc2, 1));
12262 }
12263
12264 /* Return a non zero value if CODE is one of the operators that can be
12265    used in conjunction with the `=' operator in a compound assignment.  */
12266
12267 static int
12268 binop_compound_p (code)
12269     enum tree_code code;
12270 {
12271   int i;
12272   for (i = 0; i < BINOP_COMPOUND_CANDIDATES; i++)
12273     if (binop_lookup [i] == code)
12274       break;
12275
12276   return i < BINOP_COMPOUND_CANDIDATES;
12277 }
12278
12279 /* Reorganize after a fold to get SAVE_EXPR to generate what we want.  */
12280
12281 static tree
12282 java_refold (t)
12283      tree t;
12284 {
12285   tree c, b, ns, decl;
12286
12287   if (TREE_CODE (t) != MODIFY_EXPR)
12288     return t;
12289
12290   c = TREE_OPERAND (t, 1);
12291   if (! (c && TREE_CODE (c) == COMPOUND_EXPR
12292          && TREE_CODE (TREE_OPERAND (c, 0)) == MODIFY_EXPR
12293          && binop_compound_p (TREE_CODE (TREE_OPERAND (c, 1)))))
12294     return t;
12295
12296   /* Now the left branch of the binary operator. */
12297   b = TREE_OPERAND (TREE_OPERAND (c, 1), 0);
12298   if (! (b && TREE_CODE (b) == NOP_EXPR 
12299          && TREE_CODE (TREE_OPERAND (b, 0)) == SAVE_EXPR))
12300     return t;
12301
12302   ns = TREE_OPERAND (TREE_OPERAND (b, 0), 0);
12303   if (! (ns && TREE_CODE (ns) == NOP_EXPR
12304          && TREE_CODE (TREE_OPERAND (ns, 0)) == SAVE_EXPR))
12305     return t;
12306
12307   decl = TREE_OPERAND (TREE_OPERAND (ns, 0), 0);
12308   if ((JDECL_P (decl) || TREE_CODE (decl) == COMPONENT_REF)
12309       /* It's got to be the an equivalent decl */
12310       && java_decl_equiv (decl, TREE_OPERAND (TREE_OPERAND (c, 0), 0)))
12311     {
12312       /* Shorten the NOP_EXPR/SAVE_EXPR path. */
12313       TREE_OPERAND (TREE_OPERAND (c, 1), 0) = TREE_OPERAND (ns, 0);
12314       /* Substitute the COMPOUND_EXPR by the BINOP_EXPR */
12315       TREE_OPERAND (t, 1) = TREE_OPERAND (c, 1);
12316       /* Change the right part of the BINOP_EXPR */
12317       TREE_OPERAND (TREE_OPERAND (t, 1), 1) = TREE_OPERAND (c, 0);
12318     }
12319
12320   return t;
12321 }
12322
12323 /* Binary operators (15.16 up to 15.18). We return error_mark_node on
12324    errors but we modify NODE so that it contains the type computed
12325    according to the expression, when it's fixed. Otherwise, we write
12326    error_mark_node as the type. It allows us to further the analysis
12327    of remaining nodes and detects more errors in certain cases.  */
12328
12329 static tree
12330 patch_binop (node, wfl_op1, wfl_op2)
12331      tree node;
12332      tree wfl_op1;
12333      tree wfl_op2;
12334 {
12335   tree op1 = TREE_OPERAND (node, 0);
12336   tree op2 = TREE_OPERAND (node, 1);
12337   tree op1_type = TREE_TYPE (op1);
12338   tree op2_type = TREE_TYPE (op2);
12339   tree prom_type = NULL_TREE, cn;
12340   int code = TREE_CODE (node);
12341
12342   /* If 1, tell the routine that we have to return error_mark_node
12343      after checking for the initialization of the RHS */
12344   int error_found = 0;
12345
12346   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
12347
12348   switch (code)
12349     {
12350     /* 15.16 Multiplicative operators */
12351     case MULT_EXPR:             /* 15.16.1 Multiplication Operator * */
12352     case RDIV_EXPR:             /* 15.16.2 Division Operator / */
12353     case TRUNC_DIV_EXPR:        /* 15.16.2 Integral type Division Operator / */
12354     case TRUNC_MOD_EXPR:        /* 15.16.3 Remainder operator % */
12355       if (!JPRIMITIVE_TYPE_P (op1_type) || !JPRIMITIVE_TYPE_P (op2_type))
12356         {
12357           if (!JPRIMITIVE_TYPE_P (op1_type))
12358             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
12359           if (!JPRIMITIVE_TYPE_P (op2_type) && (op1_type != op2_type))
12360             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
12361           TREE_TYPE (node) = error_mark_node;
12362           error_found = 1;
12363           break;
12364         }
12365       prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12366       /* Change the division operator if necessary */
12367       if (code == RDIV_EXPR && TREE_CODE (prom_type) == INTEGER_TYPE)
12368         TREE_SET_CODE (node, TRUNC_DIV_EXPR);
12369
12370       if (TREE_CODE (prom_type) == INTEGER_TYPE
12371           && flag_use_divide_subroutine
12372           && ! flag_emit_class_files
12373           && (code == RDIV_EXPR || code == TRUNC_MOD_EXPR))
12374         return build_java_soft_divmod (TREE_CODE (node), prom_type, op1, op2);
12375  
12376       /* This one is more complicated. FLOATs are processed by a
12377          function call to soft_fmod. Duplicate the value of the
12378          COMPOUND_ASSIGN_P flag. */
12379       if (code == TRUNC_MOD_EXPR)
12380         {
12381           tree mod = build_java_binop (TRUNC_MOD_EXPR, prom_type, op1, op2);
12382           COMPOUND_ASSIGN_P (mod) = COMPOUND_ASSIGN_P (node);
12383           TREE_SIDE_EFFECTS (mod)
12384             = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
12385           return mod;
12386         }
12387       break;
12388
12389     /* 15.17 Additive Operators */
12390     case PLUS_EXPR:             /* 15.17.1 String Concatenation Operator + */
12391
12392       /* Operation is valid if either one argument is a string
12393          constant, a String object or a StringBuffer crafted for the
12394          purpose of the a previous usage of the String concatenation
12395          operator */
12396
12397       if (TREE_CODE (op1) == STRING_CST 
12398           || TREE_CODE (op2) == STRING_CST
12399           || JSTRING_TYPE_P (op1_type)
12400           || JSTRING_TYPE_P (op2_type)
12401           || IS_CRAFTED_STRING_BUFFER_P (op1)
12402           || IS_CRAFTED_STRING_BUFFER_P (op2))
12403         return build_string_concatenation (op1, op2);
12404
12405     case MINUS_EXPR:            /* 15.17.2 Additive Operators (+ and -) for
12406                                    Numeric Types */
12407       if (!JPRIMITIVE_TYPE_P (op1_type) || !JPRIMITIVE_TYPE_P (op2_type))
12408         {
12409           if (!JPRIMITIVE_TYPE_P (op1_type))
12410             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
12411           if (!JPRIMITIVE_TYPE_P (op2_type) && (op1_type != op2_type))
12412             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
12413           TREE_TYPE (node) = error_mark_node;
12414           error_found = 1;
12415           break;
12416         }
12417       prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12418       break;
12419
12420     /* 15.18 Shift Operators */
12421     case LSHIFT_EXPR:
12422     case RSHIFT_EXPR:
12423     case URSHIFT_EXPR:
12424       if (!JINTEGRAL_TYPE_P (op1_type) || !JINTEGRAL_TYPE_P (op2_type))
12425         {
12426           if (!JINTEGRAL_TYPE_P (op1_type))
12427             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
12428           else
12429             {
12430               if (JPRIMITIVE_TYPE_P (op2_type))
12431                 parse_error_context (wfl_operator,
12432                                      "Incompatible type for `%s'. Explicit cast needed to convert shift distance from `%s' to integral",
12433                                      operator_string (node),
12434                                      lang_printable_name (op2_type, 0));
12435               else
12436                 parse_error_context (wfl_operator,
12437                                      "Incompatible type for `%s'. Can't convert shift distance from `%s' to integral", 
12438                                      operator_string (node),
12439                                      lang_printable_name (op2_type, 0));
12440             }
12441           TREE_TYPE (node) = error_mark_node;
12442           error_found = 1;
12443           break;
12444         }
12445
12446       /* Unary numeric promotion (5.6.1) is performed on each operand
12447          separatly */
12448       op1 = do_unary_numeric_promotion (op1);
12449       op2 = do_unary_numeric_promotion (op2);
12450
12451       /* The type of the shift expression is the type of the promoted
12452          type of the left-hand operand */
12453       prom_type = TREE_TYPE (op1);
12454
12455       /* Shift int only up to 0x1f and long up to 0x3f */
12456       if (prom_type == int_type_node)
12457         op2 = fold (build (BIT_AND_EXPR, int_type_node, op2, 
12458                            build_int_2 (0x1f, 0)));
12459       else
12460         op2 = fold (build (BIT_AND_EXPR, int_type_node, op2, 
12461                            build_int_2 (0x3f, 0)));
12462
12463       /* The >>> operator is a >> operating on unsigned quantities */
12464       if (code == URSHIFT_EXPR && ! flag_emit_class_files)
12465         {
12466           tree to_return;
12467           tree utype = unsigned_type (prom_type);
12468           op1 = convert (utype, op1);
12469           TREE_SET_CODE (node, RSHIFT_EXPR);
12470           TREE_OPERAND (node, 0) = op1;
12471           TREE_OPERAND (node, 1) = op2;
12472           TREE_TYPE (node) = utype;
12473           to_return = convert (prom_type, node);
12474           /* Copy the original value of the COMPOUND_ASSIGN_P flag */
12475           COMPOUND_ASSIGN_P (to_return) = COMPOUND_ASSIGN_P (node);
12476           TREE_SIDE_EFFECTS (to_return)
12477             = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
12478           return to_return;
12479         }
12480       break;
12481
12482       /* 15.19.1 Type Comparison Operator instaceof */
12483     case INSTANCEOF_EXPR:
12484
12485       TREE_TYPE (node) = boolean_type_node;
12486
12487       if (!(op2_type = resolve_type_during_patch (op2)))
12488         return error_mark_node;
12489
12490       /* The first operand must be a reference type or the null type */
12491       if (!JREFERENCE_TYPE_P (op1_type) && op1 != null_pointer_node)
12492         error_found = 1;        /* Error reported further below */
12493
12494       /* The second operand must be a reference type */
12495       if (!JREFERENCE_TYPE_P (op2_type))
12496         {
12497           SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
12498           parse_error_context
12499             (wfl_operator, "Invalid argument `%s' for `instanceof'",
12500              lang_printable_name (op2_type, 0));
12501           error_found = 1;
12502         }
12503
12504       if (!error_found && valid_ref_assignconv_cast_p (op1_type, op2_type, 1))
12505         {
12506           /* If the first operand is null, the result is always false */
12507           if (op1 == null_pointer_node)
12508             return boolean_false_node;
12509           else if (flag_emit_class_files)
12510             {
12511               TREE_OPERAND (node, 1) = op2_type;
12512               TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1);
12513               return node;
12514             }
12515           /* Otherwise we have to invoke instance of to figure it out */
12516           else
12517             return build_instanceof (op1, op2_type);
12518         }
12519       /* There is no way the expression operand can be an instance of
12520          the type operand. This is a compile time error. */
12521       else
12522         {
12523           char *t1 = xstrdup (lang_printable_name (op1_type, 0));
12524           SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
12525           parse_error_context 
12526             (wfl_operator, "Impossible for `%s' to be instance of `%s'",
12527              t1, lang_printable_name (op2_type, 0));
12528           free (t1);
12529           error_found = 1;
12530         }
12531       
12532       break;
12533
12534       /* 15.21 Bitwise and Logical Operators */
12535     case BIT_AND_EXPR:
12536     case BIT_XOR_EXPR:
12537     case BIT_IOR_EXPR:
12538       if (JINTEGRAL_TYPE_P (op1_type) && JINTEGRAL_TYPE_P (op2_type))
12539         /* Binary numeric promotion is performed on both operand and the
12540            expression retain that type */
12541         prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12542
12543       else if (TREE_CODE (op1_type) == BOOLEAN_TYPE 
12544                && TREE_CODE (op1_type) == BOOLEAN_TYPE)
12545         /* The type of the bitwise operator expression is BOOLEAN */
12546         prom_type = boolean_type_node;
12547       else
12548         {
12549           if (!JINTEGRAL_TYPE_P (op1_type))
12550             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
12551           if (!JINTEGRAL_TYPE_P (op2_type) && (op1_type != op2_type))
12552             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op2_type);
12553           TREE_TYPE (node) = error_mark_node;
12554           error_found = 1;
12555           /* Insert a break here if adding thing before the switch's
12556              break for this case */
12557         }
12558       break;
12559
12560       /* 15.22 Conditional-And Operator */
12561     case TRUTH_ANDIF_EXPR:
12562       /* 15.23 Conditional-Or Operator */
12563     case TRUTH_ORIF_EXPR:
12564       /* Operands must be of BOOLEAN type */
12565       if (TREE_CODE (op1_type) != BOOLEAN_TYPE || 
12566           TREE_CODE (op2_type) != BOOLEAN_TYPE)
12567         {
12568           if (TREE_CODE (op1_type) != BOOLEAN_TYPE)
12569             ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op1_type);
12570           if (TREE_CODE (op2_type) != BOOLEAN_TYPE && (op1_type != op2_type))
12571             ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op2_type);
12572           TREE_TYPE (node) = boolean_type_node;
12573           error_found = 1;
12574           break;
12575         }
12576       /* The type of the conditional operators is BOOLEAN */
12577       prom_type = boolean_type_node;
12578       break;
12579
12580       /* 15.19.1 Numerical Comparison Operators <, <=, >, >= */
12581     case LT_EXPR:
12582     case GT_EXPR:
12583     case LE_EXPR:
12584     case GE_EXPR:
12585       /* The type of each of the operands must be a primitive numeric
12586          type */
12587       if (!JNUMERIC_TYPE_P (op1_type) || ! JNUMERIC_TYPE_P (op2_type))
12588         {
12589           if (!JNUMERIC_TYPE_P (op1_type))
12590             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
12591           if (!JNUMERIC_TYPE_P (op2_type) && (op1_type != op2_type))
12592             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
12593           TREE_TYPE (node) = boolean_type_node;
12594           error_found = 1;
12595           break;
12596         }
12597       /* Binary numeric promotion is performed on the operands */
12598       binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12599       /* The type of the relation expression is always BOOLEAN */
12600       prom_type = boolean_type_node;
12601       break;
12602
12603       /* 15.20 Equality Operator */
12604     case EQ_EXPR:
12605     case NE_EXPR:
12606       /* It's time for us to patch the strings. */
12607       if ((cn = patch_string (op1))) 
12608        {
12609          op1 = cn;
12610          op1_type = TREE_TYPE (op1);
12611        }
12612       if ((cn = patch_string (op2))) 
12613        {
12614          op2 = cn;
12615          op2_type = TREE_TYPE (op2);
12616        }
12617       
12618       /* 15.20.1 Numerical Equality Operators == and != */
12619       /* Binary numeric promotion is performed on the operands */
12620       if (JNUMERIC_TYPE_P (op1_type) && JNUMERIC_TYPE_P (op2_type))
12621         binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12622       
12623       /* 15.20.2 Boolean Equality Operators == and != */
12624       else if (TREE_CODE (op1_type) == BOOLEAN_TYPE &&
12625           TREE_CODE (op2_type) == BOOLEAN_TYPE)
12626         ;                       /* Nothing to do here */
12627       
12628       /* 15.20.3 Reference Equality Operators == and != */
12629       /* Types have to be either references or the null type. If
12630          they're references, it must be possible to convert either
12631          type to the other by casting conversion. */
12632       else if (op1 == null_pointer_node || op2 == null_pointer_node 
12633                || (JREFERENCE_TYPE_P (op1_type) && JREFERENCE_TYPE_P (op2_type)
12634                    && (valid_ref_assignconv_cast_p (op1_type, op2_type, 1)
12635                        || valid_ref_assignconv_cast_p (op2_type, 
12636                                                        op1_type, 1))))
12637         ;                       /* Nothing to do here */
12638           
12639       /* Else we have an error figure what can't be converted into
12640          what and report the error */
12641       else
12642         {
12643           char *t1;
12644           t1 = xstrdup (lang_printable_name (op1_type, 0));
12645           parse_error_context 
12646             (wfl_operator,
12647              "Incompatible type for `%s'. Can't convert `%s' to `%s'",
12648              operator_string (node), t1, 
12649              lang_printable_name (op2_type, 0));
12650           free (t1);
12651           TREE_TYPE (node) = boolean_type_node;
12652           error_found = 1;
12653           break;
12654         }
12655       prom_type = boolean_type_node;
12656       break;
12657     }
12658
12659   if (error_found)
12660     return error_mark_node;
12661
12662   TREE_OPERAND (node, 0) = op1;
12663   TREE_OPERAND (node, 1) = op2;
12664   TREE_TYPE (node) = prom_type;
12665   TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
12666   
12667   if (flag_emit_xref)
12668     return node;
12669
12670   /* fold does not respect side-effect order as required for Java but not C.
12671    * Also, it sometimes create SAVE_EXPRs which are bad when emitting
12672    * bytecode.
12673    */
12674   if (flag_emit_class_files ? (TREE_CONSTANT (op1) && TREE_CONSTANT (op2))
12675       : ! TREE_SIDE_EFFECTS (node))
12676     node = fold (node);
12677   return node;
12678 }
12679
12680 /* Concatenate the STRING_CST CSTE and STRING. When AFTER is a non
12681    zero value, the value of CSTE comes after the valude of STRING */
12682
12683 static tree
12684 do_merge_string_cste (cste, string, string_len, after)
12685      tree cste;
12686      const char *string;
12687      int string_len, after;
12688 {
12689   int len = TREE_STRING_LENGTH (cste) + string_len;
12690   const char *old = TREE_STRING_POINTER (cste);
12691   TREE_STRING_LENGTH (cste) = len;
12692   TREE_STRING_POINTER (cste) = obstack_alloc (expression_obstack, len+1);
12693   if (after)
12694     {
12695       strcpy (TREE_STRING_POINTER (cste), string);
12696       strcat (TREE_STRING_POINTER (cste), old);
12697     }
12698   else
12699     {
12700       strcpy (TREE_STRING_POINTER (cste), old);
12701       strcat (TREE_STRING_POINTER (cste), string);
12702     }
12703   return cste;
12704 }
12705
12706 /* Tries to merge OP1 (a STRING_CST) and OP2 (if suitable). Return a
12707    new STRING_CST on success, NULL_TREE on failure */
12708
12709 static tree
12710 merge_string_cste (op1, op2, after)
12711      tree op1, op2;
12712      int after;
12713 {
12714   /* Handle two string constants right away */
12715   if (TREE_CODE (op2) == STRING_CST)
12716     return do_merge_string_cste (op1, TREE_STRING_POINTER (op2), 
12717                                  TREE_STRING_LENGTH (op2), after);
12718   
12719   /* Reasonable integer constant can be treated right away */
12720   if (TREE_CODE (op2) == INTEGER_CST && !TREE_CONSTANT_OVERFLOW (op2))
12721     {
12722       static const char *boolean_true = "true";
12723       static const char *boolean_false = "false";
12724       static const char *null_pointer = "null";
12725       char ch[3];
12726       const char *string;
12727       
12728       if (op2 == boolean_true_node)
12729         string = boolean_true;
12730       else if (op2 == boolean_false_node)
12731         string = boolean_false;
12732       else if (op2 == null_pointer_node)
12733         string = null_pointer;
12734       else if (TREE_TYPE (op2) == char_type_node)
12735         {
12736           ch[0] = (char )TREE_INT_CST_LOW (op2);
12737           ch[1] = '\0';
12738           string = ch;
12739         }
12740       else
12741           string = print_int_node (op2);
12742       
12743       return do_merge_string_cste (op1, string, strlen (string), after);
12744     }
12745   return NULL_TREE;
12746 }
12747
12748 /* Tries to statically concatenate OP1 and OP2 if possible. Either one
12749    has to be a STRING_CST and the other part must be a STRING_CST or a
12750    INTEGRAL constant. Return a new STRING_CST if the operation
12751    succeed, NULL_TREE otherwise.
12752
12753    If the case we want to optimize for space, we might want to return
12754    NULL_TREE for each invocation of this routine. FIXME */
12755
12756 static tree
12757 string_constant_concatenation (op1, op2)
12758      tree op1, op2;
12759 {
12760   if (TREE_CODE (op1) == STRING_CST || (TREE_CODE (op2) == STRING_CST))
12761     {
12762       tree string, rest;
12763       int invert;
12764       
12765       string = (TREE_CODE (op1) == STRING_CST ? op1 : op2);
12766       rest   = (string == op1 ? op2 : op1);
12767       invert = (string == op1 ? 0 : 1 );
12768       
12769       /* Walk REST, only if it looks reasonable */
12770       if (TREE_CODE (rest) != STRING_CST
12771           && !IS_CRAFTED_STRING_BUFFER_P (rest)
12772           && !JSTRING_TYPE_P (TREE_TYPE (rest))
12773           && TREE_CODE (rest) == EXPR_WITH_FILE_LOCATION)
12774         {
12775           rest = java_complete_tree (rest);
12776           if (rest == error_mark_node)
12777             return error_mark_node;
12778           rest = fold (rest);
12779         }
12780       return merge_string_cste (string, rest, invert);
12781     }
12782   return NULL_TREE;
12783 }
12784
12785 /* Implement the `+' operator. Does static optimization if possible,
12786    otherwise create (if necessary) and append elements to a
12787    StringBuffer. The StringBuffer will be carried around until it is
12788    used for a function call or an assignment. Then toString() will be
12789    called on it to turn it into a String object. */
12790
12791 static tree
12792 build_string_concatenation (op1, op2)
12793      tree op1, op2;
12794 {
12795   tree result;
12796   int side_effects = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
12797
12798   if (flag_emit_xref)
12799     return build (PLUS_EXPR, string_type_node, op1, op2);
12800   
12801   /* Try to do some static optimization */
12802   if ((result = string_constant_concatenation (op1, op2)))
12803     return result;
12804
12805   /* Discard empty strings on either side of the expression */
12806   if (TREE_CODE (op1) == STRING_CST && TREE_STRING_LENGTH (op1) == 0)
12807     {
12808       op1 = op2;
12809       op2 = NULL_TREE;
12810     }
12811   else if (TREE_CODE (op2) == STRING_CST && TREE_STRING_LENGTH (op2) == 0)
12812     op2 = NULL_TREE;
12813
12814   /* If operands are string constant, turn then into object references */
12815   if (TREE_CODE (op1) == STRING_CST)
12816     op1 = patch_string_cst (op1);
12817   if (op2 && TREE_CODE (op2) == STRING_CST)
12818     op2 = patch_string_cst (op2);
12819
12820   /* If either one of the constant is null and the other non null
12821      operand is a String object, return it. */
12822   if (JSTRING_TYPE_P (TREE_TYPE (op1)) && !op2)
12823     return op1;
12824
12825   /* If OP1 isn't already a StringBuffer, create and
12826      initialize a new one */
12827   if (!IS_CRAFTED_STRING_BUFFER_P (op1))
12828     {
12829       /* Two solutions here: 
12830          1) OP1 is a constant string reference, we call new StringBuffer(OP1)
12831          2) OP1 is something else, we call new StringBuffer().append(OP1).  */
12832       if (TREE_CONSTANT (op1) && JSTRING_TYPE_P (TREE_TYPE (op1)))
12833         op1 = BUILD_STRING_BUFFER (op1);
12834       else
12835         {
12836           tree aNew = BUILD_STRING_BUFFER (NULL_TREE);
12837           op1 = make_qualified_primary (aNew, BUILD_APPEND (op1), 0);
12838         }
12839     }
12840
12841   if (op2)
12842     {
12843       /* OP1 is no longer the last node holding a crafted StringBuffer */
12844       IS_CRAFTED_STRING_BUFFER_P (op1) = 0;
12845       /* Create a node for `{new...,xxx}.append (op2)' */
12846       if (op2)
12847         op1 = make_qualified_primary (op1, BUILD_APPEND (op2), 0);
12848     }
12849
12850   /* Mark the last node holding a crafted StringBuffer */
12851   IS_CRAFTED_STRING_BUFFER_P (op1) = 1;
12852
12853   TREE_SIDE_EFFECTS (op1) = side_effects;
12854   return op1;
12855 }
12856
12857 /* Patch the string node NODE. NODE can be a STRING_CST of a crafted
12858    StringBuffer. If no string were found to be patched, return
12859    NULL. */
12860
12861 static tree
12862 patch_string (node)
12863     tree node;
12864 {
12865   if (node == error_mark_node)
12866     return error_mark_node;
12867   if (TREE_CODE (node) == STRING_CST)
12868     return patch_string_cst (node);
12869   else if (IS_CRAFTED_STRING_BUFFER_P (node))
12870     {
12871       int saved = ctxp->explicit_constructor_p;
12872       tree invoke = build_method_invocation (wfl_to_string, NULL_TREE);
12873       tree ret;
12874       /* Temporary disable forbid the use of `this'. */
12875       ctxp->explicit_constructor_p = 0;
12876       ret = java_complete_tree (make_qualified_primary (node, invoke, 0));
12877       /* String concatenation arguments must be evaluated in order too. */
12878       ret = force_evaluation_order (ret);
12879       /* Restore it at its previous value */
12880       ctxp->explicit_constructor_p = saved;
12881       return ret;
12882     }
12883   return NULL_TREE;
12884 }
12885
12886 /* Build the internal representation of a string constant.  */
12887
12888 static tree
12889 patch_string_cst (node)
12890      tree node;
12891 {
12892   int location;
12893   if (! flag_emit_class_files)
12894     {
12895       push_obstacks (&permanent_obstack, &permanent_obstack);
12896       node = get_identifier (TREE_STRING_POINTER (node));
12897       location = alloc_name_constant (CONSTANT_String, node);
12898       node = build_ref_from_constant_pool (location);
12899       pop_obstacks ();
12900     }
12901   TREE_TYPE (node) = string_ptr_type_node;
12902   TREE_CONSTANT (node) = 1;
12903   return node;
12904 }
12905
12906 /* Build an incomplete unary operator expression. */
12907
12908 static tree
12909 build_unaryop (op_token, op_location, op1)
12910      int op_token, op_location;
12911      tree op1;
12912 {
12913   enum tree_code op;
12914   tree unaryop;
12915   switch (op_token)
12916     {
12917     case PLUS_TK: op = UNARY_PLUS_EXPR; break;
12918     case MINUS_TK: op = NEGATE_EXPR; break;
12919     case NEG_TK: op = TRUTH_NOT_EXPR; break;
12920     case NOT_TK: op = BIT_NOT_EXPR; break;
12921     default: fatal ("Unknown token `%d' for unary operator - build_unaryop",
12922                     op_token);
12923     }
12924
12925   unaryop = build1 (op, NULL_TREE, op1);
12926   TREE_SIDE_EFFECTS (unaryop) = 1;
12927   /* Store the location of the operator, for better error report. The
12928      string of the operator will be rebuild based on the OP value. */
12929   EXPR_WFL_LINECOL (unaryop) = op_location;
12930   return unaryop;
12931 }
12932
12933 /* Special case for the ++/-- operators, since they require an extra
12934    argument to build, which is set to NULL and patched
12935    later. IS_POST_P is 1 if the operator, 0 otherwise.  */
12936
12937 static tree
12938 build_incdec (op_token, op_location, op1, is_post_p)
12939      int op_token, op_location;
12940      tree op1;
12941      int is_post_p;
12942 {
12943   static enum tree_code lookup [2][2] = 
12944     {
12945       { PREDECREMENT_EXPR, PREINCREMENT_EXPR, },
12946       { POSTDECREMENT_EXPR, POSTINCREMENT_EXPR, },
12947     };
12948   tree node = build (lookup [is_post_p][(op_token - DECR_TK)], 
12949                      NULL_TREE, op1, NULL_TREE);
12950   TREE_SIDE_EFFECTS (node) = 1;
12951   /* Store the location of the operator, for better error report. The
12952      string of the operator will be rebuild based on the OP value. */
12953   EXPR_WFL_LINECOL (node) = op_location;
12954   return node;
12955 }     
12956
12957 /* Build an incomplete cast operator, based on the use of the
12958    CONVERT_EXPR. Note that TREE_TYPE of the constructed node is
12959    set. java_complete_tree is trained to walk a CONVERT_EXPR even
12960    though its type is already set.  */
12961
12962 static tree
12963 build_cast (location, type, exp)
12964      int location;
12965      tree type, exp;
12966 {
12967   tree node = build1 (CONVERT_EXPR, type, exp);
12968   EXPR_WFL_LINECOL (node) = location;
12969   return node;
12970 }
12971
12972 /* Build an incomplete class reference operator.  */
12973 static tree
12974 build_incomplete_class_ref (location, class_name)
12975     int location;
12976     tree class_name;
12977 {
12978   tree node = build1 (CLASS_LITERAL, NULL_TREE, class_name);
12979   EXPR_WFL_LINECOL (node) = location;
12980   return node;
12981 }
12982
12983 /* Complete an incomplete class reference operator.  */
12984 static tree
12985 patch_incomplete_class_ref (node)
12986     tree node;
12987 {
12988   tree type = TREE_OPERAND (node, 0);
12989   tree ref_type;
12990
12991   if (!(ref_type = resolve_type_during_patch (type)))
12992     return error_mark_node;
12993
12994   if (!flag_emit_class_files || JPRIMITIVE_TYPE_P (ref_type))
12995     {
12996       /* A class referenced by `foo.class' is initialized.  */
12997       return build_class_init (ref_type, build_class_ref (ref_type));
12998     }
12999
13000   /* If we're emitting class files and we have to deal with non
13001      primitive types, we invoke (and consider generating) the
13002      synthetic static method `class$'. */
13003   if (!TYPE_DOT_CLASS (current_class))
13004       build_dot_class_method (current_class);
13005   ref_type = 
13006     build_dot_class_method_invocation (DECL_NAME (TYPE_NAME (ref_type)));
13007   return java_complete_tree (ref_type);
13008 }
13009
13010 /* 15.14 Unary operators. We return error_mark_node in case of error,
13011    but preserve the type of NODE if the type is fixed.  */
13012
13013 static tree
13014 patch_unaryop (node, wfl_op)
13015      tree node;
13016      tree wfl_op;
13017 {
13018   tree op = TREE_OPERAND (node, 0);
13019   tree op_type = TREE_TYPE (op);
13020   tree prom_type = NULL_TREE, value, decl;
13021   int outer_field_flag = 0;
13022   int code = TREE_CODE (node);
13023   int error_found = 0;
13024
13025   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13026
13027   switch (code)
13028     {
13029       /* 15.13.2 Postfix Increment Operator ++ */
13030     case POSTINCREMENT_EXPR:
13031       /* 15.13.3 Postfix Increment Operator -- */
13032     case POSTDECREMENT_EXPR:
13033       /* 15.14.1 Prefix Increment Operator ++ */
13034     case PREINCREMENT_EXPR:
13035       /* 15.14.2 Prefix Decrement Operator -- */
13036     case PREDECREMENT_EXPR:
13037       op = decl = strip_out_static_field_access_decl (op);
13038       outer_field_flag = outer_field_expanded_access_p (op, NULL, NULL, NULL);
13039       /* We might be trying to change an outer field accessed using
13040          access method. */
13041       if (outer_field_flag)
13042         {
13043           /* Retrieve the decl of the field we're trying to access. We
13044              do that by first retrieving the function we would call to
13045              access the field. It has been already verified that this
13046              field isn't final */
13047           if (flag_emit_class_files)
13048             decl = TREE_OPERAND (op, 0);
13049           else
13050             decl = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (op, 0), 0), 0);
13051           decl = DECL_FUNCTION_ACCESS_DECL (decl);
13052         }
13053       /* We really should have a JAVA_ARRAY_EXPR to avoid this */
13054       else if (!JDECL_P (decl) 
13055           && TREE_CODE (decl) != COMPONENT_REF
13056           && !(flag_emit_class_files && TREE_CODE (decl) == ARRAY_REF)
13057           && TREE_CODE (decl) != INDIRECT_REF
13058           && !(TREE_CODE (decl) == COMPOUND_EXPR
13059                && TREE_OPERAND (decl, 1)
13060                && (TREE_CODE (TREE_OPERAND (decl, 1)) == INDIRECT_REF)))
13061         {
13062           tree lvalue;
13063           /* Before screaming, check that we're not in fact trying to
13064              increment a optimized static final access, in which case
13065              we issue an different error message. */
13066           if (!(TREE_CODE (wfl_op) == EXPR_WITH_FILE_LOCATION
13067                 && resolve_expression_name (wfl_op, &lvalue)
13068                 && check_final_assignment (lvalue, wfl_op)))
13069             parse_error_context (wfl_operator, "Invalid argument to `%s'",
13070                                  operator_string (node));
13071           TREE_TYPE (node) = error_mark_node;
13072           error_found = 1;
13073         }
13074       
13075       if (check_final_assignment (op, wfl_op))
13076         error_found = 1;
13077
13078       /* From now on, we know that op if a variable and that it has a
13079          valid wfl. We use wfl_op to locate errors related to the
13080          ++/-- operand. */
13081       else if (!JNUMERIC_TYPE_P (op_type))
13082         {
13083           parse_error_context
13084             (wfl_op, "Invalid argument type `%s' to `%s'",
13085              lang_printable_name (op_type, 0), operator_string (node));
13086           TREE_TYPE (node) = error_mark_node;
13087           error_found = 1;
13088         }
13089       else
13090         {
13091           /* Before the addition, binary numeric promotion is performed on
13092              both operands, if really necessary */
13093           if (JINTEGRAL_TYPE_P (op_type))
13094             {
13095               value = build_int_2 (1, 0);
13096               TREE_TYPE (value) = TREE_TYPE (node) = op_type;
13097             }
13098           else
13099             {
13100               value = build_int_2 (1, 0);
13101               TREE_TYPE (node) = 
13102                 binary_numeric_promotion (op_type, 
13103                                           TREE_TYPE (value), &op, &value);
13104             }
13105
13106           /* We remember we might be accessing an outer field */
13107           if (outer_field_flag)
13108             {
13109               /* We re-generate an access to the field */
13110               value = build (PLUS_EXPR, TREE_TYPE (op), 
13111                              build_outer_field_access (wfl_op, decl), value);
13112                                                     
13113               /* And we patch the original access$() into a write 
13114                  with plus_op as a rhs */
13115               return outer_field_access_fix (node, op, value);
13116             }
13117
13118           /* And write back into the node. */
13119           TREE_OPERAND (node, 0) = op;
13120           TREE_OPERAND (node, 1) = value;
13121           /* Convert the overall back into its original type, if
13122              necessary, and return */
13123           if (JINTEGRAL_TYPE_P (op_type))
13124             return fold (node);
13125           else
13126             return fold (convert (op_type, node));
13127         }
13128       break;
13129
13130       /* 15.14.3 Unary Plus Operator + */
13131     case UNARY_PLUS_EXPR:
13132       /* 15.14.4 Unary Minus Operator - */
13133     case NEGATE_EXPR:
13134       if (!JNUMERIC_TYPE_P (op_type))
13135         {
13136           ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op_type);
13137           TREE_TYPE (node) = error_mark_node;
13138           error_found = 1;
13139         }
13140       /* Unary numeric promotion is performed on operand */
13141       else
13142         {
13143           op = do_unary_numeric_promotion (op);
13144           prom_type = TREE_TYPE (op);
13145           if (code == UNARY_PLUS_EXPR)
13146             return fold (op);
13147         }
13148       break;
13149
13150       /* 15.14.5 Bitwise Complement Operator ~ */
13151     case BIT_NOT_EXPR:
13152       if (!JINTEGRAL_TYPE_P (op_type))
13153         {
13154           ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op_type);
13155           TREE_TYPE (node) = error_mark_node;
13156           error_found = 1;
13157         }
13158       else
13159         {
13160           op = do_unary_numeric_promotion (op);
13161           prom_type = TREE_TYPE (op);
13162         }
13163       break;
13164
13165       /* 15.14.6 Logical Complement Operator ! */
13166     case TRUTH_NOT_EXPR:
13167       if (TREE_CODE (op_type) != BOOLEAN_TYPE)
13168         {
13169           ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op_type);
13170           /* But the type is known. We will report an error if further
13171              attempt of a assignment is made with this rhs */
13172           TREE_TYPE (node) = boolean_type_node;
13173           error_found = 1;
13174         }
13175       else
13176         prom_type = boolean_type_node;
13177       break;
13178
13179       /* 15.15 Cast Expression */
13180     case CONVERT_EXPR:
13181       value = patch_cast (node, wfl_operator);
13182       if (value == error_mark_node)
13183         {
13184           /* If this cast is part of an assignment, we tell the code
13185              that deals with it not to complain about a mismatch,
13186              because things have been cast, anyways */
13187           TREE_TYPE (node) = error_mark_node;
13188           error_found = 1;
13189         }
13190       else
13191         {
13192           value = fold (value);
13193           TREE_SIDE_EFFECTS (value) = TREE_SIDE_EFFECTS (op);
13194           return value;
13195         }
13196       break;
13197     }
13198   
13199   if (error_found)
13200     return error_mark_node;
13201
13202   /* There are cases where node has been replaced by something else
13203      and we don't end up returning here: UNARY_PLUS_EXPR,
13204      CONVERT_EXPR, {POST,PRE}{INCR,DECR}EMENT_EXPR. */
13205   TREE_OPERAND (node, 0) = fold (op);
13206   TREE_TYPE (node) = prom_type;
13207   TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op);
13208   return fold (node);
13209 }
13210
13211 /* Generic type resolution that sometimes takes place during node
13212    patching. Returned the resolved type or generate an error
13213    message. Return the resolved type or NULL_TREE.  */
13214
13215 static tree
13216 resolve_type_during_patch (type)
13217      tree type;
13218 {
13219   if (unresolved_type_p (type, NULL))
13220     {
13221       tree type_decl = resolve_no_layout (EXPR_WFL_NODE (type), NULL_TREE);
13222       if (!type_decl)
13223         {
13224           parse_error_context (type, 
13225                                "Class `%s' not found in type declaration",
13226                                IDENTIFIER_POINTER (EXPR_WFL_NODE (type)));
13227           return NULL_TREE;
13228         }
13229       else
13230         {
13231           CLASS_LOADED_P (TREE_TYPE (type_decl)) = 1;
13232           return TREE_TYPE (type_decl);
13233         }
13234     }
13235   return type;
13236 }
13237 /* 5.5 Casting Conversion. error_mark_node is returned if an error is
13238    found. Otherwise NODE or something meant to replace it is returned.  */
13239
13240 static tree
13241 patch_cast (node, wfl_operator)
13242      tree node;
13243      tree wfl_operator;
13244 {
13245   tree op = TREE_OPERAND (node, 0);
13246   tree op_type = TREE_TYPE (op);
13247   tree cast_type = TREE_TYPE (node);
13248   char *t1;
13249
13250   /* First resolve OP_TYPE if unresolved */
13251   if (!(cast_type = resolve_type_during_patch (cast_type)))
13252     return error_mark_node;
13253
13254   /* Check on cast that are proven correct at compile time */
13255   if (JNUMERIC_TYPE_P (cast_type) && JNUMERIC_TYPE_P (op_type))
13256     {
13257       /* Same type */
13258       if (cast_type == op_type)
13259         return node;
13260
13261       /* float and double type are converted to the original type main
13262          variant and then to the target type. */
13263       if (JFLOAT_TYPE_P (op_type) && TREE_CODE (cast_type) == CHAR_TYPE)
13264         op = convert (integer_type_node, op);
13265
13266       /* Try widening/narowwing convertion. Potentially, things need
13267          to be worked out in gcc so we implement the extreme cases
13268          correctly. fold_convert() needs to be fixed. */
13269       return convert (cast_type, op);
13270     }
13271
13272   /* It's also valid to cast a boolean into a boolean */
13273   if (op_type == boolean_type_node && cast_type == boolean_type_node)
13274     return node;
13275
13276   /* null can be casted to references */
13277   if (op == null_pointer_node && JREFERENCE_TYPE_P (cast_type))
13278     return build_null_of_type (cast_type);
13279
13280   /* The remaining legal casts involve conversion between reference
13281      types. Check for their compile time correctness. */
13282   if (JREFERENCE_TYPE_P (op_type) && JREFERENCE_TYPE_P (cast_type) 
13283       && valid_ref_assignconv_cast_p (op_type, cast_type, 1))
13284     {
13285       TREE_TYPE (node) = promote_type (cast_type);
13286       /* Now, the case can be determined correct at compile time if
13287          OP_TYPE can be converted into CAST_TYPE by assignment
13288          conversion (5.2) */
13289
13290       if (valid_ref_assignconv_cast_p (op_type, cast_type, 0))
13291         {
13292           TREE_SET_CODE (node, NOP_EXPR);
13293           return node;
13294         }
13295
13296       if (flag_emit_class_files)
13297         {
13298           TREE_SET_CODE (node, CONVERT_EXPR);
13299           return node;
13300         }
13301
13302       /* The cast requires a run-time check */
13303       return build (CALL_EXPR, promote_type (cast_type),
13304                     build_address_of (soft_checkcast_node),
13305                     tree_cons (NULL_TREE, build_class_ref (cast_type),
13306                                build_tree_list (NULL_TREE, op)),
13307                     NULL_TREE);
13308     }
13309
13310   /* Any other casts are proven incorrect at compile time */
13311   t1 = xstrdup (lang_printable_name (op_type, 0));
13312   parse_error_context (wfl_operator, "Invalid cast from `%s' to `%s'",
13313                        t1, lang_printable_name (cast_type, 0));
13314   free (t1);
13315   return error_mark_node;
13316 }
13317
13318 /* Build a null constant and give it the type TYPE.  */
13319
13320 static tree
13321 build_null_of_type (type)
13322      tree type;
13323 {
13324   tree node = build_int_2 (0, 0);
13325   TREE_TYPE (node) = promote_type (type);
13326   return node;
13327 }
13328
13329 /* Build an ARRAY_REF incomplete tree node. Note that operand 1 isn't
13330    a list of indices. */
13331 static tree
13332 build_array_ref (location, array, index)
13333      int location;
13334      tree array, index;
13335 {
13336   tree node = build (ARRAY_REF, NULL_TREE, array, index);
13337   EXPR_WFL_LINECOL (node) = location;
13338   return node;
13339 }
13340
13341 /* 15.12 Array Access Expression */
13342
13343 static tree
13344 patch_array_ref (node)
13345      tree node;
13346 {
13347   tree array = TREE_OPERAND (node, 0);
13348   tree array_type  = TREE_TYPE (array);
13349   tree index = TREE_OPERAND (node, 1);
13350   tree index_type = TREE_TYPE (index);
13351   int error_found = 0;
13352
13353   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13354
13355   if (TREE_CODE (array_type) == POINTER_TYPE)
13356     array_type = TREE_TYPE (array_type);
13357
13358   /* The array reference must be an array */
13359   if (!TYPE_ARRAY_P (array_type))
13360     {
13361       parse_error_context 
13362         (wfl_operator,
13363          "`[]' can only be applied to arrays. It can't be applied to `%s'",
13364          lang_printable_name (array_type, 0));
13365       TREE_TYPE (node) = error_mark_node;
13366       error_found = 1;
13367     }
13368
13369   /* The array index undergoes unary numeric promotion. The promoted
13370      type must be int */
13371   index = do_unary_numeric_promotion (index);
13372   if (TREE_TYPE (index) != int_type_node)
13373     {
13374       if (valid_cast_to_p (index_type, int_type_node))
13375         parse_error_context (wfl_operator,
13376    "Incompatible type for `[]'. Explicit cast needed to convert `%s' to `int'",
13377                              lang_printable_name (index_type, 0));
13378       else
13379         parse_error_context (wfl_operator,
13380           "Incompatible type for `[]'. Can't convert `%s' to `int'",
13381                              lang_printable_name (index_type, 0));
13382       TREE_TYPE (node) = error_mark_node;
13383       error_found = 1;
13384     }
13385
13386   if (error_found)
13387     return error_mark_node;
13388
13389   array_type = TYPE_ARRAY_ELEMENT (array_type);
13390
13391   if (flag_emit_class_files || flag_emit_xref)
13392     {
13393       TREE_OPERAND (node, 0) = array;
13394       TREE_OPERAND (node, 1) = index;
13395     }
13396   else
13397     {
13398       /* The save_expr is for correct evaluation order.  It would be cleaner
13399          to use force_evaluation_order (see comment there), but that is
13400          difficult when we also have to deal with bounds checking. */
13401       if (TREE_SIDE_EFFECTS (index))
13402         array = save_expr (array);
13403       node = build_java_arrayaccess (array, array_type, index);
13404       if (TREE_SIDE_EFFECTS (index))
13405         node = build (COMPOUND_EXPR, array_type, array, node);
13406     }
13407   TREE_TYPE (node) = array_type;
13408   return node;
13409 }
13410
13411 /* 15.9 Array Creation Expressions */
13412
13413 static tree
13414 build_newarray_node (type, dims, extra_dims)
13415      tree type;
13416      tree dims;
13417      int extra_dims;
13418 {
13419   tree node =
13420     build (NEW_ARRAY_EXPR, NULL_TREE, type, nreverse (dims), 
13421            build_int_2 (extra_dims, 0));
13422   return node;
13423 }
13424
13425 static tree
13426 patch_newarray (node)
13427      tree node;
13428 {
13429   tree type = TREE_OPERAND (node, 0);
13430   tree dims = TREE_OPERAND (node, 1);
13431   tree cdim, array_type;
13432   int error_found = 0;
13433   int ndims = 0;
13434   int xdims = TREE_INT_CST_LOW (TREE_OPERAND (node, 2));
13435
13436   /* Dimension types are verified. It's better for the types to be
13437      verified in order. */
13438   for (cdim = dims, ndims = 0; cdim; cdim = TREE_CHAIN (cdim), ndims++ )
13439     {
13440       int dim_error = 0;
13441       tree dim = TREE_VALUE (cdim);
13442
13443       /* Dim might have been saved during its evaluation */
13444       dim = (TREE_CODE (dim) == SAVE_EXPR ? dim = TREE_OPERAND (dim, 0) : dim);
13445
13446       /* The type of each specified dimension must be an integral type. */
13447       if (!JINTEGRAL_TYPE_P (TREE_TYPE (dim)))
13448         dim_error = 1;
13449
13450       /* Each expression undergoes an unary numeric promotion (5.6.1) and the
13451          promoted type must be int. */
13452       else
13453         {
13454           dim = do_unary_numeric_promotion (dim);
13455           if (TREE_TYPE (dim) != int_type_node)
13456             dim_error = 1;
13457         }
13458
13459       /* Report errors on types here */
13460       if (dim_error)
13461         {
13462           parse_error_context 
13463             (TREE_PURPOSE (cdim), 
13464              "Incompatible type for dimension in array creation expression. %s convert `%s' to `int'", 
13465              (valid_cast_to_p (TREE_TYPE (dim), int_type_node) ?
13466               "Explicit cast needed to" : "Can't"),
13467              lang_printable_name (TREE_TYPE (dim), 0));
13468           error_found = 1;
13469         }
13470
13471       TREE_PURPOSE (cdim) = NULL_TREE;
13472     }
13473
13474   /* Resolve array base type if unresolved */
13475   if (!(type = resolve_type_during_patch (type)))
13476     error_found = 1;
13477
13478   if (error_found)
13479     {
13480       /* We don't want further evaluation of this bogus array creation
13481          operation */
13482       TREE_TYPE (node) = error_mark_node;
13483       return error_mark_node;
13484     }
13485
13486   /* Set array_type to the actual (promoted) array type of the result. */
13487   if (TREE_CODE (type) == RECORD_TYPE)
13488     type = build_pointer_type (type);
13489   while (--xdims >= 0)
13490     {
13491       type = promote_type (build_java_array_type (type, -1));
13492     }
13493   dims = nreverse (dims);
13494   array_type = type;
13495   for (cdim = dims; cdim; cdim = TREE_CHAIN (cdim))
13496     {
13497       type = array_type;
13498       array_type
13499         = build_java_array_type (type,
13500                                  TREE_CODE (cdim) == INTEGER_CST
13501                                  ? (HOST_WIDE_INT) TREE_INT_CST_LOW (cdim)
13502                                  : -1);
13503       array_type = promote_type (array_type);
13504     }
13505   dims = nreverse (dims);
13506
13507   /* The node is transformed into a function call. Things are done
13508      differently according to the number of dimensions. If the number
13509      of dimension is equal to 1, then the nature of the base type
13510      (primitive or not) matters. */
13511   if (ndims == 1)
13512     return build_new_array (type, TREE_VALUE (dims));
13513   
13514   /* Can't reuse what's already written in expr.c because it uses the
13515      JVM stack representation. Provide a build_multianewarray. FIXME */
13516   return build (CALL_EXPR, array_type,
13517                 build_address_of (soft_multianewarray_node),
13518                 tree_cons (NULL_TREE, build_class_ref (TREE_TYPE (array_type)),
13519                            tree_cons (NULL_TREE, 
13520                                       build_int_2 (ndims, 0), dims )),
13521                 NULL_TREE);
13522 }
13523
13524 /* 10.6 Array initializer.  */
13525
13526 /* Build a wfl for array element that don't have one, so we can
13527    pin-point errors.  */
13528
13529 static tree
13530 maybe_build_array_element_wfl (node)
13531      tree node;
13532 {
13533   if (TREE_CODE (node) != EXPR_WITH_FILE_LOCATION)
13534     return build_expr_wfl (NULL_TREE, ctxp->filename,
13535                            ctxp->elc.line, ctxp->elc.prev_col);
13536   else
13537     return NULL_TREE;
13538 }
13539
13540 /* Build a NEW_ARRAY_INIT that features a CONSTRUCTOR node. This makes
13541    identification of initialized arrays easier to detect during walk
13542    and expansion.  */
13543
13544 static tree
13545 build_new_array_init (location, values)
13546      int location;
13547      tree values;
13548 {
13549   tree constructor = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, values);
13550   tree to_return = build1 (NEW_ARRAY_INIT, NULL_TREE, constructor);
13551   EXPR_WFL_LINECOL (to_return) = location;
13552   return to_return;
13553 }
13554
13555 /* Expand a NEW_ARRAY_INIT node. Return error_mark_node if an error
13556    occurred.  Otherwise return NODE after having set its type
13557    appropriately.  */
13558
13559 static tree
13560 patch_new_array_init (type, node)
13561      tree type, node;
13562 {
13563   int error_seen = 0;
13564   tree current, element_type;
13565   HOST_WIDE_INT length;
13566   int all_constant = 1;
13567   tree init = TREE_OPERAND (node, 0);
13568
13569   if (TREE_CODE (type) != POINTER_TYPE || ! TYPE_ARRAY_P (TREE_TYPE (type)))
13570     {
13571       parse_error_context (node,
13572                            "Invalid array initializer for non-array type `%s'",
13573                            lang_printable_name (type, 1));
13574       return error_mark_node;
13575     }
13576   type = TREE_TYPE (type);
13577   element_type = TYPE_ARRAY_ELEMENT (type);
13578
13579   CONSTRUCTOR_ELTS (init) = nreverse (CONSTRUCTOR_ELTS (init));
13580
13581   for (length = 0, current = CONSTRUCTOR_ELTS (init);
13582        current;  length++, current = TREE_CHAIN (current))
13583     {
13584       tree elt = TREE_VALUE (current);
13585       if (elt == NULL_TREE || TREE_CODE (elt) != NEW_ARRAY_INIT)
13586         {
13587           error_seen |= array_constructor_check_entry (element_type, current);
13588           elt = TREE_VALUE (current);
13589           /* When compiling to native code, STRING_CST is converted to
13590              INDIRECT_REF, but still with a TREE_CONSTANT flag. */
13591           if (! TREE_CONSTANT (elt) || TREE_CODE (elt) == INDIRECT_REF)
13592             all_constant = 0;
13593         }
13594       else
13595         {
13596           TREE_VALUE (current) = patch_new_array_init (element_type, elt);
13597           TREE_PURPOSE (current) = NULL_TREE;
13598           all_constant = 0;
13599         }
13600       if (elt && TREE_CODE (elt) == TREE_LIST 
13601           && TREE_VALUE (elt) == error_mark_node)
13602         error_seen = 1;
13603     }
13604
13605   if (error_seen)
13606     return error_mark_node;
13607
13608   /* Create a new type. We can't reuse the one we have here by
13609      patching its dimension because it originally is of dimension -1
13610      hence reused by gcc. This would prevent triangular arrays. */
13611   type = build_java_array_type (element_type, length);
13612   TREE_TYPE (init) = TREE_TYPE (TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (type))));
13613   TREE_TYPE (node) = promote_type (type);
13614   TREE_CONSTANT (init) = all_constant;
13615   TREE_CONSTANT (node) = all_constant;
13616   return node;
13617 }
13618
13619 /* Verify that one entry of the initializer element list can be
13620    assigned to the array base type. Report 1 if an error occurred, 0
13621    otherwise.  */
13622
13623 static int
13624 array_constructor_check_entry (type, entry)
13625      tree type, entry;
13626 {
13627   char *array_type_string = NULL;       /* For error reports */
13628   tree value, type_value, new_value, wfl_value, patched;
13629   int error_seen = 0;
13630
13631   new_value = NULL_TREE;
13632   wfl_value = TREE_VALUE (entry);
13633
13634   push_obstacks (&permanent_obstack, &permanent_obstack);
13635   value = java_complete_tree (TREE_VALUE (entry));
13636   /* patch_string return error_mark_node if arg is error_mark_node */
13637   if ((patched = patch_string (value)))
13638     value = patched;
13639   if (value == error_mark_node)
13640     return 1;
13641   
13642   type_value = TREE_TYPE (value);
13643   
13644   /* At anytime, try_builtin_assignconv can report a warning on
13645      constant overflow during narrowing. */
13646   SET_WFL_OPERATOR (wfl_operator, TREE_PURPOSE (entry), wfl_value);
13647   new_value = try_builtin_assignconv (wfl_operator, type, value);
13648   if (!new_value && (new_value = try_reference_assignconv (type, value)))
13649     type_value = promote_type (type);
13650
13651   pop_obstacks ();
13652   /* Check and report errors */
13653   if (!new_value)
13654     {
13655       const char *msg = (!valid_cast_to_p (type_value, type) ?
13656                    "Can't" : "Explicit cast needed to");
13657       if (!array_type_string)
13658         array_type_string = xstrdup (lang_printable_name (type, 1));
13659       parse_error_context 
13660         (wfl_operator, "Incompatible type for array. %s convert `%s' to `%s'",
13661          msg, lang_printable_name (type_value, 1), array_type_string);
13662       error_seen = 1;
13663     }
13664   
13665   if (new_value)
13666     {
13667       new_value = maybe_build_primttype_type_ref (new_value, wfl_value);
13668       TREE_VALUE (entry) = new_value;
13669     }
13670
13671   if (array_type_string)
13672     free (array_type_string);
13673
13674   TREE_PURPOSE (entry) = NULL_TREE;
13675   return error_seen;
13676 }
13677
13678 static tree
13679 build_this (location)
13680      int location;
13681 {
13682   tree node = build_wfl_node (this_identifier_node);
13683   TREE_SET_CODE (node, THIS_EXPR);
13684   EXPR_WFL_LINECOL (node) = location;
13685   return node;
13686 }
13687
13688 /* 14.15 The return statement. It builds a modify expression that
13689    assigns the returned value to the RESULT_DECL that hold the value
13690    to be returned. */
13691
13692 static tree
13693 build_return (location, op)
13694      int location;
13695      tree op;
13696 {
13697   tree node = build1 (RETURN_EXPR, NULL_TREE, op);
13698   EXPR_WFL_LINECOL (node) = location;
13699   node = build_debugable_stmt (location, node);
13700   return node;
13701 }
13702
13703 static tree
13704 patch_return (node)
13705      tree node;
13706 {
13707   tree return_exp = TREE_OPERAND (node, 0);
13708   tree meth = current_function_decl;
13709   tree mtype = TREE_TYPE (TREE_TYPE (current_function_decl));
13710   int error_found = 0;
13711
13712   TREE_TYPE (node) = error_mark_node;
13713   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13714
13715   /* It's invalid to have a return value within a function that is
13716      declared with the keyword void or that is a constructor */
13717   if (return_exp && (mtype == void_type_node || DECL_CONSTRUCTOR_P (meth)))
13718     error_found = 1;
13719
13720   /* It's invalid to use a return statement in a static block */
13721   if (DECL_CLINIT_P (current_function_decl))
13722     error_found = 1;
13723
13724   /* It's invalid to have a no return value within a function that
13725      isn't declared with the keyword `void' */
13726   if (!return_exp && (mtype != void_type_node && !DECL_CONSTRUCTOR_P (meth)))
13727     error_found = 2;
13728   
13729   if (in_instance_initializer)
13730     error_found = 1;
13731
13732   if (error_found)
13733     {
13734       if (in_instance_initializer)
13735         parse_error_context (wfl_operator,
13736                              "`return' inside instance initializer");
13737         
13738       else if (DECL_CLINIT_P (current_function_decl))
13739         parse_error_context (wfl_operator,
13740                              "`return' inside static initializer");
13741
13742       else if (!DECL_CONSTRUCTOR_P (meth))
13743         {
13744           char *t = xstrdup (lang_printable_name (mtype, 0));
13745           parse_error_context (wfl_operator, 
13746                                "`return' with%s value from `%s %s'",
13747                                (error_found == 1 ? "" : "out"), 
13748                                t, lang_printable_name (meth, 0));
13749           free (t);
13750         }
13751       else
13752         parse_error_context (wfl_operator, 
13753                              "`return' with value from constructor `%s'",
13754                              lang_printable_name (meth, 0));
13755       return error_mark_node;
13756     }
13757
13758   /* If we have a return_exp, build a modify expression and expand
13759      it. Note: at that point, the assignment is declared valid, but we
13760      may want to carry some more hacks */
13761   if (return_exp)
13762     {
13763       tree exp = java_complete_tree (return_exp);
13764       tree modify, patched;
13765
13766       /* If the function returned value and EXP are booleans, EXP has
13767       to be converted into the type of DECL_RESULT, which is integer
13768       (see complete_start_java_method) */
13769       if (TREE_TYPE (exp) == boolean_type_node &&
13770           TREE_TYPE (TREE_TYPE (meth)) == boolean_type_node)
13771         exp = convert_to_integer (TREE_TYPE (DECL_RESULT (meth)), exp);
13772
13773       /* `null' can be assigned to a function returning a reference */
13774       if (JREFERENCE_TYPE_P (TREE_TYPE (TREE_TYPE (meth))) &&
13775           exp == null_pointer_node)
13776         exp = build_null_of_type (TREE_TYPE (TREE_TYPE (meth)));
13777
13778       if ((patched = patch_string (exp)))
13779         exp = patched;
13780       
13781       modify = build (MODIFY_EXPR, NULL_TREE, DECL_RESULT (meth), exp);
13782       EXPR_WFL_LINECOL (modify) = EXPR_WFL_LINECOL (node);
13783       modify = java_complete_tree (modify);
13784
13785       if (modify != error_mark_node)
13786         {
13787           TREE_SIDE_EFFECTS (modify) = 1;
13788           TREE_OPERAND (node, 0) = modify;
13789         }
13790       else
13791         return error_mark_node;
13792     }
13793   TREE_TYPE (node) = void_type_node;
13794   TREE_SIDE_EFFECTS (node) = 1;
13795   return node;
13796 }
13797
13798 /* 14.8 The if Statement */
13799
13800 static tree
13801 build_if_else_statement (location, expression, if_body, else_body)
13802      int location;
13803      tree expression, if_body, else_body;
13804 {
13805   tree node;
13806   if (!else_body)
13807     else_body = empty_stmt_node;
13808   node = build (COND_EXPR, NULL_TREE, expression, if_body, else_body);
13809   EXPR_WFL_LINECOL (node) = location;
13810   node = build_debugable_stmt (location, node);
13811   return node;
13812 }
13813
13814 static tree
13815 patch_if_else_statement (node)
13816      tree node;
13817 {
13818   tree expression = TREE_OPERAND (node, 0);
13819
13820   TREE_TYPE (node) = error_mark_node;
13821   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13822
13823   /* The type of expression must be boolean */
13824   if (TREE_TYPE (expression) != boolean_type_node
13825       && TREE_TYPE (expression) != promoted_boolean_type_node)
13826     {
13827       parse_error_context 
13828         (wfl_operator, 
13829          "Incompatible type for `if'. Can't convert `%s' to `boolean'", 
13830          lang_printable_name (TREE_TYPE (expression), 0));
13831       return error_mark_node;
13832     }
13833   
13834   TREE_TYPE (node) = void_type_node;
13835   TREE_SIDE_EFFECTS (node) = 1;
13836   CAN_COMPLETE_NORMALLY (node)
13837     = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1))
13838     | CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 2));
13839   return node;
13840 }
13841
13842 /* 14.6 Labeled Statements */
13843
13844 /* Action taken when a lableled statement is parsed. a new
13845    LABELED_BLOCK_EXPR is created. No statement is attached to the
13846    label, yet.  LABEL can be NULL_TREE for artificially-generated blocks. */
13847
13848 static tree
13849 build_labeled_block (location, label)
13850      int location;
13851      tree label;
13852 {
13853   tree label_name ;
13854   tree label_decl, node;
13855   if (label == NULL_TREE || label == continue_identifier_node)
13856     label_name = label;
13857   else
13858     {
13859       label_name = merge_qualified_name (label_id, label);
13860       /* Issue an error if we try to reuse a label that was previously
13861          declared */
13862       if (IDENTIFIER_LOCAL_VALUE (label_name))
13863         {
13864           EXPR_WFL_LINECOL (wfl_operator) = location;
13865           parse_error_context (wfl_operator,
13866             "Declaration of `%s' shadows a previous label declaration",
13867                                IDENTIFIER_POINTER (label));
13868           EXPR_WFL_LINECOL (wfl_operator) = 
13869             EXPR_WFL_LINECOL (IDENTIFIER_LOCAL_VALUE (label_name));
13870           parse_error_context (wfl_operator,
13871             "This is the location of the previous declaration of label `%s'",
13872                                IDENTIFIER_POINTER (label));
13873           java_error_count--;
13874         }
13875     }
13876
13877   label_decl = create_label_decl (label_name);
13878   node = build (LABELED_BLOCK_EXPR, NULL_TREE, label_decl, NULL_TREE);
13879   EXPR_WFL_LINECOL (node) = location;
13880   TREE_SIDE_EFFECTS (node) = 1;
13881   return node;
13882 }
13883
13884 /* A labeled statement LBE is attached a statement.  */
13885
13886 static tree
13887 finish_labeled_statement (lbe, statement)
13888      tree lbe;                  /* Labeled block expr */
13889      tree statement;
13890 {
13891   /* In anyways, tie the loop to its statement */
13892   LABELED_BLOCK_BODY (lbe) = statement;
13893   pop_labeled_block ();
13894   POP_LABELED_BLOCK ();
13895   return lbe;
13896 }
13897
13898 /* 14.10, 14.11, 14.12 Loop Statements */
13899
13900 /* Create an empty LOOP_EXPR and make it the last in the nested loop
13901    list. */
13902
13903 static tree
13904 build_new_loop (loop_body)
13905      tree loop_body;
13906 {
13907   tree loop =  build (LOOP_EXPR, NULL_TREE, loop_body);
13908   TREE_SIDE_EFFECTS (loop) = 1;
13909   PUSH_LOOP (loop);
13910   return loop;
13911 }
13912
13913 /* Create a loop body according to the following structure:
13914      COMPOUND_EXPR
13915        COMPOUND_EXPR            (loop main body)
13916          EXIT_EXPR              (this order is for while/for loops.
13917          LABELED_BLOCK_EXPR      the order is reversed for do loops)
13918            LABEL_DECL           (a continue occuring here branches at the 
13919            BODY                  end of this labeled block)
13920        INCREMENT                (if any)
13921
13922   REVERSED, if non zero, tells that the loop condition expr comes
13923   after the body, like in the do-while loop.
13924
13925   To obtain a loop, the loop body structure described above is
13926   encapsulated within a LOOP_EXPR surrounded by a LABELED_BLOCK_EXPR:
13927
13928    LABELED_BLOCK_EXPR
13929      LABEL_DECL                   (use this label to exit the loop)
13930      LOOP_EXPR
13931        <structure described above> */
13932
13933 static tree
13934 build_loop_body (location, condition, reversed)
13935      int location;
13936      tree condition;
13937      int reversed;
13938 {
13939   tree first, second, body;
13940
13941   condition = build (EXIT_EXPR, NULL_TREE, condition); /* Force walk */
13942   EXPR_WFL_LINECOL (condition) = location; /* For accurate error report */
13943   condition = build_debugable_stmt (location, condition);
13944   TREE_SIDE_EFFECTS (condition) = 1;
13945
13946   body = build_labeled_block (0, continue_identifier_node);
13947   first = (reversed ? body : condition);
13948   second = (reversed ? condition : body);
13949   return 
13950     build (COMPOUND_EXPR, NULL_TREE, 
13951            build (COMPOUND_EXPR, NULL_TREE, first, second), empty_stmt_node);
13952 }
13953
13954 /* Install CONDITION (if any) and loop BODY (using REVERSED to tell
13955    their order) on the current loop. Unlink the current loop from the
13956    loop list.  */
13957
13958 static tree
13959 finish_loop_body (location, condition, body, reversed)
13960      int location;
13961      tree condition, body;
13962      int reversed;
13963 {
13964   tree to_return = ctxp->current_loop;
13965   tree loop_body = LOOP_EXPR_BODY (to_return);
13966   if (condition)
13967     {
13968       tree cnode = LOOP_EXPR_BODY_CONDITION_EXPR (loop_body, reversed);
13969       /* We wrapped the EXIT_EXPR around a WFL so we can debug it.
13970          The real EXIT_EXPR is one operand further. */
13971       EXPR_WFL_LINECOL (cnode) = location;
13972       /* This one is for accurate error reports */
13973       EXPR_WFL_LINECOL (TREE_OPERAND (cnode, 0)) = location;
13974       TREE_OPERAND (TREE_OPERAND (cnode, 0), 0) = condition;
13975     }
13976   LOOP_EXPR_BODY_BODY_EXPR (loop_body, reversed) = body;
13977   POP_LOOP ();
13978   return to_return;
13979 }
13980
13981 /* Tailored version of finish_loop_body for FOR loops, when FOR
13982    loops feature the condition part */
13983
13984 static tree
13985 finish_for_loop (location, condition, update, body)
13986     int location;
13987     tree condition, update, body;
13988 {
13989   /* Put the condition and the loop body in place */
13990   tree loop = finish_loop_body (location, condition, body, 0);
13991   /* LOOP is the current loop which has been now popped of the loop
13992      stack. Install the update block */
13993   LOOP_EXPR_BODY_UPDATE_BLOCK (LOOP_EXPR_BODY (loop)) = update;
13994   return loop;
13995 }
13996
13997 /* Try to find the loop a block might be related to. This comprises
13998    the case where the LOOP_EXPR is found as the second operand of a
13999    COMPOUND_EXPR, because the loop happens to have an initialization
14000    part, then expressed as the first operand of the COMPOUND_EXPR. If
14001    the search finds something, 1 is returned. Otherwise, 0 is
14002    returned. The search is assumed to start from a
14003    LABELED_BLOCK_EXPR's block.  */
14004
14005 static tree
14006 search_loop (statement)
14007     tree statement;
14008 {
14009   if (TREE_CODE (statement) == LOOP_EXPR)
14010     return statement;
14011
14012   if (TREE_CODE (statement) == BLOCK)
14013     statement = BLOCK_SUBBLOCKS (statement);
14014   else
14015     return NULL_TREE;
14016
14017   if (statement && TREE_CODE (statement) == COMPOUND_EXPR)
14018     while (statement && TREE_CODE (statement) == COMPOUND_EXPR)
14019       statement = TREE_OPERAND (statement, 1);
14020
14021   return (TREE_CODE (statement) == LOOP_EXPR
14022           && FOR_LOOP_P (statement) ? statement : NULL_TREE);
14023 }
14024
14025 /* Return 1 if LOOP can be found in the labeled block BLOCK. 0 is
14026    returned otherwise.  */
14027
14028 static int
14029 labeled_block_contains_loop_p (block, loop)
14030     tree block, loop;
14031 {
14032   if (!block)
14033     return 0;
14034
14035   if (LABELED_BLOCK_BODY (block) == loop)
14036     return 1;
14037
14038   if (FOR_LOOP_P (loop) && search_loop (LABELED_BLOCK_BODY (block)) == loop)
14039     return 1;
14040
14041   return 0;
14042 }
14043
14044 /* If the loop isn't surrounded by a labeled statement, create one and
14045    insert LOOP as its body.  */
14046
14047 static tree
14048 patch_loop_statement (loop)
14049      tree loop;
14050 {
14051   tree loop_label;
14052
14053   TREE_TYPE (loop) = void_type_node;
14054   if (labeled_block_contains_loop_p (ctxp->current_labeled_block, loop))
14055     return loop;
14056
14057   loop_label = build_labeled_block (0, NULL_TREE);
14058   /* LOOP is an EXPR node, so it should have a valid EXPR_WFL_LINECOL
14059      that LOOP_LABEL could enquire about, for a better accuracy. FIXME */
14060   LABELED_BLOCK_BODY (loop_label) = loop;
14061   PUSH_LABELED_BLOCK (loop_label);
14062   return loop_label;
14063 }
14064
14065 /* 14.13, 14.14: break and continue Statements */
14066
14067 /* Build a break or a continue statement. a null NAME indicates an
14068    unlabeled break/continue statement.  */
14069
14070 static tree
14071 build_bc_statement (location, is_break, name)
14072      int location, is_break;
14073      tree name;
14074 {
14075   tree break_continue, label_block_expr = NULL_TREE;
14076
14077   if (name)
14078     {
14079       if (!(label_block_expr = IDENTIFIER_LOCAL_VALUE 
14080             (merge_qualified_name (label_id, EXPR_WFL_NODE (name)))))
14081         /* Null means that we don't have a target for this named
14082            break/continue. In this case, we make the target to be the
14083            label name, so that the error can be reported accuratly in
14084            patch_bc_statement. */
14085         label_block_expr = EXPR_WFL_NODE (name);
14086     }
14087   /* Unlabeled break/continue will be handled during the
14088      break/continue patch operation */
14089   break_continue 
14090     = build (EXIT_BLOCK_EXPR, NULL_TREE, label_block_expr, NULL_TREE);
14091
14092   IS_BREAK_STMT_P (break_continue) = is_break;
14093   TREE_SIDE_EFFECTS (break_continue) = 1;
14094   EXPR_WFL_LINECOL (break_continue) = location;
14095   break_continue = build_debugable_stmt (location, break_continue);
14096   return break_continue;
14097 }
14098
14099 /* Verification of a break/continue statement. */
14100
14101 static tree
14102 patch_bc_statement (node)
14103      tree node;
14104 {
14105   tree bc_label = EXIT_BLOCK_LABELED_BLOCK (node), target_stmt;
14106   tree labeled_block = ctxp->current_labeled_block;
14107   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14108  
14109   /* Having an identifier here means that the target is unknown. */
14110   if (bc_label != NULL_TREE && TREE_CODE (bc_label) == IDENTIFIER_NODE)
14111     {
14112       parse_error_context (wfl_operator, "No label definition found for `%s'",
14113                            IDENTIFIER_POINTER (bc_label));
14114       return error_mark_node;
14115     }
14116   if (! IS_BREAK_STMT_P (node))
14117     {
14118       /* It's a continue statement. */
14119       for (;; labeled_block = TREE_CHAIN (labeled_block))
14120         {
14121           if (labeled_block == NULL_TREE)
14122             {
14123               if (bc_label == NULL_TREE)
14124                 parse_error_context (wfl_operator,
14125                                      "`continue' must be in loop");
14126               else
14127                 parse_error_context 
14128                   (wfl_operator, "continue label `%s' does not name a loop",
14129                    IDENTIFIER_POINTER (bc_label));
14130               return error_mark_node;
14131             }
14132           if ((DECL_NAME (LABELED_BLOCK_LABEL (labeled_block))
14133                == continue_identifier_node)
14134               && (bc_label == NULL_TREE
14135                   || TREE_CHAIN (labeled_block) == bc_label))
14136             {
14137               bc_label = labeled_block;
14138               break;
14139             }
14140         }
14141     }
14142   else if (!bc_label)
14143     { 
14144       for (;; labeled_block = TREE_CHAIN (labeled_block))
14145         {
14146           if (labeled_block == NULL_TREE)
14147             {
14148               parse_error_context (wfl_operator,
14149                                      "`break' must be in loop or switch");
14150               return error_mark_node;
14151             }
14152           target_stmt = LABELED_BLOCK_BODY (labeled_block);
14153           if (TREE_CODE (target_stmt) == SWITCH_EXPR
14154               || search_loop (target_stmt))
14155             {
14156               bc_label = labeled_block;
14157               break;
14158             }
14159         }
14160     }
14161
14162   EXIT_BLOCK_LABELED_BLOCK (node) = bc_label;
14163   CAN_COMPLETE_NORMALLY (bc_label) = 1;
14164
14165   /* Our break/continue don't return values. */
14166   TREE_TYPE (node) = void_type_node;
14167   /* Encapsulate the break within a compound statement so that it's
14168      expanded all the times by expand_expr (and not clobbered
14169      sometimes, like after a if statement) */
14170   node = add_stmt_to_compound (NULL_TREE, void_type_node, node);
14171   TREE_SIDE_EFFECTS (node) = 1;
14172   return node;
14173 }
14174
14175 /* Process the exit expression belonging to a loop. Its type must be
14176    boolean.  */
14177
14178 static tree
14179 patch_exit_expr (node)
14180      tree node;
14181 {
14182   tree expression = TREE_OPERAND (node, 0);
14183   TREE_TYPE (node) = error_mark_node;
14184   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14185
14186   /* The type of expression must be boolean */
14187   if (TREE_TYPE (expression) != boolean_type_node)
14188     {
14189       parse_error_context 
14190         (wfl_operator, 
14191     "Incompatible type for loop conditional. Can't convert `%s' to `boolean'", 
14192          lang_printable_name (TREE_TYPE (expression), 0));
14193       return error_mark_node;
14194     }
14195   /* Now we know things are allright, invert the condition, fold and
14196      return */
14197   TREE_OPERAND (node, 0) = 
14198     fold (build1 (TRUTH_NOT_EXPR, boolean_type_node, expression));
14199
14200   if (! integer_zerop (TREE_OPERAND (node, 0))
14201       && ctxp->current_loop != NULL_TREE
14202       && TREE_CODE (ctxp->current_loop) == LOOP_EXPR)
14203     CAN_COMPLETE_NORMALLY (ctxp->current_loop) = 1;
14204   if (! integer_onep (TREE_OPERAND (node, 0)))
14205     CAN_COMPLETE_NORMALLY (node) = 1;
14206
14207
14208   TREE_TYPE (node) = void_type_node;
14209   return node;
14210 }
14211
14212 /* 14.9 Switch statement */
14213
14214 static tree
14215 patch_switch_statement (node)
14216      tree node;
14217 {
14218   tree se = TREE_OPERAND (node, 0), se_type;
14219
14220   /* Complete the switch expression */
14221   se = TREE_OPERAND (node, 0) = java_complete_tree (se);
14222   se_type = TREE_TYPE (se);
14223   /* The type of the switch expression must be char, byte, short or
14224      int */
14225   if (!JINTEGRAL_TYPE_P (se_type))
14226     {
14227       EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14228       parse_error_context (wfl_operator,
14229           "Incompatible type for `switch'. Can't convert `%s' to `int'",
14230                            lang_printable_name (se_type, 0));
14231       /* This is what java_complete_tree will check */
14232       TREE_OPERAND (node, 0) = error_mark_node;
14233       return error_mark_node;
14234     }
14235
14236   TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
14237
14238   /* Ready to return */
14239   if (TREE_CODE (TREE_OPERAND (node, 1)) == ERROR_MARK)
14240     {
14241       TREE_TYPE (node) = error_mark_node;
14242       return error_mark_node;
14243     }
14244   TREE_TYPE (node) = void_type_node;
14245   TREE_SIDE_EFFECTS (node) = 1;
14246   CAN_COMPLETE_NORMALLY (node)
14247     = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)) 
14248       || ! SWITCH_HAS_DEFAULT (node);
14249   return node;
14250 }
14251
14252 /* 14.18 The try/catch statements */
14253
14254 static tree
14255 build_try_statement (location, try_block, catches)
14256      int location;
14257      tree try_block, catches;
14258 {
14259   tree node = build (TRY_EXPR, NULL_TREE, try_block, catches);
14260   EXPR_WFL_LINECOL (node) = location;
14261   return node;
14262 }
14263
14264 static tree
14265 build_try_finally_statement (location, try_block, finally)
14266      int location;
14267      tree try_block, finally;
14268 {
14269   tree node = build (TRY_FINALLY_EXPR, NULL_TREE, try_block, finally);
14270   EXPR_WFL_LINECOL (node) = location;
14271   return node;
14272 }
14273
14274 static tree
14275 patch_try_statement (node)
14276      tree node;
14277 {
14278   int error_found = 0;
14279   tree try = TREE_OPERAND (node, 0);
14280   /* Exception handlers are considered in left to right order */
14281   tree catch = nreverse (TREE_OPERAND (node, 1));
14282   tree current, caught_type_list = NULL_TREE;
14283
14284   /* Check catch clauses, if any. Every time we find an error, we try
14285      to process the next catch clause. We process the catch clause before
14286      the try block so that when processing the try block we can check thrown
14287      exceptions againts the caught type list. */
14288   for (current = catch; current; current = TREE_CHAIN (current))
14289     {
14290       tree carg_decl, carg_type;
14291       tree sub_current, catch_block, catch_clause;
14292       int unreachable;
14293
14294       /* At this point, the structure of the catch clause is
14295            CATCH_EXPR           (catch node)
14296              BLOCK              (with the decl of the parameter)
14297                COMPOUND_EXPR
14298                  MODIFY_EXPR   (assignment of the catch parameter)
14299                  BLOCK          (catch clause block)
14300        */
14301       catch_clause = TREE_OPERAND (current, 0);
14302       carg_decl = BLOCK_EXPR_DECLS (catch_clause);
14303       carg_type = TREE_TYPE (TREE_TYPE (carg_decl));
14304
14305       /* Catch clauses can't have more than one parameter declared,
14306          but it's already enforced by the grammar. Make sure that the
14307          only parameter of the clause statement in of class Throwable
14308          or a subclass of Throwable, but that was done earlier. The
14309          catch clause parameter type has also been resolved. */
14310       
14311       /* Just make sure that the catch clause parameter type inherits
14312          from java.lang.Throwable */
14313       if (!inherits_from_p (carg_type, throwable_type_node))
14314         {
14315           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
14316           parse_error_context (wfl_operator,
14317                                "Can't catch class `%s'. Catch clause parameter type must be a subclass of class `java.lang.Throwable'",
14318                                lang_printable_name (carg_type, 0));
14319           error_found = 1;
14320           continue;
14321         }
14322       
14323       /* Partial check for unreachable catch statement: The catch
14324          clause is reachable iff is no earlier catch block A in
14325          the try statement such that the type of the catch
14326          clause's parameter is the same as or a subclass of the
14327          type of A's parameter */
14328       unreachable = 0;
14329       for (sub_current = catch;
14330            sub_current != current; sub_current = TREE_CHAIN (sub_current))
14331         {
14332           tree sub_catch_clause, decl;
14333           sub_catch_clause = TREE_OPERAND (sub_current, 0);
14334           decl = BLOCK_EXPR_DECLS (sub_catch_clause);
14335
14336           if (inherits_from_p (carg_type, TREE_TYPE (TREE_TYPE (decl))))
14337             {
14338               EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
14339               parse_error_context 
14340                 (wfl_operator,
14341                  "`catch' not reached because of the catch clause at line %d",
14342                  EXPR_WFL_LINENO (sub_current));
14343               unreachable = error_found = 1;
14344               break;
14345             }
14346         }
14347       /* Complete the catch clause block */
14348       catch_block = java_complete_tree (TREE_OPERAND (current, 0));
14349       if (catch_block == error_mark_node)
14350         {
14351           error_found = 1;
14352           continue;
14353         }
14354       if (CAN_COMPLETE_NORMALLY (catch_block))
14355         CAN_COMPLETE_NORMALLY (node) = 1;
14356       TREE_OPERAND (current, 0) = catch_block;
14357
14358       if (unreachable)
14359         continue;
14360
14361       /* Things to do here: the exception must be thrown */
14362
14363       /* Link this type to the caught type list */
14364       caught_type_list = tree_cons (NULL_TREE, carg_type, caught_type_list);
14365     }
14366
14367   PUSH_EXCEPTIONS (caught_type_list);
14368   if ((try = java_complete_tree (try)) == error_mark_node)
14369     error_found = 1;
14370   if (CAN_COMPLETE_NORMALLY (try))
14371     CAN_COMPLETE_NORMALLY (node) = 1;
14372   POP_EXCEPTIONS ();
14373
14374   /* Verification ends here */
14375   if (error_found) 
14376     return error_mark_node;
14377
14378   TREE_OPERAND (node, 0) = try;
14379   TREE_OPERAND (node, 1) = catch;
14380   TREE_TYPE (node) = void_type_node;
14381   return node;
14382 }
14383
14384 /* 14.17 The synchronized Statement */
14385
14386 static tree
14387 patch_synchronized_statement (node, wfl_op1)
14388     tree node, wfl_op1;
14389 {
14390   tree expr = java_complete_tree (TREE_OPERAND (node, 0));
14391   tree block = TREE_OPERAND (node, 1);
14392
14393   tree enter, exit, expr_decl, assignment;
14394
14395   if (expr == error_mark_node)
14396     {
14397       block = java_complete_tree (block);
14398       return expr;
14399     }
14400
14401   /* The TYPE of expr must be a reference type */
14402   if (!JREFERENCE_TYPE_P (TREE_TYPE (expr)))
14403     {
14404       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
14405       parse_error_context (wfl_operator, "Incompatible type for `synchronized'. Can't convert `%s' to `java.lang.Object'",
14406                            lang_printable_name (TREE_TYPE (expr), 0));
14407       return error_mark_node;
14408     }
14409
14410   if (flag_emit_xref)
14411     {
14412       TREE_OPERAND (node, 0) = expr;
14413       TREE_OPERAND (node, 1) = java_complete_tree (block);
14414       CAN_COMPLETE_NORMALLY (node) = 1;
14415       return node;
14416     }
14417
14418   /* Generate a try-finally for the synchronized statement, except
14419      that the handler that catches all throw exception calls
14420      _Jv_MonitorExit and then rethrow the exception.
14421      The synchronized statement is then implemented as:
14422      TRY 
14423        {
14424          _Jv_MonitorEnter (expression)
14425          synchronized_block
14426          _Jv_MonitorExit (expression)
14427        }
14428      CATCH_ALL
14429        {
14430          e = _Jv_exception_info ();
14431          _Jv_MonitorExit (expression)
14432          Throw (e);
14433        } */
14434
14435   expr_decl = build_decl (VAR_DECL, generate_name (), TREE_TYPE (expr));
14436   BUILD_MONITOR_ENTER (enter, expr_decl);
14437   BUILD_MONITOR_EXIT (exit, expr_decl);
14438   CAN_COMPLETE_NORMALLY (enter) = 1;
14439   CAN_COMPLETE_NORMALLY (exit) = 1;
14440   assignment = build (MODIFY_EXPR, NULL_TREE, expr_decl, expr);
14441   TREE_SIDE_EFFECTS (assignment) = 1;
14442   node = build1 (CLEANUP_POINT_EXPR, NULL_TREE,
14443                  build (COMPOUND_EXPR, NULL_TREE,
14444                         build (WITH_CLEANUP_EXPR, NULL_TREE,
14445                                build (COMPOUND_EXPR, NULL_TREE,
14446                                       assignment, enter),
14447                                NULL_TREE, exit),
14448                         block));
14449   node = build_expr_block (node, expr_decl);
14450
14451   return java_complete_tree (node);
14452 }
14453
14454 /* 14.16 The throw Statement */
14455
14456 static tree
14457 patch_throw_statement (node, wfl_op1)
14458     tree node, wfl_op1;
14459 {
14460   tree expr = TREE_OPERAND (node, 0);
14461   tree type = TREE_TYPE (expr);
14462   int unchecked_ok = 0, tryblock_throws_ok = 0;
14463
14464   /* Thrown expression must be assignable to java.lang.Throwable */
14465   if (!try_reference_assignconv (throwable_type_node, expr))
14466     {
14467       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
14468       parse_error_context (wfl_operator,
14469     "Can't throw `%s'; it must be a subclass of class `java.lang.Throwable'",
14470                            lang_printable_name (type, 0));
14471       /* If the thrown expression was a reference, we further the
14472          compile-time check. */
14473       if (!JREFERENCE_TYPE_P (type))
14474         return error_mark_node;
14475     }
14476
14477   /* At least one of the following must be true */
14478
14479   /* The type of the throw expression is a not checked exception,
14480      i.e. is a unchecked expression. */
14481   unchecked_ok = IS_UNCHECKED_EXCEPTION_P (TREE_TYPE (type));
14482
14483   SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
14484   /* An instance can't throw a checked excetion unless that exception
14485      is explicitely declared in the `throws' clause of each
14486      constructor. This doesn't apply to anonymous classes, since they
14487      don't have declared constructors. */
14488   if (!unchecked_ok 
14489       && in_instance_initializer && !ANONYMOUS_CLASS_P (current_class))
14490     {
14491       tree current;
14492       for (current = TYPE_METHODS (current_class); current; 
14493            current = TREE_CHAIN (current))
14494         if (DECL_CONSTRUCTOR_P (current) 
14495             && !check_thrown_exceptions_do (TREE_TYPE (expr)))
14496           {
14497             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)", 
14498                                  lang_printable_name (TREE_TYPE (expr), 0));
14499             return error_mark_node;
14500           }
14501     }
14502
14503   /* Throw is contained in a try statement and at least one catch
14504      clause can receive the thrown expression or the current method is
14505      declared to throw such an exception. Or, the throw statement is
14506      contained in a method or constructor declaration and the type of
14507      the Expression is assignable to at least one type listed in the
14508      throws clause the declaration. */
14509   if (!unchecked_ok)
14510     tryblock_throws_ok = check_thrown_exceptions_do (TREE_TYPE (expr));
14511   if (!(unchecked_ok || tryblock_throws_ok))
14512     {
14513       /* If there is a surrounding try block that has no matching
14514          clatch clause, report it first. A surrounding try block exits
14515          only if there is something after the list of checked
14516          exception thrown by the current function (if any). */
14517       if (IN_TRY_BLOCK_P ())
14518         parse_error_context (wfl_operator, "Checked exception `%s' can't be caught by any of the catch clause(s) of the surrounding `try' block",
14519                              lang_printable_name (type, 0));
14520       /* If we have no surrounding try statement and the method doesn't have
14521          any throws, report it now. FIXME */
14522
14523       /* We report that the exception can't be throw from a try block
14524          in all circumstances but when the `throw' is inside a static
14525          block. */
14526       else if (!EXCEPTIONS_P (currently_caught_type_list) 
14527                && !tryblock_throws_ok)
14528         {
14529           if (DECL_CLINIT_P (current_function_decl))
14530             parse_error_context (wfl_operator,
14531                    "Checked exception `%s' can't be thrown in initializer",
14532                                  lang_printable_name (type, 0));
14533           else
14534             parse_error_context (wfl_operator,
14535                    "Checked exception `%s' isn't thrown from a `try' block", 
14536                                  lang_printable_name (type, 0));
14537         }
14538       /* Otherwise, the current method doesn't have the appropriate
14539          throws declaration */
14540       else
14541         parse_error_context (wfl_operator, "Checked exception `%s' doesn't match any of current method's `throws' declaration(s)", 
14542                              lang_printable_name (type, 0));
14543       return error_mark_node;
14544     }
14545
14546   if (! flag_emit_class_files && ! flag_emit_xref)
14547     BUILD_THROW (node, expr);
14548
14549   /* If doing xrefs, keep the location where the `throw' was seen. */
14550   if (flag_emit_xref)
14551     EXPR_WFL_LINECOL (node) = EXPR_WFL_LINECOL (wfl_op1);
14552   return node;
14553 }
14554
14555 /* Check that exception said to be thrown by method DECL can be
14556    effectively caught from where DECL is invoked.  */
14557
14558 static void
14559 check_thrown_exceptions (location, decl)
14560      int location;
14561      tree decl;
14562 {
14563   tree throws;
14564   /* For all the unchecked exceptions thrown by DECL */
14565   for (throws = DECL_FUNCTION_THROWS (decl); throws; 
14566        throws = TREE_CHAIN (throws)) 
14567     if (!check_thrown_exceptions_do (TREE_VALUE (throws)))
14568       {
14569 #if 1
14570         /* Temporary hack to suppresses errors about cloning arrays. FIXME */
14571         if (DECL_NAME (decl) == get_identifier ("clone"))
14572           continue;
14573 #endif
14574         EXPR_WFL_LINECOL (wfl_operator) = location;
14575         if (DECL_FINIT_P (current_function_decl))
14576           parse_error_context
14577             (wfl_operator, "Exception `%s' can't be thrown in initializer",
14578              lang_printable_name (TREE_VALUE (throws), 0));
14579         else 
14580           {
14581             parse_error_context 
14582               (wfl_operator, "Exception `%s' must be caught, or it must be declared in the `throws' clause of `%s'", 
14583                lang_printable_name (TREE_VALUE (throws), 0),
14584                (DECL_INIT_P (current_function_decl) ?
14585                 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))) :
14586                 IDENTIFIER_POINTER (DECL_NAME (current_function_decl))));
14587           }
14588       }
14589 }
14590
14591 /* Return 1 if checked EXCEPTION is caught at the current nesting level of
14592    try-catch blocks, OR is listed in the `throws' clause of the
14593    current method.  */
14594
14595 static int
14596 check_thrown_exceptions_do (exception)
14597      tree exception;
14598 {
14599   tree list = currently_caught_type_list;
14600   resolve_and_layout (exception, NULL_TREE);
14601   /* First, all the nested try-catch-finally at that stage. The
14602      last element contains `throws' clause exceptions, if any. */
14603   if (IS_UNCHECKED_EXCEPTION_P (exception))
14604     return 1;
14605   while (list)
14606     {
14607       tree caught;
14608       for (caught = TREE_VALUE (list); caught; caught = TREE_CHAIN (caught))
14609         if (valid_ref_assignconv_cast_p (exception, TREE_VALUE (caught), 0))
14610           return 1;
14611       list = TREE_CHAIN (list);
14612     }
14613   return 0;
14614 }
14615
14616 static void
14617 purge_unchecked_exceptions (mdecl)
14618      tree mdecl;
14619 {
14620   tree throws = DECL_FUNCTION_THROWS (mdecl);
14621   tree new = NULL_TREE;
14622
14623   while (throws)
14624     {
14625       tree next = TREE_CHAIN (throws);
14626       if (!IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (throws)))
14627         {
14628           TREE_CHAIN (throws) = new;
14629           new = throws;
14630         }
14631       throws = next;
14632     }
14633   /* List is inverted here, but it doesn't matter */
14634   DECL_FUNCTION_THROWS (mdecl) = new;
14635 }
14636
14637 /* 15.24 Conditional Operator ?: */
14638
14639 static tree
14640 patch_conditional_expr (node, wfl_cond, wfl_op1)
14641      tree node, wfl_cond, wfl_op1;
14642 {
14643   tree cond = TREE_OPERAND (node, 0);
14644   tree op1 = TREE_OPERAND (node, 1);
14645   tree op2 = TREE_OPERAND (node, 2);
14646   tree resulting_type = NULL_TREE;
14647   tree t1, t2, patched;
14648   int error_found = 0;
14649
14650   /* Operands of ?: might be StringBuffers crafted as a result of a
14651      string concatenation. Obtain a descent operand here.  */
14652   if ((patched = patch_string (op1)))
14653     TREE_OPERAND (node, 1) = op1 = patched;
14654   if ((patched = patch_string (op2)))
14655     TREE_OPERAND (node, 2) = op2 = patched;
14656
14657   t1 = TREE_TYPE (op1);
14658   t2 = TREE_TYPE (op2);
14659
14660   /* The first expression must be a boolean */
14661   if (TREE_TYPE (cond) != boolean_type_node)
14662     {
14663       SET_WFL_OPERATOR (wfl_operator, node, wfl_cond);
14664       parse_error_context (wfl_operator,
14665                "Incompatible type for `?:'. Can't convert `%s' to `boolean'",
14666                            lang_printable_name (TREE_TYPE (cond), 0));
14667       error_found = 1;
14668     }
14669
14670   /* Second and third can be numeric, boolean (i.e. primitive),
14671      references or null. Anything else results in an error */
14672   if (!((JNUMERIC_TYPE_P (t1) && JNUMERIC_TYPE_P (t2))
14673         || ((JREFERENCE_TYPE_P (t1) || op1 == null_pointer_node) 
14674             && (JREFERENCE_TYPE_P (t2) || op2 == null_pointer_node))
14675         || (t1 == boolean_type_node && t2 == boolean_type_node)))
14676     error_found = 1;
14677
14678   /* Determine the type of the conditional expression. Same types are
14679      easy to deal with */
14680   else if (t1 == t2)
14681     resulting_type = t1;
14682
14683   /* There are different rules for numeric types */
14684   else if (JNUMERIC_TYPE_P (t1))
14685     {
14686       /* if byte/short found, the resulting type is short */
14687       if ((t1 == byte_type_node && t2 == short_type_node)
14688           || (t1 == short_type_node && t2 == byte_type_node))
14689         resulting_type = short_type_node;
14690
14691       /* If t1 is a constant int and t2 is of type byte, short or char
14692          and t1's value fits in t2, then the resulting type is t2 */
14693       else if ((t1 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 1)))
14694           && JBSC_TYPE_P (t2) && int_fits_type_p (TREE_OPERAND (node, 1), t2))
14695         resulting_type = t2;
14696
14697       /* If t2 is a constant int and t1 is of type byte, short or char
14698          and t2's value fits in t1, then the resulting type is t1 */
14699       else if ((t2 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 2)))
14700           && JBSC_TYPE_P (t1) && int_fits_type_p (TREE_OPERAND (node, 2), t1))
14701         resulting_type = t1;
14702
14703       /* Otherwise, binary numeric promotion is applied and the
14704          resulting type is the promoted type of operand 1 and 2 */
14705       else 
14706         resulting_type = binary_numeric_promotion (t1, t2, 
14707                                                    &TREE_OPERAND (node, 1), 
14708                                                    &TREE_OPERAND (node, 2));
14709     }
14710
14711   /* Cases of a reference and a null type */
14712   else if (JREFERENCE_TYPE_P (t1) && op2 == null_pointer_node)
14713     resulting_type = t1;
14714
14715   else if (JREFERENCE_TYPE_P (t2) && op1 == null_pointer_node)
14716     resulting_type = t2;
14717
14718   /* Last case: different reference types. If a type can be converted
14719      into the other one by assignment conversion, the latter
14720      determines the type of the expression */
14721   else if ((resulting_type = try_reference_assignconv (t1, op2)))
14722     resulting_type = promote_type (t1);
14723
14724   else if ((resulting_type = try_reference_assignconv (t2, op1)))
14725     resulting_type = promote_type (t2);
14726
14727   /* If we don't have any resulting type, we're in trouble */
14728   if (!resulting_type)
14729     {
14730       char *t = xstrdup (lang_printable_name (t1, 0));
14731       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
14732       parse_error_context (wfl_operator,
14733                  "Incompatible type for `?:'. Can't convert `%s' to `%s'",
14734                            t, lang_printable_name (t2, 0));
14735       free (t);
14736       error_found = 1;
14737     }
14738
14739   if (error_found)
14740     {
14741       TREE_TYPE (node) = error_mark_node;
14742       return error_mark_node;
14743     }
14744
14745   TREE_TYPE (node) = resulting_type;
14746   TREE_SET_CODE (node, COND_EXPR);
14747   CAN_COMPLETE_NORMALLY (node) = 1;
14748   return node;
14749 }
14750
14751 /* Try to constant fold NODE.
14752    If NODE is not a constant expression, return NULL_EXPR.
14753    CONTEXT is a static final VAR_DECL whose initializer we are folding. */
14754
14755 static tree
14756 fold_constant_for_init (node, context)
14757      tree node;
14758      tree context;
14759 {
14760   tree op0, op1, val;
14761   enum tree_code code = TREE_CODE (node);
14762
14763   if (code == STRING_CST)
14764     return node;
14765
14766   if (code == INTEGER_CST || code == REAL_CST)
14767     return convert (TREE_TYPE (context), node);
14768
14769   switch (code)
14770     {
14771     case PLUS_EXPR:
14772     case MINUS_EXPR:
14773     case MULT_EXPR:
14774     case TRUNC_MOD_EXPR:
14775     case RDIV_EXPR:
14776     case LSHIFT_EXPR:
14777     case RSHIFT_EXPR:
14778     case URSHIFT_EXPR:
14779     case BIT_AND_EXPR:
14780     case BIT_XOR_EXPR:
14781     case BIT_IOR_EXPR:
14782     case TRUTH_ANDIF_EXPR:
14783     case TRUTH_ORIF_EXPR:
14784     case EQ_EXPR: 
14785     case NE_EXPR:
14786     case GT_EXPR:
14787     case GE_EXPR:
14788     case LT_EXPR:
14789     case LE_EXPR:
14790       op0 = TREE_OPERAND (node, 0);
14791       op1 = TREE_OPERAND (node, 1);
14792       val = fold_constant_for_init (op0, context);
14793       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14794         return NULL_TREE;
14795       TREE_OPERAND (node, 0) = val;
14796       val = fold_constant_for_init (op1, context);
14797       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14798         return NULL_TREE;
14799       TREE_OPERAND (node, 1) = val;
14800       return patch_binop (node, op0, op1);
14801
14802     case UNARY_PLUS_EXPR:
14803     case NEGATE_EXPR:
14804     case TRUTH_NOT_EXPR:
14805     case BIT_NOT_EXPR:
14806     case CONVERT_EXPR:
14807       op0 = TREE_OPERAND (node, 0);
14808       val = fold_constant_for_init (op0, context);
14809       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14810         return NULL_TREE;
14811       TREE_OPERAND (node, 0) = val;
14812       return patch_unaryop (node, op0);
14813       break;
14814
14815     case COND_EXPR:
14816       val = fold_constant_for_init (TREE_OPERAND (node, 0), context);
14817       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14818         return NULL_TREE;
14819       TREE_OPERAND (node, 0) = val;
14820       val = fold_constant_for_init (TREE_OPERAND (node, 1), context);
14821       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14822         return NULL_TREE;
14823       TREE_OPERAND (node, 1) = val;
14824       val = fold_constant_for_init (TREE_OPERAND (node, 2), context);
14825       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14826         return NULL_TREE;
14827       TREE_OPERAND (node, 2) = val;
14828       return integer_zerop (TREE_OPERAND (node, 0)) ? TREE_OPERAND (node, 1)
14829         : TREE_OPERAND (node, 2);
14830
14831     case VAR_DECL:
14832     case FIELD_DECL:
14833       if (! FIELD_FINAL (node)
14834           || DECL_INITIAL (node) == NULL_TREE)
14835         return NULL_TREE;
14836       val = DECL_INITIAL (node);
14837       /* Guard against infinite recursion. */
14838       DECL_INITIAL (node) = NULL_TREE;
14839       val = fold_constant_for_init (val, node);
14840       DECL_INITIAL (node) = val;
14841       return val;
14842
14843     case EXPR_WITH_FILE_LOCATION:
14844       /* Compare java_complete_tree and resolve_expression_name. */
14845       if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
14846           || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
14847         {
14848           tree name = EXPR_WFL_NODE (node);
14849           tree decl;
14850           if (PRIMARY_P (node))
14851             return NULL_TREE;
14852           else if (! QUALIFIED_P (name))
14853             {
14854               decl = lookup_field_wrapper (DECL_CONTEXT (context), name);
14855               if (decl == NULL_TREE 
14856                   || (! FIELD_STATIC (decl) && ! FIELD_FINAL (decl)))
14857                 return NULL_TREE;
14858               return fold_constant_for_init (decl, decl);
14859             }
14860           else
14861             {
14862               /* Wait until the USE_COMPONENT_REF re-write.  FIXME. */
14863               qualify_ambiguous_name (node);
14864               if (resolve_field_access (node, &decl, NULL)
14865                   && decl != NULL_TREE)
14866                 return fold_constant_for_init (decl, decl);
14867               return NULL_TREE;
14868             }
14869         }
14870       else
14871         {
14872           op0 = TREE_OPERAND (node, 0);
14873           val = fold_constant_for_init (op0, context);
14874           if (val == NULL_TREE || ! TREE_CONSTANT (val))
14875             return NULL_TREE;
14876           TREE_OPERAND (node, 0) = val;
14877           return val;
14878         }
14879
14880 #ifdef USE_COMPONENT_REF
14881     case IDENTIFIER:
14882     case COMPONENT_REF:
14883       ?;
14884 #endif
14885
14886     default:
14887       return NULL_TREE;
14888     }
14889 }
14890
14891 #ifdef USE_COMPONENT_REF
14892 /* Context is 'T' for TypeName, 'P' for PackageName,
14893    'M' for MethodName, 'E' for ExpressionName, and 'A' for AmbiguousName. */
14894
14895 tree
14896 resolve_simple_name (name, context)
14897      tree name;
14898      int context;
14899 {
14900 }
14901
14902 tree
14903 resolve_qualified_name (name, context)
14904      tree name;
14905      int context;
14906 {
14907 }
14908 #endif