OSDN Git Service

0aded2585115cbb2d96efbd190724ad7cda91829
[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 ((tree));
85 static int  parser_check_super PARAMS ((tree, tree, tree));
86 static int  parser_check_super_interface PARAMS ((tree, tree, tree));
87 static void check_modifiers_consistency PARAMS ((int));
88 static tree lookup_cl PARAMS ((tree));
89 static tree lookup_java_method2 PARAMS ((tree, tree, int));
90 static tree method_header PARAMS ((int, tree, tree, tree));
91 static void fix_method_argument_names PARAMS ((tree ,tree));
92 static tree method_declarator PARAMS ((tree, tree));
93 static void parse_warning_context PARAMS ((tree cl, const char *msg, ...))
94   ATTRIBUTE_PRINTF_2;
95 static void issue_warning_error_from_context PARAMS ((tree, const char *msg, va_list));
96 static void parse_ctor_invocation_error PARAMS ((void));
97 static tree parse_jdk1_1_error PARAMS ((const char *));
98 static void complete_class_report_errors PARAMS ((jdep *));
99 static int process_imports PARAMS ((void));
100 static void read_import_dir PARAMS ((tree));
101 static int find_in_imports_on_demand PARAMS ((tree));
102 static void find_in_imports PARAMS ((tree));
103 static void check_inner_class_access PARAMS ((tree, tree, tree));
104 static int check_pkg_class_access PARAMS ((tree, tree));
105 static void register_package PARAMS ((tree));
106 static tree resolve_package PARAMS ((tree, tree *));
107 static tree lookup_package_type PARAMS ((const char *, int));
108 static tree lookup_package_type_and_set_next PARAMS ((const char *, int, tree *));
109 static tree resolve_class PARAMS ((tree, tree, tree, tree));
110 static void declare_local_variables PARAMS ((int, tree, tree));
111 static void source_start_java_method PARAMS ((tree));
112 static void source_end_java_method PARAMS ((void));
113 static void expand_start_java_method PARAMS ((tree));
114 static tree find_name_in_single_imports PARAMS ((tree));
115 static void check_abstract_method_header PARAMS ((tree));
116 static tree lookup_java_interface_method2 PARAMS ((tree, tree));
117 static tree resolve_expression_name PARAMS ((tree, tree *));
118 static tree maybe_create_class_interface_decl PARAMS ((tree, tree, tree, tree));
119 static int check_class_interface_creation PARAMS ((int, int, tree, 
120                                                   tree, tree, tree));
121 static tree patch_method_invocation PARAMS ((tree, tree, tree, 
122                                             int *, tree *));
123 static int breakdown_qualified PARAMS ((tree *, tree *, tree));
124 static tree resolve_and_layout PARAMS ((tree, tree));
125 static tree qualify_and_find PARAMS ((tree, tree, tree));
126 static tree resolve_no_layout PARAMS ((tree, tree));
127 static int invocation_mode PARAMS ((tree, int));
128 static tree find_applicable_accessible_methods_list PARAMS ((int, tree, 
129                                                             tree, tree));
130 static void search_applicable_methods_list PARAMS ((int, tree, tree, tree, 
131                                                    tree *, tree *));
132 static tree find_most_specific_methods_list PARAMS ((tree));
133 static int argument_types_convertible PARAMS ((tree, tree));
134 static tree patch_invoke PARAMS ((tree, tree, tree));
135 static int maybe_use_access_method PARAMS ((int, tree *, tree *));
136 static tree lookup_method_invoke PARAMS ((int, tree, tree, tree, tree));
137 static tree register_incomplete_type PARAMS ((int, tree, tree, tree));
138 static tree obtain_incomplete_type PARAMS ((tree));
139 static tree java_complete_lhs PARAMS ((tree));
140 static tree java_complete_tree PARAMS ((tree));
141 static tree maybe_generate_pre_expand_clinit PARAMS ((tree));
142 static int maybe_yank_clinit PARAMS ((tree));
143 static void java_complete_expand_method PARAMS ((tree));
144 static int  unresolved_type_p PARAMS ((tree, tree *));
145 static void create_jdep_list PARAMS ((struct parser_ctxt *));
146 static tree build_expr_block PARAMS ((tree, tree));
147 static tree enter_block PARAMS ((void));
148 static tree enter_a_block PARAMS ((tree));
149 static tree exit_block PARAMS ((void));
150 static tree lookup_name_in_blocks PARAMS ((tree));
151 static void maybe_absorb_scoping_blocks PARAMS ((void));
152 static tree build_method_invocation PARAMS ((tree, tree));
153 static tree build_new_invocation PARAMS ((tree, tree));
154 static tree build_assignment PARAMS ((int, int, tree, tree));
155 static tree build_binop PARAMS ((enum tree_code, int, tree, tree));
156 static int check_final_assignment PARAMS ((tree ,tree));
157 static tree patch_assignment PARAMS ((tree, tree, tree ));
158 static tree patch_binop PARAMS ((tree, tree, tree));
159 static tree build_unaryop PARAMS ((int, int, tree));
160 static tree build_incdec PARAMS ((int, int, tree, int));
161 static tree patch_unaryop PARAMS ((tree, tree));
162 static tree build_cast PARAMS ((int, tree, tree));
163 static tree build_null_of_type PARAMS ((tree));
164 static tree patch_cast PARAMS ((tree, tree));
165 static int valid_ref_assignconv_cast_p PARAMS ((tree, tree, int));
166 static int valid_builtin_assignconv_identity_widening_p PARAMS ((tree, tree));
167 static int valid_cast_to_p PARAMS ((tree, tree));
168 static int valid_method_invocation_conversion_p PARAMS ((tree, tree));
169 static tree try_builtin_assignconv PARAMS ((tree, tree, tree));
170 static tree try_reference_assignconv PARAMS ((tree, tree));
171 static tree build_unresolved_array_type PARAMS ((tree));
172 static tree build_array_from_name PARAMS ((tree, tree, tree, tree *));
173 static tree build_array_ref PARAMS ((int, tree, tree));
174 static tree patch_array_ref PARAMS ((tree));
175 static tree make_qualified_name PARAMS ((tree, tree, int));
176 static tree merge_qualified_name PARAMS ((tree, tree));
177 static tree make_qualified_primary PARAMS ((tree, tree, int));
178 static int resolve_qualified_expression_name PARAMS ((tree, tree *, 
179                                                      tree *, tree *));
180 static void qualify_ambiguous_name PARAMS ((tree));
181 static tree resolve_field_access PARAMS ((tree, tree *, tree *));
182 static tree build_newarray_node PARAMS ((tree, tree, int));
183 static tree patch_newarray PARAMS ((tree));
184 static tree resolve_type_during_patch PARAMS ((tree));
185 static tree build_this PARAMS ((int));
186 static tree build_wfl_wrap PARAMS ((tree, int));
187 static tree build_return PARAMS ((int, tree));
188 static tree patch_return PARAMS ((tree));
189 static tree maybe_access_field PARAMS ((tree, tree, tree));
190 static int complete_function_arguments PARAMS ((tree));
191 static int check_for_static_method_reference PARAMS ((tree, tree, tree, 
192                                                       tree, tree));
193 static int not_accessible_p PARAMS ((tree, tree, int));
194 static void check_deprecation PARAMS ((tree, tree));
195 static int class_in_current_package PARAMS ((tree));
196 static tree build_if_else_statement PARAMS ((int, tree, tree, tree));
197 static tree patch_if_else_statement PARAMS ((tree));
198 static tree add_stmt_to_compound PARAMS ((tree, tree, tree));
199 static tree add_stmt_to_block PARAMS ((tree, tree, tree));
200 static tree patch_exit_expr PARAMS ((tree));
201 static tree build_labeled_block PARAMS ((int, tree));
202 static tree finish_labeled_statement PARAMS ((tree, tree));
203 static tree build_bc_statement PARAMS ((int, int, tree));
204 static tree patch_bc_statement PARAMS ((tree));
205 static tree patch_loop_statement PARAMS ((tree));
206 static tree build_new_loop PARAMS ((tree));
207 static tree build_loop_body PARAMS ((int, tree, int));
208 static tree finish_loop_body PARAMS ((int, tree, tree, int));
209 static tree build_debugable_stmt PARAMS ((int, tree));
210 static tree finish_for_loop PARAMS ((int, tree, tree, tree));
211 static tree patch_switch_statement PARAMS ((tree));
212 static tree string_constant_concatenation PARAMS ((tree, tree));
213 static tree build_string_concatenation PARAMS ((tree, tree));
214 static tree patch_string_cst PARAMS ((tree));
215 static tree patch_string PARAMS ((tree));
216 static tree build_try_statement PARAMS ((int, tree, tree));
217 static tree build_try_finally_statement PARAMS ((int, tree, tree));
218 static tree patch_try_statement PARAMS ((tree));
219 static tree patch_synchronized_statement PARAMS ((tree, tree));
220 static tree patch_throw_statement PARAMS ((tree, tree));
221 static void check_thrown_exceptions PARAMS ((int, tree));
222 static int check_thrown_exceptions_do PARAMS ((tree));
223 static void purge_unchecked_exceptions PARAMS ((tree));
224 static void check_throws_clauses PARAMS ((tree, tree, tree));
225 static void finish_method_declaration PARAMS ((tree));
226 static tree build_super_invocation PARAMS ((tree));
227 static int verify_constructor_circularity PARAMS ((tree, tree));
228 static char *constructor_circularity_msg PARAMS ((tree, tree));
229 static tree build_this_super_qualified_invocation PARAMS ((int, tree, tree,
230                                                           int, int));
231 static const char *get_printable_method_name PARAMS ((tree));
232 static tree patch_conditional_expr PARAMS ((tree, tree, tree));
233 static tree generate_finit PARAMS ((tree));
234 static void add_instance_initializer PARAMS ((tree));
235 static void fix_constructors PARAMS ((tree));
236 static tree build_alias_initializer_parameter_list PARAMS ((int, tree,
237                                                             tree, int *));
238 static void craft_constructor PARAMS ((tree, tree));
239 static int verify_constructor_super PARAMS ((tree));
240 static tree create_artificial_method PARAMS ((tree, int, tree, tree, tree));
241 static void start_artificial_method_body PARAMS ((tree));
242 static void end_artificial_method_body PARAMS ((tree));
243 static int check_method_redefinition PARAMS ((tree, tree));
244 static int reset_method_name PARAMS ((tree));
245 static int check_method_types_complete PARAMS ((tree));
246 static void java_check_regular_methods PARAMS ((tree));
247 static void java_check_abstract_methods PARAMS ((tree));
248 static tree maybe_build_primttype_type_ref PARAMS ((tree, tree));
249 static void unreachable_stmt_error PARAMS ((tree));
250 static tree find_expr_with_wfl PARAMS ((tree));
251 static void missing_return_error PARAMS ((tree));
252 static tree build_new_array_init PARAMS ((int, tree));
253 static tree patch_new_array_init PARAMS ((tree, tree));
254 static tree maybe_build_array_element_wfl PARAMS ((tree));
255 static int array_constructor_check_entry PARAMS ((tree, tree));
256 static const char *purify_type_name PARAMS ((const char *));
257 static tree fold_constant_for_init PARAMS ((tree, tree));
258 static tree strip_out_static_field_access_decl PARAMS ((tree));
259 static jdeplist *reverse_jdep_list PARAMS ((struct parser_ctxt *));
260 static void static_ref_err PARAMS ((tree, tree, tree));
261 static void parser_add_interface PARAMS ((tree, tree, tree));
262 static void add_superinterfaces PARAMS ((tree, tree));
263 static tree jdep_resolve_class PARAMS ((jdep *));
264 static int note_possible_classname PARAMS ((const char *, int));
265 static void java_complete_expand_classes PARAMS ((void));
266 static void java_complete_expand_class PARAMS ((tree));
267 static void java_complete_expand_methods PARAMS ((tree));
268 static tree cut_identifier_in_qualified PARAMS ((tree));
269 static tree java_stabilize_reference PARAMS ((tree));
270 static tree do_unary_numeric_promotion PARAMS ((tree));
271 static char * operator_string PARAMS ((tree));
272 static tree do_merge_string_cste PARAMS ((tree, const char *, int, int));
273 static tree merge_string_cste PARAMS ((tree, tree, int));
274 static tree java_refold PARAMS ((tree));
275 static int java_decl_equiv PARAMS ((tree, tree));
276 static int binop_compound_p PARAMS ((enum tree_code));
277 static tree search_loop PARAMS ((tree));
278 static int labeled_block_contains_loop_p PARAMS ((tree, tree));
279 static void check_abstract_method_definitions PARAMS ((int, tree, tree));
280 static void java_check_abstract_method_definitions PARAMS ((tree));
281 static void java_debug_context_do PARAMS ((int));
282 static void java_parser_context_push_initialized_field PARAMS ((void));
283 static void java_parser_context_pop_initialized_field PARAMS ((void));
284 static tree reorder_static_initialized PARAMS ((tree));
285 static void java_parser_context_suspend PARAMS ((void));
286 static void java_parser_context_resume PARAMS ((void));
287
288 /* JDK 1.1 work. FIXME */
289
290 static tree maybe_make_nested_class_name PARAMS ((tree));
291 static void make_nested_class_name PARAMS ((tree));
292 static void set_nested_class_simple_name_value PARAMS ((tree, int));
293 static void link_nested_class_to_enclosing PARAMS ((void));
294 static tree find_as_inner_class PARAMS ((tree, tree, tree));
295 static tree find_as_inner_class_do PARAMS ((tree, tree));
296 static int check_inner_class_redefinition PARAMS ((tree, tree));
297
298 static tree build_thisn_assign PARAMS ((void));
299 static tree build_current_thisn PARAMS ((tree));
300 static tree build_access_to_thisn PARAMS ((tree, tree, int));
301 static tree maybe_build_thisn_access_method PARAMS ((tree));
302
303 static tree build_outer_field_access PARAMS ((tree, tree));
304 static tree build_outer_field_access_methods PARAMS ((tree));
305 static tree build_outer_field_access_expr PARAMS ((int, tree, tree, 
306                                                   tree, tree));
307 static tree build_outer_method_access_method PARAMS ((tree));
308 static tree build_new_access_id PARAMS ((void));
309 static tree build_outer_field_access_method PARAMS ((tree, tree, tree,
310                                                     tree, tree));
311
312 static int outer_field_access_p PARAMS ((tree, tree));
313 static int outer_field_expanded_access_p PARAMS ((tree, tree *, 
314                                                  tree *, tree *));
315 static tree outer_field_access_fix PARAMS ((tree, tree, tree));
316 static tree build_incomplete_class_ref PARAMS ((int, tree));
317 static tree patch_incomplete_class_ref PARAMS ((tree));
318 static tree create_anonymous_class PARAMS ((int, tree));
319 static void patch_anonymous_class PARAMS ((tree, tree, tree));
320 static void add_inner_class_fields PARAMS ((tree, tree));
321
322 static tree build_dot_class_method PARAMS ((tree));
323 static tree build_dot_class_method_invocation PARAMS ((tree));
324 static void create_new_parser_context PARAMS ((int));
325
326 /* Number of error found so far. */
327 int java_error_count; 
328 /* Number of warning found so far. */
329 int java_warning_count;
330 /* Tell when not to fold, when doing xrefs */
331 int do_not_fold;
332 /* Cyclic inheritance report, as it can be set by layout_class */
333 char *cyclic_inheritance_report;
334
335 /* Tell when we're within an instance initializer */
336 static int in_instance_initializer;
337
338 /* The current parser context */
339 struct parser_ctxt *ctxp;
340
341 /* List of things that were analyzed for which code will be generated */
342 static struct parser_ctxt *ctxp_for_generation = NULL;
343
344 /* binop_lookup maps token to tree_code. It is used where binary
345    operations are involved and required by the parser. RDIV_EXPR
346    covers both integral/floating point division. The code is changed
347    once the type of both operator is worked out.  */
348
349 static enum tree_code binop_lookup[19] = 
350   { 
351     PLUS_EXPR, MINUS_EXPR, MULT_EXPR, RDIV_EXPR, TRUNC_MOD_EXPR,
352     LSHIFT_EXPR, RSHIFT_EXPR, URSHIFT_EXPR, 
353     BIT_AND_EXPR, BIT_XOR_EXPR, BIT_IOR_EXPR,
354     TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR,
355     EQ_EXPR, NE_EXPR, GT_EXPR, GE_EXPR, LT_EXPR, LE_EXPR,
356    };
357 #define BINOP_LOOKUP(VALUE)                                             \
358   binop_lookup [((VALUE) - PLUS_TK)%                                    \
359                 (sizeof (binop_lookup) / sizeof (binop_lookup[0]))]
360
361 /* This is the end index for binary operators that can also be used
362    in compound assignements. */
363 #define BINOP_COMPOUND_CANDIDATES 11
364
365 /* Fake WFL used to report error message. It is initialized once if
366    needed and reused with it's location information is overriden.  */
367 tree wfl_operator = NULL_TREE;
368
369 /* The "$L" identifier we use to create labels.  */
370 static tree label_id = NULL_TREE;
371
372 /* The "StringBuffer" identifier used for the String `+' operator. */
373 static tree wfl_string_buffer = NULL_TREE; 
374
375 /* The "append" identifier used for String `+' operator.  */
376 static tree wfl_append = NULL_TREE;
377
378 /* The "toString" identifier used for String `+' operator. */
379 static tree wfl_to_string = NULL_TREE;
380
381 /* The "java.lang" import qualified name.  */
382 static tree java_lang_id = NULL_TREE;
383
384 /* The generated `inst$' identifier used for generated enclosing
385    instance/field access functions.  */
386 static tree inst_id = NULL_TREE;
387
388 /* The "java.lang.Cloneable" qualified name.  */
389 static tree java_lang_cloneable = NULL_TREE;
390
391 /* Context and flag for static blocks */
392 static tree current_static_block = NULL_TREE;
393
394 /* The generated `write_parm_value$' identifier.  */
395 static tree wpv_id;
396
397 /* The list of all packages we've seen so far */
398 static tree package_list = NULL_TREE;
399  
400 /* Check modifiers. If one doesn't fit, retrieve it in its declaration
401    line and point it out.  */
402 /* Should point out the one that don't fit. ASCII/unicode, going
403    backward. FIXME */
404
405 #define check_modifiers(__message, __value, __mask) do {        \
406   if ((__value) & ~(__mask))                                    \
407     {                                                           \
408       int i, remainder = (__value) & ~(__mask);                 \
409       for (i = 0; i <= 10; i++)                                 \
410         if ((1 << i) & remainder)                               \
411           parse_error_context (ctxp->modifier_ctx [i], (__message), \
412                                java_accstring_lookup (1 << i)); \
413     }                                                           \
414 } while (0)
415
416 %}
417
418 %union {
419   tree node;
420   int sub_token;
421   struct {
422     int token;
423     int location;
424   } operator;
425   int value;
426 }
427
428 %{
429 #include "lex.c"
430 %}
431
432 %pure_parser
433
434 /* Things defined here have to match the order of what's in the
435    binop_lookup table.  */
436
437 %token   PLUS_TK         MINUS_TK        MULT_TK         DIV_TK    REM_TK
438 %token   LS_TK           SRS_TK          ZRS_TK
439 %token   AND_TK          XOR_TK          OR_TK
440 %token   BOOL_AND_TK BOOL_OR_TK 
441 %token   EQ_TK NEQ_TK GT_TK GTE_TK LT_TK LTE_TK
442
443 /* This maps to the same binop_lookup entry than the token above */
444
445 %token   PLUS_ASSIGN_TK  MINUS_ASSIGN_TK MULT_ASSIGN_TK DIV_ASSIGN_TK
446 %token   REM_ASSIGN_TK   
447 %token   LS_ASSIGN_TK    SRS_ASSIGN_TK   ZRS_ASSIGN_TK
448 %token   AND_ASSIGN_TK   XOR_ASSIGN_TK   OR_ASSIGN_TK
449
450
451 /* Modifier TOKEN have to be kept in this order. Don't scramble it */
452
453 %token   PUBLIC_TK       PRIVATE_TK         PROTECTED_TK
454 %token   STATIC_TK       FINAL_TK           SYNCHRONIZED_TK
455 %token   VOLATILE_TK     TRANSIENT_TK       NATIVE_TK
456 %token   PAD_TK          ABSTRACT_TK        MODIFIER_TK
457
458 /* Keep those two in order, too */
459 %token   DECR_TK INCR_TK
460
461 /* From now one, things can be in any order */
462
463 %token   DEFAULT_TK      IF_TK              THROW_TK
464 %token   BOOLEAN_TK      DO_TK              IMPLEMENTS_TK
465 %token   THROWS_TK       BREAK_TK           IMPORT_TK       
466 %token   ELSE_TK         INSTANCEOF_TK      RETURN_TK
467 %token   VOID_TK         CATCH_TK           INTERFACE_TK
468 %token   CASE_TK         EXTENDS_TK         FINALLY_TK
469 %token   SUPER_TK        WHILE_TK           CLASS_TK
470 %token   SWITCH_TK       CONST_TK           TRY_TK
471 %token   FOR_TK          NEW_TK             CONTINUE_TK
472 %token   GOTO_TK         PACKAGE_TK         THIS_TK
473
474 %token   BYTE_TK         SHORT_TK           INT_TK            LONG_TK
475 %token   CHAR_TK         INTEGRAL_TK
476
477 %token   FLOAT_TK        DOUBLE_TK          FP_TK
478
479 %token   ID_TK
480
481 %token   REL_QM_TK         REL_CL_TK NOT_TK  NEG_TK
482
483 %token   ASSIGN_ANY_TK   ASSIGN_TK
484 %token   OP_TK  CP_TK  OCB_TK  CCB_TK  OSB_TK  CSB_TK  SC_TK  C_TK DOT_TK
485
486 %token   STRING_LIT_TK   CHAR_LIT_TK        INT_LIT_TK        FP_LIT_TK
487 %token   TRUE_TK         FALSE_TK           BOOL_LIT_TK       NULL_TK
488
489 %type    <value>        modifiers MODIFIER_TK final synchronized
490
491 %type    <node>         super ID_TK identifier
492 %type    <node>         name simple_name qualified_name
493 %type    <node>         type_declaration compilation_unit
494                         field_declaration method_declaration extends_interfaces
495                         interfaces interface_type_list
496                         class_member_declaration
497                         import_declarations package_declaration 
498                         type_declarations interface_body
499                         interface_member_declaration constant_declaration
500                         interface_member_declarations interface_type
501                         abstract_method_declaration interface_type_list
502 %type    <node>         class_body_declaration class_member_declaration
503                         static_initializer constructor_declaration block
504 %type    <node>         class_body_declarations constructor_header
505 %type    <node>         class_or_interface_type class_type class_type_list
506                         constructor_declarator explicit_constructor_invocation
507 %type    <node>         dim_expr dim_exprs this_or_super throws
508
509 %type    <node>         variable_declarator_id variable_declarator
510                         variable_declarators variable_initializer
511                         variable_initializers constructor_body
512                         array_initializer
513
514 %type    <node>         class_body block_end constructor_block_end
515 %type    <node>         statement statement_without_trailing_substatement
516                         labeled_statement if_then_statement label_decl
517                         if_then_else_statement while_statement for_statement
518                         statement_nsi labeled_statement_nsi do_statement
519                         if_then_else_statement_nsi while_statement_nsi
520                         for_statement_nsi statement_expression_list for_init
521                         for_update statement_expression expression_statement
522                         primary_no_new_array expression primary
523                         array_creation_expression array_type
524                         class_instance_creation_expression field_access
525                         method_invocation array_access something_dot_new
526                         argument_list postfix_expression while_expression 
527                         post_increment_expression post_decrement_expression
528                         unary_expression_not_plus_minus unary_expression
529                         pre_increment_expression pre_decrement_expression
530                         unary_expression_not_plus_minus cast_expression
531                         multiplicative_expression additive_expression
532                         shift_expression relational_expression 
533                         equality_expression and_expression 
534                         exclusive_or_expression inclusive_or_expression
535                         conditional_and_expression conditional_or_expression
536                         conditional_expression assignment_expression
537                         left_hand_side assignment for_header for_begin
538                         constant_expression do_statement_begin empty_statement
539                         switch_statement synchronized_statement throw_statement
540                         try_statement switch_expression switch_block
541                         catches catch_clause catch_clause_parameter finally
542                         anonymous_class_creation
543 %type    <node>         return_statement break_statement continue_statement
544
545 %type    <operator>     ASSIGN_TK      MULT_ASSIGN_TK  DIV_ASSIGN_TK  
546 %type    <operator>     REM_ASSIGN_TK  PLUS_ASSIGN_TK  MINUS_ASSIGN_TK
547 %type    <operator>     LS_ASSIGN_TK   SRS_ASSIGN_TK   ZRS_ASSIGN_TK
548 %type    <operator>     AND_ASSIGN_TK  XOR_ASSIGN_TK   OR_ASSIGN_TK
549 %type    <operator>     ASSIGN_ANY_TK  assignment_operator
550 %token   <operator>     EQ_TK GTE_TK ZRS_TK SRS_TK GT_TK LTE_TK LS_TK 
551 %token   <operator>     BOOL_AND_TK AND_TK BOOL_OR_TK OR_TK INCR_TK PLUS_TK
552 %token   <operator>     DECR_TK MINUS_TK MULT_TK DIV_TK XOR_TK REM_TK NEQ_TK
553 %token   <operator>     NEG_TK REL_QM_TK REL_CL_TK NOT_TK LT_TK OCB_TK CCB_TK
554 %token   <operator>     OP_TK OSB_TK DOT_TK THROW_TK INSTANCEOF_TK
555 %type    <operator>     THIS_TK SUPER_TK RETURN_TK BREAK_TK CONTINUE_TK 
556 %type    <operator>     CASE_TK DEFAULT_TK TRY_TK CATCH_TK SYNCHRONIZED_TK
557 %type    <operator>     NEW_TK
558
559 %type    <node>         method_body 
560         
561 %type    <node>         literal INT_LIT_TK FP_LIT_TK BOOL_LIT_TK CHAR_LIT_TK
562                         STRING_LIT_TK NULL_TK VOID_TK
563
564 %type    <node>         IF_TK WHILE_TK FOR_TK
565
566 %type    <node>         formal_parameter_list formal_parameter
567                         method_declarator method_header
568
569 %type    <node>         primitive_type reference_type type 
570                         BOOLEAN_TK INTEGRAL_TK FP_TK
571
572 /* Added or modified JDK 1.1 rule types  */
573 %type    <node>         type_literals array_type_literal
574
575 %%
576 /* 19.2 Production from 2.3: The Syntactic Grammar  */
577 goal:
578         compilation_unit
579                 {}
580 ;
581
582 /* 19.3 Productions from 3: Lexical structure  */
583 literal:
584         INT_LIT_TK
585 |       FP_LIT_TK
586 |       BOOL_LIT_TK
587 |       CHAR_LIT_TK
588 |       STRING_LIT_TK
589 |       NULL_TK
590 ;
591
592 /* 19.4 Productions from 4: Types, Values and Variables  */
593 type:
594         primitive_type
595 |       reference_type
596 ;
597
598 primitive_type:
599         INTEGRAL_TK
600 |       FP_TK
601 |       BOOLEAN_TK
602 ;
603
604 reference_type:
605         class_or_interface_type
606 |       array_type
607 ;
608
609 class_or_interface_type:
610         name
611 ;
612
613 class_type:
614         class_or_interface_type /* Default rule */
615 ;
616
617 interface_type:
618          class_or_interface_type
619 ;
620
621 array_type:
622         primitive_type OSB_TK CSB_TK
623                 { 
624                   $$ = build_java_array_type ($1, -1);
625                   CLASS_LOADED_P ($$) = 1;
626                 }
627 |       name OSB_TK CSB_TK
628                 { $$ = build_unresolved_array_type ($1); }
629 |       array_type OSB_TK CSB_TK
630                 { $$ = build_unresolved_array_type ($1); }
631 |       primitive_type OSB_TK error
632                 {RULE ("']' expected"); RECOVER;}
633 |       array_type OSB_TK error
634                 {RULE ("']' expected"); RECOVER;}
635 ;
636
637 /* 19.5 Productions from 6: Names  */
638 name:
639         simple_name             /* Default rule */
640 |       qualified_name          /* Default rule */
641 ;
642
643 simple_name:
644         identifier              /* Default rule */
645         {
646           if (strchr (IDENTIFIER_POINTER (EXPR_WFL_NODE ($$)), '$'))
647             parse_error_context ($$, "Invalid type name `%s'",
648                                  IDENTIFIER_POINTER (EXPR_WFL_NODE ($$)));
649         }
650 ;
651
652 qualified_name:
653         name DOT_TK identifier
654                 { $$ = make_qualified_name ($1, $3, $2.location); }
655 ;
656
657 identifier:
658         ID_TK
659 ;
660
661 /* 19.6: Production from 7: Packages  */
662 compilation_unit:
663                 {$$ = NULL;}
664 |       package_declaration
665 |       import_declarations
666 |       type_declarations
667 |       package_declaration import_declarations
668 |       package_declaration type_declarations
669 |       import_declarations type_declarations
670 |       package_declaration import_declarations type_declarations
671 ;
672
673 import_declarations:
674         import_declaration
675                 {
676                   $$ = NULL;
677                 }
678 |       import_declarations import_declaration
679                 {
680                   $$ = NULL;
681                 }
682 ;
683
684 type_declarations:
685         type_declaration
686 |       type_declarations type_declaration
687 ;
688
689 package_declaration:
690         PACKAGE_TK name SC_TK
691                 { 
692                   ctxp->package = EXPR_WFL_NODE ($2);
693                   register_package (ctxp->package);
694                 }
695 |       PACKAGE_TK error
696                 {yyerror ("Missing name"); RECOVER;}
697 |       PACKAGE_TK name error
698                 {yyerror ("';' expected"); RECOVER;}
699 ;
700
701 import_declaration:
702         single_type_import_declaration
703 |       type_import_on_demand_declaration
704 ;
705
706 single_type_import_declaration:
707         IMPORT_TK name SC_TK
708                 {
709                   tree name = EXPR_WFL_NODE ($2), last_name;
710                   int   i = IDENTIFIER_LENGTH (name)-1;
711                   const char *last = &IDENTIFIER_POINTER (name)[i];
712                   while (last != IDENTIFIER_POINTER (name))
713                     {
714                       if (last [0] == '.')
715                         break;
716                       last--;
717                     }
718                   last_name = get_identifier (++last);
719                   if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (last_name))
720                     {
721                       tree err = find_name_in_single_imports (last_name);
722                       if (err && err != name)
723                         parse_error_context
724                           ($2, "Ambiguous class: `%s' and `%s'",
725                            IDENTIFIER_POINTER (name), 
726                            IDENTIFIER_POINTER (err));
727                       else
728                         REGISTER_IMPORT ($2, last_name);
729                     }
730                   else
731                     REGISTER_IMPORT ($2, last_name);
732                 }
733 |       IMPORT_TK error
734                 {yyerror ("Missing name"); RECOVER;}
735 |       IMPORT_TK name error
736                 {yyerror ("';' expected"); RECOVER;}
737 ;
738
739 type_import_on_demand_declaration:
740         IMPORT_TK name DOT_TK MULT_TK SC_TK
741                 {
742                   tree name = EXPR_WFL_NODE ($2);
743                   /* Don't import java.lang.* twice. */
744                   if (name != java_lang_id)
745                     {
746                       read_import_dir ($2);
747                       ctxp->import_demand_list = 
748                         chainon (ctxp->import_demand_list,
749                                  build_tree_list ($2, NULL_TREE));
750                     }
751                 }
752 |       IMPORT_TK name DOT_TK error
753                 {yyerror ("'*' expected"); RECOVER;}
754 |       IMPORT_TK name DOT_TK MULT_TK error
755                 {yyerror ("';' expected"); RECOVER;}
756 ;
757
758 type_declaration:
759         class_declaration
760                 { end_class_declaration (0); }
761 |       interface_declaration
762                 { end_class_declaration (0); }
763 |       SC_TK
764                 { $$ = NULL; }
765 |       error
766                 {
767                   YYERROR_NOW;
768                   yyerror ("Class or interface declaration expected");
769                 }
770 ;
771
772 /* 19.7 Shortened from the original:
773    modifiers: modifier | modifiers modifier
774    modifier: any of public...  */
775 modifiers:
776         MODIFIER_TK
777                 {
778                   $$ = (1 << $1);
779                 }
780 |       modifiers MODIFIER_TK
781                 {
782                   int acc = (1 << $2);
783                   if ($$ & acc)
784                     parse_error_context 
785                       (ctxp->modifier_ctx [$2], "Modifier `%s' declared twice",
786                        java_accstring_lookup (acc));
787                   else
788                     {
789                       $$ |= acc;
790                     }
791                 }
792 ;
793
794 /* 19.8.1 Production from $8.1: Class Declaration */
795 class_declaration:
796         modifiers CLASS_TK identifier super interfaces
797                 { create_class ($1, $3, $4, $5); }
798         class_body
799 |       CLASS_TK identifier super interfaces 
800                 { create_class (0, $2, $3, $4); }
801         class_body
802 |       modifiers CLASS_TK error
803                 {yyerror ("Missing class name"); RECOVER;}
804 |       CLASS_TK error
805                 {yyerror ("Missing class name"); RECOVER;}
806 |       CLASS_TK identifier error
807                 {
808                   if (!ctxp->class_err) yyerror ("'{' expected"); 
809                   DRECOVER(class1);
810                 }
811 |       modifiers CLASS_TK identifier error
812                 {if (!ctxp->class_err) yyerror ("'{' expected"); RECOVER;}
813 ;
814
815 super:
816                 { $$ = NULL; }
817 |       EXTENDS_TK class_type
818                 { $$ = $2; }
819 |       EXTENDS_TK class_type error
820                 {yyerror ("'{' expected"); ctxp->class_err=1;}
821 |       EXTENDS_TK error
822                 {yyerror ("Missing super class name"); ctxp->class_err=1;}
823 ;
824
825 interfaces:
826                 { $$ = NULL_TREE; }
827 |       IMPLEMENTS_TK interface_type_list
828                 { $$ = $2; }
829 |       IMPLEMENTS_TK error
830                 {
831                   ctxp->class_err=1;
832                   yyerror ("Missing interface name"); 
833                 }
834 ;
835
836 interface_type_list:
837         interface_type
838                 { 
839                   ctxp->interface_number = 1;
840                   $$ = build_tree_list ($1, NULL_TREE);
841                 }
842 |       interface_type_list C_TK interface_type
843                 { 
844                   ctxp->interface_number++;
845                   $$ = chainon ($1, build_tree_list ($3, NULL_TREE));
846                 }
847 |       interface_type_list C_TK error
848                 {yyerror ("Missing interface name"); RECOVER;}
849 ;
850
851 class_body:
852         OCB_TK CCB_TK
853                 { 
854                   /* Store the location of the `}' when doing xrefs */
855                   if (flag_emit_xref)
856                     DECL_END_SOURCE_LINE (GET_CPC ()) = 
857                       EXPR_WFL_ADD_COL ($2.location, 1);
858                   $$ = GET_CPC ();
859                 }
860 |       OCB_TK class_body_declarations CCB_TK
861                 { 
862                   /* Store the location of the `}' when doing xrefs */
863                   if (flag_emit_xref)
864                     DECL_END_SOURCE_LINE (GET_CPC ()) = 
865                       EXPR_WFL_ADD_COL ($3.location, 1);
866                   $$ = GET_CPC ();
867                 }
868 ;
869
870 class_body_declarations:
871         class_body_declaration
872 |       class_body_declarations class_body_declaration
873 ;
874
875 class_body_declaration:
876         class_member_declaration
877 |       static_initializer
878 |       constructor_declaration
879 |       block                   /* Added, JDK1.1, instance initializer */
880                 {
881                   TREE_CHAIN ($1) = CPC_INSTANCE_INITIALIZER_STMT (ctxp);
882                   SET_CPC_INSTANCE_INITIALIZER_STMT (ctxp, $1);
883                 }
884 ;
885
886 class_member_declaration:
887         field_declaration
888 |       field_declaration SC_TK
889                 { $$ = $1; }
890 |       method_declaration
891 |       class_declaration       /* Added, JDK1.1 inner classes */
892                 { end_class_declaration (1); }
893 |       interface_declaration   /* Added, JDK1.1 inner interfaces */
894                 { end_class_declaration (1); }
895 ;
896
897 /* 19.8.2 Productions from 8.3: Field Declarations  */
898 field_declaration:
899         type variable_declarators SC_TK
900                 { register_fields (0, $1, $2); }
901 |       modifiers type variable_declarators SC_TK
902                 {
903                   check_modifiers 
904                     ("Illegal modifier `%s' for field declaration",
905                      $1, FIELD_MODIFIERS);
906                   check_modifiers_consistency ($1);
907                   register_fields ($1, $2, $3);
908                 }
909 ;
910
911 variable_declarators:
912         /* Should we use build_decl_list () instead ? FIXME */
913         variable_declarator     /* Default rule */
914 |       variable_declarators C_TK variable_declarator
915                 { $$ = chainon ($1, $3); }
916 |       variable_declarators C_TK error
917                 {yyerror ("Missing term"); RECOVER;}
918 ;
919
920 variable_declarator:
921         variable_declarator_id
922                 { $$ = build_tree_list ($1, NULL_TREE); }
923 |       variable_declarator_id ASSIGN_TK variable_initializer
924                 { 
925                   if (java_error_count)
926                     $3 = NULL_TREE;
927                   $$ = build_tree_list 
928                     ($1, build_assignment ($2.token, $2.location, $1, $3));
929                 }
930 |       variable_declarator_id ASSIGN_TK error
931                 {
932                   yyerror ("Missing variable initializer");
933                   $$ = build_tree_list ($1, NULL_TREE);
934                   RECOVER;
935                 }
936 |       variable_declarator_id ASSIGN_TK variable_initializer error
937                 {
938                   yyerror ("';' expected");
939                   $$ = build_tree_list ($1, NULL_TREE);
940                   RECOVER;
941                 }
942 ;
943
944 variable_declarator_id:
945         identifier
946 |       variable_declarator_id OSB_TK CSB_TK
947                 { $$ = build_unresolved_array_type ($1); }
948 |       identifier error
949                 {yyerror ("Invalid declaration"); DRECOVER(vdi);}
950 |       variable_declarator_id OSB_TK error
951                 {yyerror ("']' expected"); DRECOVER(vdi);}
952 |       variable_declarator_id CSB_TK error
953                 {yyerror ("Unbalanced ']'"); DRECOVER(vdi);}
954 ;
955
956 variable_initializer:
957         expression
958 |       array_initializer
959 ;
960
961 /* 19.8.3 Productions from 8.4: Method Declarations  */
962 method_declaration:
963         method_header 
964                 {
965                   current_function_decl = $1;
966                   if (current_function_decl
967                       && TREE_CODE (current_function_decl) == FUNCTION_DECL)
968                     source_start_java_method (current_function_decl);
969                   else
970                     current_function_decl = NULL_TREE;
971                 }
972         method_body
973                 { finish_method_declaration ($3); }
974 |       method_header error
975                 {YYNOT_TWICE yyerror ("'{' expected"); RECOVER;}
976 ;
977
978 method_header:  
979         type method_declarator throws
980                 { $$ = method_header (0, $1, $2, $3); }
981 |       VOID_TK method_declarator throws
982                 { $$ = method_header (0, void_type_node, $2, $3); }
983 |       modifiers type method_declarator throws
984                 { $$ = method_header ($1, $2, $3, $4); }
985 |       modifiers VOID_TK method_declarator throws
986                 { $$ = method_header ($1, void_type_node, $3, $4); }
987 |       type error
988                 {
989                   yyerror ("Invalid method declaration, method name required");
990                   RECOVER;
991                 }
992 |       modifiers type error
993                 {RECOVER;}
994 |       VOID_TK error
995                 {yyerror ("Identifier expected"); RECOVER;}
996 |       modifiers VOID_TK error
997                 {yyerror ("Identifier expected"); RECOVER;}
998 |       modifiers error
999                 {
1000                   yyerror ("Invalid method declaration, return type required");
1001                   RECOVER;
1002                 }
1003 ;
1004
1005 method_declarator:
1006         identifier OP_TK CP_TK
1007                 { 
1008                   ctxp->formal_parameter_number = 0;
1009                   $$ = method_declarator ($1, NULL_TREE);
1010                 }
1011 |       identifier OP_TK formal_parameter_list CP_TK
1012                 { $$ = method_declarator ($1, $3); }
1013 |       method_declarator OSB_TK CSB_TK
1014                 {
1015                   EXPR_WFL_LINECOL (wfl_operator) = $2.location;
1016                   TREE_PURPOSE ($1) = 
1017                     build_unresolved_array_type (TREE_PURPOSE ($1));
1018                   parse_warning_context 
1019                     (wfl_operator, 
1020                      "Discouraged form of returned type specification");
1021                 }
1022 |       identifier OP_TK error
1023                 {yyerror ("')' expected"); DRECOVER(method_declarator);}
1024 |       method_declarator OSB_TK error
1025                 {yyerror ("']' expected"); RECOVER;}
1026 ;
1027
1028 formal_parameter_list:
1029         formal_parameter
1030                 {
1031                   ctxp->formal_parameter_number = 1;
1032                 }
1033 |       formal_parameter_list C_TK formal_parameter
1034                 {
1035                   ctxp->formal_parameter_number += 1;
1036                   $$ = chainon ($1, $3);
1037                 }
1038 |       formal_parameter_list C_TK error
1039                 { yyerror ("Missing formal parameter term"); RECOVER; }
1040 ;
1041
1042 formal_parameter:
1043         type variable_declarator_id
1044                 {
1045                   $$ = build_tree_list ($2, $1);
1046                 }
1047 |       final type variable_declarator_id /* Added, JDK1.1 final parms */
1048                 { 
1049                   $$ = build_tree_list ($3, $2);
1050                   ARG_FINAL_P ($$) = 1;
1051                 }
1052 |       type error
1053                 {
1054                   yyerror ("Missing identifier"); RECOVER;
1055                   $$ = NULL_TREE;
1056                 }
1057 |       final type error
1058                 {
1059                   yyerror ("Missing identifier"); RECOVER;
1060                   $$ = NULL_TREE;
1061                 }
1062 ;
1063
1064 final:
1065         modifiers
1066                 {
1067                   check_modifiers ("Illegal modifier `%s'. Only `final' was expected here",
1068                                    $1, ACC_FINAL);
1069                   if ($1 != ACC_FINAL)
1070                     MODIFIER_WFL (FINAL_TK) = build_wfl_node (NULL_TREE);
1071                 }
1072 ;
1073
1074 throws:
1075                 { $$ = NULL_TREE; }
1076 |       THROWS_TK class_type_list
1077                 { $$ = $2; }
1078 |       THROWS_TK error
1079                 {yyerror ("Missing class type term"); RECOVER;}
1080 ;
1081
1082 class_type_list:
1083         class_type
1084                 { $$ = build_tree_list ($1, $1); }
1085 |       class_type_list C_TK class_type
1086                 { $$ = tree_cons ($3, $3, $1); }
1087 |       class_type_list C_TK error
1088                 {yyerror ("Missing class type term"); RECOVER;}
1089 ;
1090
1091 method_body:
1092         block
1093 |       block SC_TK
1094 |       SC_TK
1095                 { $$ = NULL_TREE; } /* Probably not the right thing to do. */
1096 ;
1097
1098 /* 19.8.4 Productions from 8.5: Static Initializers  */
1099 static_initializer:
1100         static block
1101                 {
1102                   TREE_CHAIN ($2) = CPC_STATIC_INITIALIZER_STMT (ctxp);
1103                   SET_CPC_STATIC_INITIALIZER_STMT (ctxp, $2);
1104                 }
1105 |       static block SC_TK      /* Shouldn't be here. FIXME */
1106                 {
1107                   TREE_CHAIN ($2) = CPC_STATIC_INITIALIZER_STMT (ctxp);
1108                   SET_CPC_STATIC_INITIALIZER_STMT (ctxp, $2);
1109                 }
1110 ;
1111
1112 static:                         /* Test lval.sub_token here */
1113         modifiers
1114                 {
1115                   check_modifiers ("Illegal modifier `%s' for static initializer", $1, ACC_STATIC);
1116                   /* Can't have a static initializer in an innerclass */
1117                   if ($1 | ACC_STATIC &&
1118                       GET_CPC_LIST () && !TOPLEVEL_CLASS_DECL_P (GET_CPC ()))
1119                     parse_error_context 
1120                       (MODIFIER_WFL (STATIC_TK),
1121                        "Can't define static initializer in class `%s'. Static initializer can only be defined in top-level classes",
1122                        IDENTIFIER_POINTER (DECL_NAME (GET_CPC ())));
1123                   SOURCE_FRONTEND_DEBUG (("Modifiers: %d", $1));
1124                 }
1125 ;
1126
1127 /* 19.8.5 Productions from 8.6: Constructor Declarations  */
1128 constructor_declaration:
1129         constructor_header
1130                 {
1131                   current_function_decl = $1;
1132                   source_start_java_method (current_function_decl);
1133                 }
1134         constructor_body
1135                 { finish_method_declaration ($3); }
1136 ;
1137
1138 constructor_header:
1139         constructor_declarator throws
1140                 { $$ = method_header (0, NULL_TREE, $1, $2); }
1141 |       modifiers constructor_declarator throws
1142                 { $$ = method_header ($1, NULL_TREE, $2, $3); }
1143 ;
1144
1145 constructor_declarator:
1146         simple_name OP_TK CP_TK
1147                 { 
1148                   ctxp->formal_parameter_number = 0;  
1149                   $$ = method_declarator ($1, NULL_TREE);
1150                 }
1151 |       simple_name OP_TK formal_parameter_list CP_TK
1152                 { $$ = method_declarator ($1, $3); }
1153 ;
1154
1155 constructor_body:
1156         /* Unlike regular method, we always need a complete (empty)
1157            body so we can safely perform all the required code
1158            addition (super invocation and field initialization) */
1159         block_begin constructor_block_end
1160                 { 
1161                   BLOCK_EXPR_BODY ($2) = empty_stmt_node;
1162                   $$ = $2;
1163                 }
1164 |       block_begin explicit_constructor_invocation constructor_block_end
1165                 { $$ = $3; }
1166 |       block_begin block_statements constructor_block_end
1167                 { $$ = $3; }
1168 |       block_begin explicit_constructor_invocation block_statements constructor_block_end
1169                 { $$ = $4; }
1170 ;
1171
1172 constructor_block_end:
1173         block_end
1174 |       block_end SC_TK
1175
1176 /* Error recovery for that rule moved down expression_statement: rule.  */
1177 explicit_constructor_invocation:
1178         this_or_super OP_TK CP_TK SC_TK
1179                 { 
1180                   $$ = build_method_invocation ($1, NULL_TREE); 
1181                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $$);
1182                   $$ = java_method_add_stmt (current_function_decl, $$);
1183                 }
1184 |       this_or_super OP_TK argument_list CP_TK SC_TK
1185                 { 
1186                   $$ = build_method_invocation ($1, $3); 
1187                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $$);
1188                   $$ = java_method_add_stmt (current_function_decl, $$);
1189                 }
1190         /* Added, JDK1.1 inner classes. Modified because the rule
1191            'primary' couldn't work.  */
1192 |       name DOT_TK SUPER_TK OP_TK argument_list CP_TK SC_TK
1193                 {$$ = parse_jdk1_1_error ("explicit constructor invocation"); }
1194 |       name DOT_TK SUPER_TK OP_TK CP_TK SC_TK
1195                 {$$ = parse_jdk1_1_error ("explicit constructor invocation"); }
1196 ;
1197
1198 this_or_super:                  /* Added, simplifies error diagnostics */
1199         THIS_TK
1200                 {
1201                   tree wfl = build_wfl_node (this_identifier_node);
1202                   EXPR_WFL_LINECOL (wfl) = $1.location;
1203                   $$ = wfl;
1204                 }
1205 |       SUPER_TK
1206                 {
1207                   tree wfl = build_wfl_node (super_identifier_node);
1208                   EXPR_WFL_LINECOL (wfl) = $1.location;
1209                   $$ = wfl;
1210                 }
1211 ;
1212
1213 /* 19.9 Productions from 9: Interfaces  */
1214 /* 19.9.1 Productions from 9.1: Interfaces Declarations  */
1215 interface_declaration:
1216         INTERFACE_TK identifier
1217                 { create_interface (0, $2, NULL_TREE); }
1218         interface_body
1219 |       modifiers INTERFACE_TK identifier
1220                 { create_interface ($1, $3, NULL_TREE); }
1221         interface_body
1222 |       INTERFACE_TK identifier extends_interfaces
1223                 { create_interface (0, $2, $3); }
1224         interface_body
1225 |       modifiers INTERFACE_TK identifier extends_interfaces
1226                 { create_interface ($1, $3, $4); }
1227         interface_body
1228 |       INTERFACE_TK identifier error
1229                 {yyerror ("'{' expected"); RECOVER;}
1230 |       modifiers INTERFACE_TK identifier error
1231                 {yyerror ("'{' expected"); RECOVER;}
1232 ;
1233
1234 extends_interfaces:
1235         EXTENDS_TK interface_type
1236                 { 
1237                   ctxp->interface_number = 1;
1238                   $$ = build_tree_list ($2, NULL_TREE);
1239                 }
1240 |       extends_interfaces C_TK interface_type
1241                 { 
1242                   ctxp->interface_number++;
1243                   $$ = chainon ($1, build_tree_list ($3, NULL_TREE));
1244                 }
1245 |       EXTENDS_TK error
1246                 {yyerror ("Invalid interface type"); RECOVER;}
1247 |       extends_interfaces C_TK error
1248                 {yyerror ("Missing term"); RECOVER;}
1249 ;
1250
1251 interface_body:
1252         OCB_TK CCB_TK
1253                 { $$ = NULL_TREE; }
1254 |       OCB_TK interface_member_declarations CCB_TK
1255                 { $$ = NULL_TREE; }
1256 ;
1257
1258 interface_member_declarations:
1259         interface_member_declaration
1260 |       interface_member_declarations interface_member_declaration
1261 ;
1262
1263 interface_member_declaration:
1264         constant_declaration
1265 |       abstract_method_declaration
1266 |       class_declaration       /* Added, JDK1.1 inner classes */
1267                 { end_class_declaration (1); }
1268 |       interface_declaration   /* Added, JDK1.1 inner interfaces */
1269                 { end_class_declaration (1); }
1270 ;
1271
1272 constant_declaration:
1273         field_declaration
1274 ;
1275
1276 abstract_method_declaration:
1277         method_header SC_TK
1278                 { 
1279                   check_abstract_method_header ($1);
1280                   current_function_decl = NULL_TREE; /* FIXME ? */
1281                 }
1282 |       method_header error
1283                 {yyerror ("';' expected"); RECOVER;}
1284 ;
1285
1286 /* 19.10 Productions from 10: Arrays  */
1287 array_initializer:
1288         OCB_TK CCB_TK
1289                 { $$ = build_new_array_init ($1.location, NULL_TREE); }
1290 |       OCB_TK variable_initializers CCB_TK
1291                 { $$ = build_new_array_init ($1.location, $2); }
1292 |       OCB_TK variable_initializers C_TK CCB_TK
1293                 { $$ = build_new_array_init ($1.location, $2); }
1294 ;
1295
1296 variable_initializers:
1297         variable_initializer
1298                 { 
1299                   $$ = tree_cons (maybe_build_array_element_wfl ($1), 
1300                                   $1, NULL_TREE);
1301                 }
1302 |       variable_initializers C_TK variable_initializer
1303                 {
1304                   $$ = tree_cons (maybe_build_array_element_wfl ($3), $3, $1);
1305                 }
1306 |       variable_initializers C_TK error
1307                 {yyerror ("Missing term"); RECOVER;}
1308 ;
1309
1310 /* 19.11 Production from 14: Blocks and Statements  */
1311 block:
1312         OCB_TK CCB_TK
1313                 { 
1314                   /* Store the location of the `}' when doing xrefs */
1315                   if (current_function_decl && flag_emit_xref)
1316                     DECL_END_SOURCE_LINE (current_function_decl) = 
1317                       EXPR_WFL_ADD_COL ($2.location, 1);
1318                   $$ = empty_stmt_node; 
1319                 }
1320 |       block_begin block_statements block_end
1321                 { $$ = $3; }
1322 ;
1323
1324 block_begin:
1325         OCB_TK
1326                 { enter_block (); }
1327 ;
1328
1329 block_end:
1330         CCB_TK
1331                 { 
1332                   maybe_absorb_scoping_blocks ();
1333                   /* Store the location of the `}' when doing xrefs */
1334                   if (current_function_decl && flag_emit_xref)
1335                     DECL_END_SOURCE_LINE (current_function_decl) = 
1336                       EXPR_WFL_ADD_COL ($1.location, 1);                  
1337                   $$ = exit_block ();
1338                   if (!BLOCK_SUBBLOCKS ($$))
1339                     BLOCK_SUBBLOCKS ($$) = empty_stmt_node;
1340                 }
1341 ;
1342
1343 block_statements:
1344         block_statement
1345 |       block_statements block_statement
1346 ;
1347
1348 block_statement:
1349         local_variable_declaration_statement
1350 |       statement
1351                 { java_method_add_stmt (current_function_decl, $1); }
1352 |       class_declaration       /* Added, JDK1.1 local classes */
1353                 { 
1354                   LOCAL_CLASS_P (TREE_TYPE (GET_CPC ())) = 1;
1355                   end_class_declaration (1);
1356                 }
1357 ;
1358
1359 local_variable_declaration_statement:
1360         local_variable_declaration SC_TK /* Can't catch missing ';' here */
1361 ;
1362
1363 local_variable_declaration:
1364         type variable_declarators
1365                 { declare_local_variables (0, $1, $2); }
1366 |       final type variable_declarators /* Added, JDK1.1 final locals */
1367                 { declare_local_variables ($1, $2, $3); }
1368 ;
1369
1370 statement:
1371         statement_without_trailing_substatement
1372 |       labeled_statement
1373 |       if_then_statement
1374 |       if_then_else_statement
1375 |       while_statement
1376 |       for_statement
1377                 { $$ = exit_block (); }
1378 ;
1379
1380 statement_nsi:
1381         statement_without_trailing_substatement
1382 |       labeled_statement_nsi
1383 |       if_then_else_statement_nsi
1384 |       while_statement_nsi
1385 |       for_statement_nsi
1386                 { $$ = exit_block (); }
1387 ;
1388
1389 statement_without_trailing_substatement:
1390         block
1391 |       empty_statement
1392 |       expression_statement
1393 |       switch_statement
1394 |       do_statement
1395 |       break_statement
1396 |       continue_statement
1397 |       return_statement
1398 |       synchronized_statement
1399 |       throw_statement
1400 |       try_statement
1401 ;
1402
1403 empty_statement:
1404         SC_TK
1405                 { $$ = empty_stmt_node; }
1406 ;
1407
1408 label_decl:
1409         identifier REL_CL_TK
1410                 {
1411                   $$ = build_labeled_block (EXPR_WFL_LINECOL ($1), 
1412                                             EXPR_WFL_NODE ($1));
1413                   pushlevel (2);
1414                   push_labeled_block ($$);
1415                   PUSH_LABELED_BLOCK ($$);
1416                 }
1417 ;
1418
1419 labeled_statement:
1420         label_decl statement
1421                 { $$ = finish_labeled_statement ($1, $2); }
1422 |       identifier error
1423                 {yyerror ("':' expected"); RECOVER;}
1424 ;
1425
1426 labeled_statement_nsi:
1427         label_decl statement_nsi
1428                 { $$ = finish_labeled_statement ($1, $2); }
1429 ;
1430
1431 /* We concentrate here a bunch of error handling rules that we couldn't write
1432    earlier, because expression_statement catches a missing ';'.  */
1433 expression_statement:
1434         statement_expression SC_TK
1435                 {
1436                   /* We have a statement. Generate a WFL around it so
1437                      we can debug it */
1438                   $$ = build_expr_wfl ($1, input_filename, lineno, 0);
1439                   /* We know we have a statement, so set the debug
1440                      info to be eventually generate here. */
1441                   $$ = JAVA_MAYBE_GENERATE_DEBUG_INFO ($$);
1442                 }
1443 |       error SC_TK 
1444                 {
1445                   if (ctxp->prevent_ese != lineno)
1446                     yyerror ("Invalid expression statement");
1447                   DRECOVER (expr_stmt);
1448                 }
1449 |       error OCB_TK
1450                 {
1451                   if (ctxp->prevent_ese != lineno)
1452                     yyerror ("Invalid expression statement");
1453                   DRECOVER (expr_stmt);
1454                 }
1455 |       error CCB_TK
1456                 {
1457                   if (ctxp->prevent_ese != lineno)
1458                     yyerror ("Invalid expression statement");
1459                   DRECOVER (expr_stmt);
1460                 }
1461 |       this_or_super OP_TK error
1462                 {yyerror ("')' expected"); RECOVER;}
1463 |       this_or_super OP_TK CP_TK error
1464                 {
1465                   parse_ctor_invocation_error ();
1466                   RECOVER;
1467                 }
1468 |       this_or_super OP_TK argument_list error
1469                 {yyerror ("')' expected"); RECOVER;}
1470 |       this_or_super OP_TK argument_list CP_TK error
1471                 {
1472                   parse_ctor_invocation_error ();
1473                   RECOVER;
1474                 }
1475 |       name DOT_TK SUPER_TK error
1476                 {yyerror ("'(' expected"); RECOVER;}
1477 |       name DOT_TK SUPER_TK OP_TK error
1478                 {yyerror ("')' expected"); RECOVER;}
1479 |       name DOT_TK SUPER_TK OP_TK argument_list error
1480                 {yyerror ("')' expected"); RECOVER;}
1481 |       name DOT_TK SUPER_TK OP_TK argument_list CP_TK error
1482                 {yyerror ("';' expected"); RECOVER;}
1483 |       name DOT_TK SUPER_TK OP_TK CP_TK error
1484                 {yyerror ("';' expected"); RECOVER;}
1485 ;
1486
1487 statement_expression: 
1488         assignment
1489 |       pre_increment_expression
1490 |       pre_decrement_expression
1491 |       post_increment_expression
1492 |       post_decrement_expression
1493 |       method_invocation
1494 |       class_instance_creation_expression
1495 ;
1496
1497 if_then_statement:
1498         IF_TK OP_TK expression CP_TK statement
1499                 { 
1500                   $$ = build_if_else_statement ($2.location, $3, 
1501                                                 $5, NULL_TREE);
1502                 }
1503 |       IF_TK error
1504                 {yyerror ("'(' expected"); RECOVER;}
1505 |       IF_TK OP_TK error
1506                 {yyerror ("Missing term"); RECOVER;}
1507 |       IF_TK OP_TK expression error
1508                 {yyerror ("')' expected"); RECOVER;}
1509 ;
1510
1511 if_then_else_statement:
1512         IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement
1513                 { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
1514 ;
1515
1516 if_then_else_statement_nsi:
1517         IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement_nsi
1518                 { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
1519 ;
1520
1521 switch_statement:
1522         switch_expression
1523                 {
1524                   enter_block ();
1525                 }
1526         switch_block
1527                 { 
1528                   /* Make into "proper list" of COMPOUND_EXPRs.
1529                      I.e. make the last statment also have its own
1530                      COMPOUND_EXPR. */
1531                   maybe_absorb_scoping_blocks ();
1532                   TREE_OPERAND ($1, 1) = exit_block ();
1533                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $1);
1534                 }
1535 ;
1536
1537 switch_expression:
1538         SWITCH_TK OP_TK expression CP_TK
1539                 { 
1540                   $$ = build (SWITCH_EXPR, NULL_TREE, $3, NULL_TREE);
1541                   EXPR_WFL_LINECOL ($$) = $2.location;
1542                 }
1543 |       SWITCH_TK error
1544                 {yyerror ("'(' expected"); RECOVER;}
1545 |       SWITCH_TK OP_TK error
1546                 {yyerror ("Missing term or ')'"); DRECOVER(switch_statement);}
1547 |       SWITCH_TK OP_TK expression CP_TK error
1548                 {yyerror ("'{' expected"); RECOVER;}
1549 ;
1550
1551 /* Default assignment is there to avoid type node on switch_block
1552    node. */
1553
1554 switch_block:
1555         OCB_TK CCB_TK
1556                 { $$ = NULL_TREE; }
1557 |       OCB_TK switch_labels CCB_TK
1558                 { $$ = NULL_TREE; }
1559 |       OCB_TK switch_block_statement_groups CCB_TK
1560                 { $$ = NULL_TREE; }
1561 |       OCB_TK switch_block_statement_groups switch_labels CCB_TK
1562                 { $$ = NULL_TREE; }
1563 ;
1564
1565 switch_block_statement_groups: 
1566         switch_block_statement_group
1567 |       switch_block_statement_groups switch_block_statement_group
1568 ;
1569
1570 switch_block_statement_group:
1571         switch_labels block_statements
1572 ;
1573
1574 switch_labels:
1575         switch_label
1576 |       switch_labels switch_label
1577 ;
1578
1579 switch_label:
1580         CASE_TK constant_expression REL_CL_TK
1581                 { 
1582                   tree lab = build1 (CASE_EXPR, NULL_TREE, $2);
1583                   EXPR_WFL_LINECOL (lab) = $1.location;
1584                   java_method_add_stmt (current_function_decl, lab);
1585                 }
1586 |       DEFAULT_TK REL_CL_TK
1587                 { 
1588                   tree lab = build1 (DEFAULT_EXPR, NULL_TREE, NULL_TREE);
1589                   EXPR_WFL_LINECOL (lab) = $1.location;
1590                   java_method_add_stmt (current_function_decl, lab);
1591                 }
1592 |       CASE_TK error
1593                 {yyerror ("Missing or invalid constant expression"); RECOVER;}
1594 |       CASE_TK constant_expression error
1595                 {yyerror ("':' expected"); RECOVER;}
1596 |       DEFAULT_TK error
1597                 {yyerror ("':' expected"); RECOVER;}
1598 ;
1599
1600 while_expression:
1601         WHILE_TK OP_TK expression CP_TK
1602                 { 
1603                   tree body = build_loop_body ($2.location, $3, 0);
1604                   $$ = build_new_loop (body);
1605                 }
1606 ;
1607
1608 while_statement:
1609         while_expression statement
1610                 { $$ = finish_loop_body (0, NULL_TREE, $2, 0); }
1611 |       WHILE_TK error
1612                 {YYERROR_NOW; yyerror ("'(' expected"); RECOVER;}
1613 |       WHILE_TK OP_TK error
1614                 {yyerror ("Missing term and ')' expected"); RECOVER;}
1615 |       WHILE_TK OP_TK expression error
1616                 {yyerror ("')' expected"); RECOVER;}
1617 ;
1618
1619 while_statement_nsi:
1620         while_expression statement_nsi
1621                 { $$ = finish_loop_body (0, NULL_TREE, $2, 0); }
1622 ;
1623
1624 do_statement_begin:
1625         DO_TK
1626                 { 
1627                   tree body = build_loop_body (0, NULL_TREE, 1);
1628                   $$ = build_new_loop (body);
1629                 }
1630         /* Need error handing here. FIXME */
1631 ;
1632
1633 do_statement: 
1634         do_statement_begin statement WHILE_TK OP_TK expression CP_TK SC_TK
1635                 { $$ = finish_loop_body ($4.location, $5, $2, 1); }
1636 ;
1637
1638 for_statement:
1639         for_begin SC_TK expression SC_TK for_update CP_TK statement
1640                 {
1641                   if (TREE_CODE_CLASS (TREE_CODE ($3)) == 'c')
1642                     $3 = build_wfl_node ($3);
1643                   $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7);
1644                 }
1645 |       for_begin SC_TK SC_TK for_update CP_TK statement
1646                 { 
1647                   $$ = finish_for_loop (0, NULL_TREE, $4, $6);
1648                   /* We have not condition, so we get rid of the EXIT_EXPR */
1649                   LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) = 
1650                     empty_stmt_node;
1651                 }
1652 |       for_begin SC_TK error
1653                 {yyerror ("Invalid control expression"); RECOVER;}
1654 |       for_begin SC_TK expression SC_TK error
1655                 {yyerror ("Invalid update expression"); RECOVER;}
1656 |       for_begin SC_TK SC_TK error
1657                 {yyerror ("Invalid update expression"); RECOVER;}
1658 ;
1659
1660 for_statement_nsi:
1661         for_begin SC_TK expression SC_TK for_update CP_TK statement_nsi
1662                 { $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7);}
1663 |       for_begin SC_TK SC_TK for_update CP_TK statement_nsi
1664                 { 
1665                   $$ = finish_for_loop (0, NULL_TREE, $4, $6);
1666                   /* We have not condition, so we get rid of the EXIT_EXPR */
1667                   LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) = 
1668                     empty_stmt_node;
1669                 }
1670 ;
1671
1672 for_header:
1673         FOR_TK OP_TK
1674                 { 
1675                   /* This scope defined for local variable that may be
1676                      defined within the scope of the for loop */
1677                   enter_block (); 
1678                 }
1679 |       FOR_TK error
1680                 {yyerror ("'(' expected"); DRECOVER(for_1);}
1681 |       FOR_TK OP_TK error
1682                 {yyerror ("Invalid init statement"); RECOVER;}
1683 ;
1684
1685 for_begin:
1686         for_header for_init
1687                 { 
1688                   /* We now declare the loop body. The loop is
1689                      declared as a for loop. */
1690                   tree body = build_loop_body (0, NULL_TREE, 0);
1691                   $$ =  build_new_loop (body);
1692                   FOR_LOOP_P ($$) = 1;
1693                   /* The loop is added to the current block the for
1694                      statement is defined within */
1695                   java_method_add_stmt (current_function_decl, $$);
1696                 }
1697 ;
1698 for_init:                       /* Can be empty */
1699                 { $$ = empty_stmt_node; }
1700 |       statement_expression_list
1701                 { 
1702                   /* Init statement recorded within the previously
1703                      defined block scope */
1704                   $$ = java_method_add_stmt (current_function_decl, $1);
1705                 }
1706 |       local_variable_declaration
1707                 { 
1708                   /* Local variable are recorded within the previously
1709                      defined block scope */
1710                   $$ = NULL_TREE;
1711                 }
1712 |       statement_expression_list error
1713                 {yyerror ("';' expected"); DRECOVER(for_init_1);}
1714 ;
1715
1716 for_update:                     /* Can be empty */
1717                 {$$ = empty_stmt_node;}
1718 |       statement_expression_list
1719                 { $$ = build_debugable_stmt (BUILD_LOCATION (), $1); }
1720 ;
1721
1722 statement_expression_list:
1723         statement_expression
1724                 { $$ = add_stmt_to_compound (NULL_TREE, NULL_TREE, $1); }
1725 |       statement_expression_list C_TK statement_expression
1726                 { $$ = add_stmt_to_compound ($1, NULL_TREE, $3); }
1727 |       statement_expression_list C_TK error
1728                 {yyerror ("Missing term"); RECOVER;}
1729 ;
1730
1731 break_statement:
1732         BREAK_TK SC_TK
1733                 { $$ = build_bc_statement ($1.location, 1, NULL_TREE); }
1734 |       BREAK_TK identifier SC_TK
1735                 { $$ = build_bc_statement ($1.location, 1, $2); }
1736 |       BREAK_TK error
1737                 {yyerror ("Missing term"); RECOVER;}
1738 |       BREAK_TK identifier error
1739                 {yyerror ("';' expected"); RECOVER;}
1740 ;
1741
1742 continue_statement:
1743         CONTINUE_TK SC_TK
1744                 { $$ = build_bc_statement ($1.location, 0, NULL_TREE); }
1745 |       CONTINUE_TK identifier SC_TK
1746                 { $$ = build_bc_statement ($1.location, 0, $2); }
1747 |       CONTINUE_TK error
1748                 {yyerror ("Missing term"); RECOVER;}
1749 |       CONTINUE_TK identifier error
1750                 {yyerror ("';' expected"); RECOVER;}
1751 ;
1752
1753 return_statement:
1754         RETURN_TK SC_TK
1755                 { $$ = build_return ($1.location, NULL_TREE); }
1756 |       RETURN_TK expression SC_TK
1757                 { $$ = build_return ($1.location, $2); }
1758 |       RETURN_TK error
1759                 {yyerror ("Missing term"); RECOVER;}
1760 |       RETURN_TK expression error
1761                 {yyerror ("';' expected"); RECOVER;}
1762 ;
1763
1764 throw_statement:
1765         THROW_TK expression SC_TK
1766                 { 
1767                   $$ = build1 (THROW_EXPR, NULL_TREE, $2);
1768                   EXPR_WFL_LINECOL ($$) = $1.location;
1769                 }
1770 |       THROW_TK error
1771                 {yyerror ("Missing term"); RECOVER;}
1772 |       THROW_TK expression error
1773                 {yyerror ("';' expected"); RECOVER;}
1774 ;
1775
1776 synchronized_statement:
1777         synchronized OP_TK expression CP_TK block
1778                 { 
1779                   $$ = build (SYNCHRONIZED_EXPR, NULL_TREE, $3, $5);
1780                   EXPR_WFL_LINECOL ($$) = 
1781                     EXPR_WFL_LINECOL (MODIFIER_WFL (SYNCHRONIZED_TK));
1782                 }
1783 |       synchronized OP_TK expression CP_TK error
1784                 {yyerror ("'{' expected"); RECOVER;}
1785 |       synchronized error
1786                 {yyerror ("'(' expected"); RECOVER;}
1787 |       synchronized OP_TK error CP_TK
1788                 {yyerror ("Missing term"); RECOVER;}
1789 |       synchronized OP_TK error
1790                 {yyerror ("Missing term"); RECOVER;}
1791 ;
1792
1793 synchronized:
1794         modifiers
1795                 {
1796                   check_modifiers (
1797              "Illegal modifier `%s'. Only `synchronized' was expected here",
1798                                    $1, ACC_SYNCHRONIZED);
1799                   if ($1 != ACC_SYNCHRONIZED)
1800                     MODIFIER_WFL (SYNCHRONIZED_TK) = 
1801                       build_wfl_node (NULL_TREE);
1802                 }
1803 ;
1804
1805 try_statement:
1806         TRY_TK block catches
1807                 { $$ = build_try_statement ($1.location, $2, $3); }
1808 |       TRY_TK block finally
1809                 { $$ = build_try_finally_statement ($1.location, $2, $3); }
1810 |       TRY_TK block catches finally
1811                 { $$ = build_try_finally_statement 
1812                     ($1.location, build_try_statement ($1.location,
1813                                                        $2, $3), $4);
1814                 }
1815 |       TRY_TK error
1816                 {yyerror ("'{' expected"); DRECOVER (try_statement);}
1817 ;
1818
1819 catches:
1820         catch_clause
1821 |       catches catch_clause
1822                 { 
1823                   TREE_CHAIN ($2) = $1;
1824                   $$ = $2;
1825                 }
1826 ;
1827
1828 catch_clause:
1829         catch_clause_parameter block
1830                 { 
1831                   java_method_add_stmt (current_function_decl, $2);
1832                   exit_block ();
1833                   $$ = $1;
1834                 }
1835
1836 catch_clause_parameter:
1837         CATCH_TK OP_TK formal_parameter CP_TK
1838                 { 
1839                   /* We add a block to define a scope for
1840                      formal_parameter (CCBP). The formal parameter is
1841                      declared initialized by the appropriate function
1842                      call */
1843                   tree ccpb = enter_block ();
1844                   tree init = build_assignment (ASSIGN_TK, $2.location, 
1845                                                 TREE_PURPOSE ($3), 
1846                                                 soft_exceptioninfo_call_node);
1847                   declare_local_variables (0, TREE_VALUE ($3),
1848                                            build_tree_list (TREE_PURPOSE ($3),
1849                                                             init));
1850                   $$ = build1 (CATCH_EXPR, NULL_TREE, ccpb);
1851                   EXPR_WFL_LINECOL ($$) = $1.location;
1852                 }
1853 |       CATCH_TK error
1854                 {yyerror ("'(' expected"); RECOVER; $$ = NULL_TREE;}
1855 |       CATCH_TK OP_TK error 
1856                 {
1857                   yyerror ("Missing term or ')' expected"); 
1858                   RECOVER; $$ = NULL_TREE;
1859                 }
1860 |       CATCH_TK OP_TK error CP_TK /* That's for () */
1861                 {yyerror ("Missing term"); RECOVER; $$ = NULL_TREE;}
1862 ;
1863
1864 finally:
1865         FINALLY_TK block
1866                 { $$ = $2; }
1867 |       FINALLY_TK error
1868                 {yyerror ("'{' expected"); RECOVER; }
1869 ;
1870
1871 /* 19.12 Production from 15: Expressions  */
1872 primary:
1873         primary_no_new_array
1874 |       array_creation_expression
1875 ;
1876
1877 primary_no_new_array:
1878         literal
1879 |       THIS_TK
1880                 { $$ = build_this ($1.location); }
1881 |       OP_TK expression CP_TK
1882                 {$$ = $2;}
1883 |       class_instance_creation_expression
1884 |       field_access
1885 |       method_invocation
1886 |       array_access
1887 |       type_literals
1888         /* Added, JDK1.1 inner classes. Documentation is wrong
1889            refering to a 'ClassName' (class_name) rule that doesn't
1890            exist. Used name: instead.  */
1891 |       name DOT_TK THIS_TK
1892                 { 
1893                   tree wfl = build_wfl_node (this_identifier_node);
1894                   $$ = make_qualified_primary ($1, wfl, EXPR_WFL_LINECOL ($1));
1895                 }
1896 |       OP_TK expression error 
1897                 {yyerror ("')' expected"); RECOVER;}
1898 |       name DOT_TK error
1899                 {yyerror ("'class' or 'this' expected" ); RECOVER;}
1900 |       primitive_type DOT_TK error
1901                 {yyerror ("'class' expected" ); RECOVER;}
1902 |       VOID_TK DOT_TK error
1903                 {yyerror ("'class' expected" ); RECOVER;}
1904 ;
1905
1906 /* Added, JDK1.1 type literals. We can't use `type' directly, so we
1907    broke the rule down a bit. */
1908
1909 array_type_literal:
1910         primitive_type OSB_TK CSB_TK
1911                 { 
1912                   $$ = build_java_array_type ($1, -1);
1913                   CLASS_LOADED_P ($$) = 1;
1914                 }
1915 |       name OSB_TK CSB_TK
1916                 { $$ = build_unresolved_array_type ($1); }
1917 /* This triggers two reduce/reduce conflict between array_type_literal and
1918    dims. FIXME.
1919 |       array_type OSB_TK CSB_TK
1920                 { $$ = build_unresolved_array_type ($1); }
1921 */
1922 ;
1923
1924 type_literals:
1925         name DOT_TK CLASS_TK
1926                 { $$ = build_incomplete_class_ref ($2.location, $1); }
1927 |       array_type_literal DOT_TK CLASS_TK
1928                 { $$ = build_incomplete_class_ref ($2.location, $1); }
1929 |       primitive_type DOT_TK CLASS_TK
1930                 { $$ = build_class_ref ($1); }
1931 |       VOID_TK DOT_TK CLASS_TK
1932                 { $$ = build_class_ref (void_type_node); }
1933 ;
1934
1935 class_instance_creation_expression:
1936         NEW_TK class_type OP_TK argument_list CP_TK
1937                 { $$ = build_new_invocation ($2, $4); }
1938 |       NEW_TK class_type OP_TK CP_TK
1939                 { $$ = build_new_invocation ($2, NULL_TREE); }
1940 |       anonymous_class_creation
1941         /* Added, JDK1.1 inner classes, modified to use name or
1942            primary instead of primary solely which couldn't work in
1943            all situations.  */
1944 |       something_dot_new identifier OP_TK CP_TK
1945                 { 
1946                   tree ctor = build_new_invocation ($2, NULL_TREE);
1947                   $$ = make_qualified_primary ($1, ctor, 
1948                                                EXPR_WFL_LINECOL ($1));
1949                 }
1950 |       something_dot_new identifier OP_TK CP_TK class_body
1951 |       something_dot_new identifier OP_TK argument_list CP_TK
1952                 { 
1953                   tree ctor = build_new_invocation ($2, $4);
1954                   $$ = make_qualified_primary ($1, ctor, 
1955                                                EXPR_WFL_LINECOL ($1));
1956                 }
1957 |       something_dot_new identifier OP_TK argument_list CP_TK class_body
1958 |       NEW_TK error SC_TK 
1959                 {yyerror ("'(' expected"); DRECOVER(new_1);}
1960 |       NEW_TK class_type error
1961                 {yyerror ("'(' expected"); RECOVER;}
1962 |       NEW_TK class_type OP_TK error
1963                 {yyerror ("')' or term expected"); RECOVER;}
1964 |       NEW_TK class_type OP_TK argument_list error
1965                 {yyerror ("')' expected"); RECOVER;}
1966 |       something_dot_new error
1967                 {YYERROR_NOW; yyerror ("Identifier expected"); RECOVER;}
1968 |       something_dot_new identifier error
1969                 {yyerror ("'(' expected"); RECOVER;}
1970 ;
1971
1972 /* Created after JDK1.1 rules originally added to
1973    class_instance_creation_expression, but modified to use
1974    'class_type' instead of 'TypeName' (type_name) which is mentionned
1975    in the documentation but doesn't exist. */
1976
1977 anonymous_class_creation:
1978         NEW_TK class_type OP_TK argument_list CP_TK 
1979                 { create_anonymous_class ($1.location, $2); }
1980         class_body
1981                 { 
1982                   tree id = build_wfl_node (DECL_NAME (GET_CPC ()));
1983                   EXPR_WFL_LINECOL (id) = EXPR_WFL_LINECOL ($2);
1984
1985                   end_class_declaration (1);
1986
1987                   /* Now we can craft the new expression */
1988                   $$ = build_new_invocation (id, $4);
1989
1990                   /* Note that we can't possibly be here if
1991                      `class_type' is an interface (in which case the
1992                      anonymous class extends Object and implements
1993                      `class_type', hence its constructor can't have
1994                      arguments.) */
1995
1996                   /* Otherwise, the innerclass must feature a
1997                      constructor matching `argument_list'. Anonymous
1998                      classes are a bit special: it's impossible to
1999                      define constructor for them, hence constructors
2000                      must be generated following the hints provided by
2001                      the `new' expression. Whether a super constructor
2002                      of that nature exists or not is to be verified
2003                      later on in verify_constructor_super. 
2004
2005                      It's during the expansion of a `new' statement
2006                      refering to an anonymous class that a ctor will
2007                      be generated for the anonymous class, with the
2008                      right arguments. */
2009
2010                 }
2011 |       NEW_TK class_type OP_TK CP_TK 
2012                 { create_anonymous_class ($1.location, $2); }
2013         class_body         
2014                 { 
2015                   tree id = build_wfl_node (DECL_NAME (GET_CPC ()));
2016                   EXPR_WFL_LINECOL (id) = EXPR_WFL_LINECOL ($2);
2017
2018                   end_class_declaration (1);
2019
2020                   /* Now we can craft the new expression. The
2021                      statement doesn't need to be remember so that a
2022                      constructor can be generated, since its signature
2023                      is already known. */
2024                   $$ = build_new_invocation (id, NULL_TREE);
2025                 }
2026 ;
2027
2028 something_dot_new:              /* Added, not part of the specs. */
2029         name DOT_TK NEW_TK
2030                 { $$ = $1; }
2031 |       primary DOT_TK NEW_TK
2032                 { $$ = $1; }
2033 ;
2034
2035 argument_list:
2036         expression
2037                 { 
2038                   $$ = tree_cons (NULL_TREE, $1, NULL_TREE);
2039                   ctxp->formal_parameter_number = 1; 
2040                 }
2041 |       argument_list C_TK expression
2042                 {
2043                   ctxp->formal_parameter_number += 1;
2044                   $$ = tree_cons (NULL_TREE, $3, $1);
2045                 }
2046 |       argument_list C_TK error
2047                 {yyerror ("Missing term"); RECOVER;}
2048 ;
2049
2050 array_creation_expression:
2051         NEW_TK primitive_type dim_exprs
2052                 { $$ = build_newarray_node ($2, $3, 0); }
2053 |       NEW_TK class_or_interface_type dim_exprs
2054                 { $$ = build_newarray_node ($2, $3, 0); }
2055 |       NEW_TK primitive_type dim_exprs dims
2056                 { $$ = build_newarray_node ($2, $3, CURRENT_OSB (ctxp));}
2057 |       NEW_TK class_or_interface_type dim_exprs dims
2058                 { $$ = build_newarray_node ($2, $3, CURRENT_OSB (ctxp));}
2059         /* Added, JDK1.1 anonymous array. Initial documentation rule
2060            modified */
2061 |       NEW_TK class_or_interface_type dims array_initializer
2062                 {
2063                   char *sig;
2064                   while (CURRENT_OSB (ctxp)--)
2065                     obstack_1grow (&temporary_obstack, '[');
2066                   sig = obstack_finish (&temporary_obstack);
2067                   $$ = build (NEW_ANONYMOUS_ARRAY_EXPR, NULL_TREE,
2068                               $2, get_identifier (sig), $4);
2069                 }
2070 |       NEW_TK primitive_type dims array_initializer
2071                 { 
2072                   tree type = $2;
2073                   while (CURRENT_OSB (ctxp)--)
2074                     type = build_java_array_type (type, -1);
2075                   $$ = build (NEW_ANONYMOUS_ARRAY_EXPR, NULL_TREE, 
2076                               build_pointer_type (type), NULL_TREE, $4);
2077                 }
2078 |       NEW_TK error CSB_TK
2079                 {yyerror ("'[' expected"); DRECOVER ("]");}
2080 |       NEW_TK error OSB_TK
2081                 {yyerror ("']' expected"); RECOVER;}
2082 ;
2083
2084 dim_exprs:
2085         dim_expr
2086                 { $$ = build_tree_list (NULL_TREE, $1); }
2087 |       dim_exprs dim_expr
2088                 { $$ = tree_cons (NULL_TREE, $2, $$); }
2089 ;
2090
2091 dim_expr:
2092         OSB_TK expression CSB_TK
2093                 { 
2094                   if (JNUMERIC_TYPE_P (TREE_TYPE ($2)))
2095                     {
2096                       $2 = build_wfl_node ($2);
2097                       TREE_TYPE ($2) = NULL_TREE;
2098                     }
2099                   EXPR_WFL_LINECOL ($2) = $1.location;
2100                   $$ = $2;
2101                 }
2102 |       OSB_TK expression error
2103                 {yyerror ("']' expected"); RECOVER;}
2104 |       OSB_TK error
2105                 {
2106                   yyerror ("Missing term");
2107                   yyerror ("']' expected");
2108                   RECOVER;
2109                 }
2110 ;
2111
2112 dims:                           
2113         OSB_TK CSB_TK
2114                 { 
2115                   int allocate = 0;
2116                   /* If not initialized, allocate memory for the osb
2117                      numbers stack */
2118                   if (!ctxp->osb_limit)
2119                     {
2120                       allocate = ctxp->osb_limit = 32;
2121                       ctxp->osb_depth = -1;
2122                     }
2123                   /* If capacity overflown, reallocate a bigger chunk */
2124                   else if (ctxp->osb_depth+1 == ctxp->osb_limit)
2125                     allocate = ctxp->osb_limit << 1;
2126                   
2127                   if (allocate)
2128                     {
2129                       allocate *= sizeof (int);
2130                       if (ctxp->osb_number)
2131                         ctxp->osb_number = (int *)xrealloc (ctxp->osb_number,
2132                                                             allocate);
2133                       else
2134                         ctxp->osb_number = (int *)xmalloc (allocate);
2135                     }
2136                   ctxp->osb_depth++;
2137                   CURRENT_OSB (ctxp) = 1;
2138                 }
2139 |       dims OSB_TK CSB_TK
2140                 { CURRENT_OSB (ctxp)++; }
2141 |       dims OSB_TK error
2142                 { yyerror ("']' expected"); RECOVER;}
2143 ;
2144
2145 field_access:
2146         primary DOT_TK identifier
2147                 { $$ = make_qualified_primary ($1, $3, $2.location); }
2148                 /*  FIXME - REWRITE TO: 
2149                 { $$ = build_binop (COMPONENT_REF, $2.location, $1, $3); } */
2150 |       SUPER_TK DOT_TK identifier
2151                 {
2152                   tree super_wfl = 
2153                     build_wfl_node (super_identifier_node);
2154                   EXPR_WFL_LINECOL (super_wfl) = $1.location;
2155                   $$ = make_qualified_name (super_wfl, $3, $2.location);
2156                 }
2157 |       SUPER_TK error
2158                 {yyerror ("Field expected"); DRECOVER (super_field_acces);}
2159 ;
2160
2161 method_invocation:
2162         name OP_TK CP_TK
2163                 { $$ = build_method_invocation ($1, NULL_TREE); }
2164 |       name OP_TK argument_list CP_TK
2165                 { $$ = build_method_invocation ($1, $3); }
2166 |       primary DOT_TK identifier OP_TK CP_TK
2167                 { 
2168                   if (TREE_CODE ($1) == THIS_EXPR)
2169                     $$ = build_this_super_qualified_invocation 
2170                       (1, $3, NULL_TREE, 0, $2.location);
2171                   else
2172                     {
2173                       tree invok = build_method_invocation ($3, NULL_TREE);
2174                       $$ = make_qualified_primary ($1, invok, $2.location);
2175                     }
2176                 }
2177 |       primary DOT_TK identifier OP_TK argument_list CP_TK
2178                 { 
2179                   if (TREE_CODE ($1) == THIS_EXPR)
2180                     $$ = build_this_super_qualified_invocation 
2181                       (1, $3, $5, 0, $2.location);
2182                   else
2183                     {
2184                       tree invok = build_method_invocation ($3, $5);
2185                       $$ = make_qualified_primary ($1, invok, $2.location);
2186                     }
2187                 }
2188 |       SUPER_TK DOT_TK identifier OP_TK CP_TK
2189                 { 
2190                   $$ = build_this_super_qualified_invocation 
2191                     (0, $3, NULL_TREE, $1.location, $2.location);
2192                 }
2193 |       SUPER_TK DOT_TK identifier OP_TK argument_list CP_TK
2194                 {
2195                   $$ = build_this_super_qualified_invocation 
2196                     (0, $3, $5, $1.location, $2.location);
2197                 }
2198         /* Screws up thing. I let it here until I'm convinced it can
2199            be removed. FIXME
2200 |       primary DOT_TK error
2201                 {yyerror ("'(' expected"); DRECOVER(bad);} */
2202 |       SUPER_TK DOT_TK error CP_TK
2203                 { yyerror ("'(' expected"); DRECOVER (method_invocation); }
2204 |       SUPER_TK DOT_TK error DOT_TK
2205                 { yyerror ("'(' expected"); DRECOVER (method_invocation); }
2206 ;
2207
2208 array_access:
2209         name OSB_TK expression CSB_TK
2210                 { $$ = build_array_ref ($2.location, $1, $3); }
2211 |       primary_no_new_array OSB_TK expression CSB_TK
2212                 { $$ = build_array_ref ($2.location, $1, $3); }
2213 |       name OSB_TK error
2214                 {
2215                   yyerror ("Missing term and ']' expected");
2216                   DRECOVER(array_access);
2217                 }
2218 |       name OSB_TK expression error
2219                 {
2220                   yyerror ("']' expected");
2221                   DRECOVER(array_access);
2222                 }
2223 |       primary_no_new_array OSB_TK error
2224                 {
2225                   yyerror ("Missing term and ']' expected");
2226                   DRECOVER(array_access);
2227                 }
2228 |       primary_no_new_array OSB_TK expression error
2229                 {
2230                   yyerror ("']' expected");
2231                   DRECOVER(array_access);
2232                 }
2233 ;
2234
2235 postfix_expression:
2236         primary
2237 |       name
2238 |       post_increment_expression
2239 |       post_decrement_expression
2240 ;
2241
2242 post_increment_expression:
2243         postfix_expression INCR_TK
2244                 { $$ = build_incdec ($2.token, $2.location, $1, 1); }
2245 ;
2246
2247 post_decrement_expression:
2248         postfix_expression DECR_TK
2249                 { $$ = build_incdec ($2.token, $2.location, $1, 1); }
2250 ;
2251
2252 unary_expression:
2253         pre_increment_expression
2254 |       pre_decrement_expression
2255 |       PLUS_TK unary_expression
2256                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2257 |       MINUS_TK unary_expression
2258                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2259 |       unary_expression_not_plus_minus
2260 |       PLUS_TK error
2261                 {yyerror ("Missing term"); RECOVER}
2262 |       MINUS_TK error
2263                 {yyerror ("Missing term"); RECOVER}
2264 ;
2265
2266 pre_increment_expression:
2267         INCR_TK unary_expression
2268                 {$$ = build_incdec ($1.token, $1.location, $2, 0); }
2269 |       INCR_TK error
2270                 {yyerror ("Missing term"); RECOVER}
2271 ;
2272
2273 pre_decrement_expression:
2274         DECR_TK unary_expression
2275                 {$$ = build_incdec ($1.token, $1.location, $2, 0); }
2276 |       DECR_TK error
2277                 {yyerror ("Missing term"); RECOVER}
2278 ;
2279
2280 unary_expression_not_plus_minus:
2281         postfix_expression
2282 |       NOT_TK unary_expression
2283                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2284 |       NEG_TK unary_expression
2285                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2286 |       cast_expression
2287 |       NOT_TK error
2288                 {yyerror ("Missing term"); RECOVER}
2289 |       NEG_TK error
2290                 {yyerror ("Missing term"); RECOVER}
2291 ;
2292
2293 cast_expression:                /* Error handling here is potentially weak */
2294         OP_TK primitive_type dims CP_TK unary_expression
2295                 { 
2296                   tree type = $2;
2297                   while (CURRENT_OSB (ctxp)--)
2298                     type = build_java_array_type (type, -1);
2299                   ctxp->osb_depth--;
2300                   $$ = build_cast ($1.location, type, $5); 
2301                 }
2302 |       OP_TK primitive_type CP_TK unary_expression
2303                 { $$ = build_cast ($1.location, $2, $4); }
2304 |       OP_TK expression CP_TK unary_expression_not_plus_minus
2305                 { $$ = build_cast ($1.location, $2, $4); }
2306 |       OP_TK name dims CP_TK unary_expression_not_plus_minus
2307                 { 
2308                   const char *ptr;
2309                   while (CURRENT_OSB (ctxp)--)
2310                     obstack_1grow (&temporary_obstack, '[');
2311                   ctxp->osb_depth--;
2312                   obstack_grow0 (&temporary_obstack, 
2313                                  IDENTIFIER_POINTER (EXPR_WFL_NODE ($2)),
2314                                  IDENTIFIER_LENGTH (EXPR_WFL_NODE ($2)));
2315                   ptr = obstack_finish (&temporary_obstack);
2316                   EXPR_WFL_NODE ($2) = get_identifier (ptr);
2317                   $$ = build_cast ($1.location, $2, $5);
2318                 }
2319 |       OP_TK primitive_type OSB_TK error
2320                 {yyerror ("']' expected, invalid type expression");}
2321 |       OP_TK error
2322                 {
2323                   if (ctxp->prevent_ese != lineno)
2324                     yyerror ("Invalid type expression"); RECOVER;
2325                   RECOVER;
2326                 }
2327 |       OP_TK primitive_type dims CP_TK error
2328                 {yyerror ("Missing term"); RECOVER;}
2329 |       OP_TK primitive_type CP_TK error
2330                 {yyerror ("Missing term"); RECOVER;}
2331 |       OP_TK name dims CP_TK error
2332                 {yyerror ("Missing term"); RECOVER;}
2333 ;
2334
2335 multiplicative_expression:
2336         unary_expression
2337 |       multiplicative_expression MULT_TK unary_expression
2338                 { 
2339                   $$ = build_binop (BINOP_LOOKUP ($2.token), 
2340                                     $2.location, $1, $3);
2341                 }
2342 |       multiplicative_expression DIV_TK unary_expression
2343                 {
2344                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2345                                     $1, $3); 
2346                 }
2347 |       multiplicative_expression REM_TK unary_expression
2348                 {
2349                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2350                                     $1, $3); 
2351                 }
2352 |       multiplicative_expression MULT_TK error
2353                 {yyerror ("Missing term"); RECOVER;}
2354 |       multiplicative_expression DIV_TK error
2355                 {yyerror ("Missing term"); RECOVER;}
2356 |       multiplicative_expression REM_TK error
2357                 {yyerror ("Missing term"); RECOVER;}
2358 ;
2359
2360 additive_expression:
2361         multiplicative_expression
2362 |       additive_expression PLUS_TK multiplicative_expression
2363                 {
2364                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2365                                     $1, $3); 
2366                 }
2367 |       additive_expression MINUS_TK multiplicative_expression
2368                 {
2369                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2370                                     $1, $3); 
2371                 }
2372 |       additive_expression PLUS_TK error
2373                 {yyerror ("Missing term"); RECOVER;}
2374 |       additive_expression MINUS_TK error
2375                 {yyerror ("Missing term"); RECOVER;}
2376 ;
2377
2378 shift_expression:
2379         additive_expression
2380 |       shift_expression LS_TK additive_expression
2381                 {
2382                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2383                                     $1, $3); 
2384                 }
2385 |       shift_expression SRS_TK additive_expression
2386                 {
2387                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2388                                     $1, $3); 
2389                 }
2390 |       shift_expression ZRS_TK additive_expression
2391                 {
2392                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2393                                     $1, $3); 
2394                 }
2395 |       shift_expression LS_TK error
2396                 {yyerror ("Missing term"); RECOVER;}
2397 |       shift_expression SRS_TK error
2398                 {yyerror ("Missing term"); RECOVER;}
2399 |       shift_expression ZRS_TK error
2400                 {yyerror ("Missing term"); RECOVER;}
2401 ;
2402
2403 relational_expression:
2404         shift_expression
2405 |       relational_expression LT_TK shift_expression
2406                 {
2407                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2408                                     $1, $3); 
2409                 }
2410 |       relational_expression GT_TK shift_expression
2411                 {
2412                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2413                                     $1, $3); 
2414                 }
2415 |       relational_expression LTE_TK shift_expression
2416                 {
2417                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2418                                     $1, $3); 
2419                 }
2420 |       relational_expression GTE_TK shift_expression
2421                 {
2422                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2423                                     $1, $3); 
2424                 }
2425 |       relational_expression INSTANCEOF_TK reference_type
2426                 { $$ = build_binop (INSTANCEOF_EXPR, $2.location, $1, $3); }
2427 |       relational_expression LT_TK error
2428                 {yyerror ("Missing term"); RECOVER;}
2429 |       relational_expression GT_TK error
2430                 {yyerror ("Missing term"); RECOVER;}
2431 |       relational_expression LTE_TK error
2432                 {yyerror ("Missing term"); RECOVER;}
2433 |       relational_expression GTE_TK error
2434                 {yyerror ("Missing term"); RECOVER;}
2435 |       relational_expression INSTANCEOF_TK error
2436                 {yyerror ("Invalid reference type"); RECOVER;}
2437 ;
2438
2439 equality_expression:
2440         relational_expression
2441 |       equality_expression EQ_TK relational_expression
2442                 {
2443                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2444                                     $1, $3); 
2445                 }
2446 |       equality_expression NEQ_TK relational_expression
2447                 {
2448                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2449                                     $1, $3); 
2450                 }
2451 |       equality_expression EQ_TK error
2452                 {yyerror ("Missing term"); RECOVER;}
2453 |       equality_expression NEQ_TK error
2454                 {yyerror ("Missing term"); RECOVER;}
2455 ;
2456
2457 and_expression:
2458         equality_expression
2459 |       and_expression AND_TK equality_expression
2460                 {
2461                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2462                                     $1, $3); 
2463                 }
2464 |       and_expression AND_TK error
2465                 {yyerror ("Missing term"); RECOVER;}
2466 ;
2467
2468 exclusive_or_expression:
2469         and_expression
2470 |       exclusive_or_expression XOR_TK and_expression
2471                 {
2472                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2473                                     $1, $3); 
2474                 }
2475 |       exclusive_or_expression XOR_TK error
2476                 {yyerror ("Missing term"); RECOVER;}
2477 ;
2478
2479 inclusive_or_expression:
2480         exclusive_or_expression
2481 |       inclusive_or_expression OR_TK exclusive_or_expression
2482                 {
2483                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2484                                     $1, $3); 
2485                 }
2486 |       inclusive_or_expression OR_TK error
2487                 {yyerror ("Missing term"); RECOVER;}
2488 ;
2489
2490 conditional_and_expression:
2491         inclusive_or_expression
2492 |       conditional_and_expression BOOL_AND_TK inclusive_or_expression
2493                 {
2494                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2495                                     $1, $3); 
2496                 }
2497 |       conditional_and_expression BOOL_AND_TK error
2498                 {yyerror ("Missing term"); RECOVER;}
2499 ;
2500
2501 conditional_or_expression:
2502         conditional_and_expression
2503 |       conditional_or_expression BOOL_OR_TK conditional_and_expression
2504                 {
2505                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2506                                     $1, $3); 
2507                 }
2508 |       conditional_or_expression BOOL_OR_TK error
2509                 {yyerror ("Missing term"); RECOVER;}
2510 ;
2511
2512 conditional_expression:         /* Error handling here is weak */
2513         conditional_or_expression
2514 |       conditional_or_expression REL_QM_TK expression REL_CL_TK conditional_expression
2515                 {
2516                   $$ = build (CONDITIONAL_EXPR, NULL_TREE, $1, $3, $5);
2517                   EXPR_WFL_LINECOL ($$) = $2.location;
2518                 }
2519 |       conditional_or_expression REL_QM_TK REL_CL_TK error
2520                 {
2521                   YYERROR_NOW;
2522                   yyerror ("Missing term");
2523                   DRECOVER (1);
2524                 }
2525 |       conditional_or_expression REL_QM_TK error
2526                 {yyerror ("Missing term"); DRECOVER (2);}
2527 |       conditional_or_expression REL_QM_TK expression REL_CL_TK error
2528                 {yyerror ("Missing term"); DRECOVER (3);}
2529 ;
2530
2531 assignment_expression:
2532         conditional_expression
2533 |       assignment
2534 ;
2535
2536 assignment:
2537         left_hand_side assignment_operator assignment_expression
2538                 { $$ = build_assignment ($2.token, $2.location, $1, $3); }
2539 |       left_hand_side assignment_operator error
2540                 {
2541                   if (ctxp->prevent_ese != lineno)
2542                     yyerror ("Missing term");
2543                   DRECOVER (assign);
2544                 }
2545 ;
2546
2547 left_hand_side:
2548         name
2549 |       field_access
2550 |       array_access
2551 ;
2552
2553 assignment_operator:
2554         ASSIGN_ANY_TK
2555 |       ASSIGN_TK
2556 ;
2557
2558 expression:
2559         assignment_expression
2560 ;
2561
2562 constant_expression:
2563         expression
2564 ;
2565
2566 %%
2567 \f
2568
2569 /* This section of the code deal with save/restoring parser contexts.
2570    Add mode documentation here. FIXME */
2571
2572 /* Helper function. Create a new parser context. With
2573    COPY_FROM_PREVIOUS set to a non zero value, content of the previous
2574    context is copied, otherwise, the new context is zeroed. The newly
2575    created context becomes the current one.  */
2576
2577 static void
2578 create_new_parser_context (copy_from_previous)
2579     int copy_from_previous;
2580 {
2581   struct parser_ctxt *new;
2582
2583   new =  (struct parser_ctxt *)xmalloc(sizeof (struct parser_ctxt));
2584   if (copy_from_previous)
2585     {
2586       memcpy ((PTR)new, (PTR)ctxp, sizeof (struct parser_ctxt));
2587       new->saved_data_ctx = 1;
2588     }
2589   else
2590     bzero ((PTR) new, sizeof (struct parser_ctxt));
2591       
2592   new->next = ctxp;
2593   ctxp = new;
2594 }
2595
2596 /* Create a new parser context and make it the current one. */
2597
2598 void
2599 java_push_parser_context ()
2600 {
2601   create_new_parser_context (0);
2602   if (ctxp->next)
2603     {
2604       ctxp->incomplete_class = ctxp->next->incomplete_class;
2605       ctxp->gclass_list = ctxp->next->gclass_list;
2606     }
2607 }  
2608
2609 void 
2610 java_pop_parser_context (generate)
2611      int generate;
2612 {
2613   tree current;
2614   struct parser_ctxt *toFree, *next;
2615
2616   if (!ctxp)
2617     return;
2618
2619   toFree = ctxp;
2620   next = ctxp->next;
2621   if (next)
2622     {
2623       next->incomplete_class = ctxp->incomplete_class;
2624       next->gclass_list = ctxp->gclass_list;
2625       lineno = ctxp->lineno;
2626       finput = ctxp->finput;
2627       current_class = ctxp->current_class;
2628     }
2629
2630   /* Set the single import class file flag to 0 for the current list
2631      of imported things */
2632   for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
2633     IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_PURPOSE (current)) = 0;
2634
2635   /* And restore those of the previous context */
2636   if ((ctxp = next))            /* Assignment is really meant here */
2637     for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
2638       IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_PURPOSE (current)) = 1;
2639   
2640   /* If we pushed a context to parse a class intended to be generated,
2641      we keep it so we can remember the class. What we could actually
2642      do is to just update a list of class names.  */
2643   if (generate)
2644     {
2645       toFree->next = ctxp_for_generation;
2646       ctxp_for_generation = toFree;
2647     }
2648   else
2649     free (toFree);
2650 }
2651
2652 /* Create a parser context for the use of saving some global
2653    variables.  */
2654
2655 void
2656 java_parser_context_save_global ()
2657 {
2658   if (!ctxp)
2659     {
2660       java_push_parser_context ();
2661       ctxp->saved_data_ctx = 1;
2662     }
2663
2664   /* If this context already stores data, create a new one suitable
2665      for data storage. */
2666   else if (ctxp->saved_data)
2667     create_new_parser_context (1);
2668
2669   ctxp->finput = finput;
2670   ctxp->lineno = lineno;
2671   ctxp->current_class = current_class;
2672   ctxp->filename = input_filename;
2673   ctxp->current_function_decl = current_function_decl;
2674   ctxp->saved_data = 1;
2675 }
2676
2677 /* Restore some global variables from the previous context. Make the
2678    previous context the current one.  */
2679
2680 void
2681 java_parser_context_restore_global ()
2682 {
2683   finput = ctxp->finput;
2684   lineno = ctxp->lineno;
2685   current_class = ctxp->current_class;
2686   input_filename = ctxp->filename;
2687   current_function_decl = ctxp->current_function_decl;
2688   ctxp->saved_data = 0;
2689   if (ctxp->saved_data_ctx)
2690     java_pop_parser_context (0);
2691 }
2692
2693 /* Suspend vital data for the current class/function being parsed so
2694    that an other class can be parsed. Used to let local/anonymous
2695    classes be parsed.  */
2696
2697 static void
2698 java_parser_context_suspend ()
2699 {
2700   /* This makes debugging through java_debug_context easier */
2701   static const char *name = "<inner buffer context>";
2702
2703   /* Duplicate the previous context, use it to save the globals we're
2704      interested in */
2705   create_new_parser_context (1);
2706   ctxp->current_function_decl = current_function_decl;
2707   ctxp->current_class = current_class;
2708
2709   /* Then create a new context which inherits all data from the
2710      previous one. This will be the new current context  */
2711   create_new_parser_context (1);
2712
2713   /* Help debugging */
2714   ctxp->next->filename = name;
2715 }
2716
2717 /* Resume vital data for the current class/function being parsed so
2718    that an other class can be parsed. Used to let local/anonymous
2719    classes be parsed.  The trick is the data storing file position
2720    informations must be restored to their current value, so parsing
2721    can resume as if no context was ever saved. */
2722
2723 static void
2724 java_parser_context_resume ()
2725 {
2726   struct parser_ctxt *old = ctxp;             /* This one is to be discarded */
2727   struct parser_ctxt *saver = old->next;      /* This one contain saved info */
2728   struct parser_ctxt *restored = saver->next; /* This one is the old current */
2729
2730   /* We need to inherit the list of classes to complete/generate */
2731   restored->incomplete_class = old->incomplete_class;
2732   restored->gclass_list = old->gclass_list;
2733   restored->classd_list = old->classd_list;
2734   restored->class_list = old->class_list;
2735
2736   /* Restore the current class and function from the saver */
2737   current_class = saver->current_class;
2738   current_function_decl = saver->current_function_decl;
2739
2740   /* Retrive the restored context */
2741   ctxp = restored;
2742
2743   /* Re-installed the data for the parsing to carry on */
2744   bcopy (&old->marker_begining, &ctxp->marker_begining,
2745          (size_t)(&ctxp->marker_end - &ctxp->marker_begining));
2746
2747   /* Buffer context can now be discarded */
2748   free (saver);
2749   free (old);
2750 }
2751
2752 /* Add a new anchor node to which all statement(s) initializing static
2753    and non static initialized upon declaration field(s) will be
2754    linked.  */
2755
2756 static void
2757 java_parser_context_push_initialized_field ()
2758 {
2759   tree node;
2760
2761   node = build_tree_list (NULL_TREE, NULL_TREE);
2762   TREE_CHAIN (node) = CPC_STATIC_INITIALIZER_LIST (ctxp);
2763   CPC_STATIC_INITIALIZER_LIST (ctxp) = node;
2764
2765   node = build_tree_list (NULL_TREE, NULL_TREE);
2766   TREE_CHAIN (node) = CPC_INITIALIZER_LIST (ctxp);
2767   CPC_INITIALIZER_LIST (ctxp) = node;
2768
2769   node = build_tree_list (NULL_TREE, NULL_TREE);
2770   TREE_CHAIN (node) = CPC_INSTANCE_INITIALIZER_LIST (ctxp);
2771   CPC_INSTANCE_INITIALIZER_LIST (ctxp) = node;
2772 }
2773
2774 /* Pop the lists of initialized field. If this lists aren't empty,
2775    remember them so we can use it to create and populate the $finit$
2776    or <clinit> functions. */
2777
2778 static void
2779 java_parser_context_pop_initialized_field ()
2780 {
2781   tree stmts;
2782   tree class_type = TREE_TYPE (GET_CPC ());
2783
2784   if (CPC_INITIALIZER_LIST (ctxp))
2785     {
2786       stmts = CPC_INITIALIZER_STMT (ctxp);
2787       CPC_INITIALIZER_LIST (ctxp) = TREE_CHAIN (CPC_INITIALIZER_LIST (ctxp));
2788       if (stmts && !java_error_count)
2789         TYPE_FINIT_STMT_LIST (class_type) = reorder_static_initialized (stmts);
2790     }
2791
2792   if (CPC_STATIC_INITIALIZER_LIST (ctxp))
2793     {
2794       stmts = CPC_STATIC_INITIALIZER_STMT (ctxp);
2795       CPC_STATIC_INITIALIZER_LIST (ctxp) = 
2796         TREE_CHAIN (CPC_STATIC_INITIALIZER_LIST (ctxp));
2797       /* Keep initialization in order to enforce 8.5 */
2798       if (stmts && !java_error_count)
2799         TYPE_CLINIT_STMT_LIST (class_type) = nreverse (stmts);
2800     }
2801
2802   /* JDK 1.1 instance initializers */
2803   if (CPC_INSTANCE_INITIALIZER_LIST (ctxp))
2804     {
2805       stmts = CPC_INSTANCE_INITIALIZER_STMT (ctxp);
2806       CPC_INSTANCE_INITIALIZER_LIST (ctxp) = 
2807         TREE_CHAIN (CPC_INSTANCE_INITIALIZER_LIST (ctxp));
2808       if (stmts && !java_error_count)
2809         TYPE_II_STMT_LIST (class_type) = nreverse (stmts);
2810     }
2811 }
2812
2813 static tree
2814 reorder_static_initialized (list)
2815      tree list;
2816 {
2817   /* We have to keep things in order. The alias initializer have to
2818      come first, then the initialized regular field, in reverse to
2819      keep them in lexical order. */
2820   tree marker, previous = NULL_TREE;
2821   for (marker = list; marker; previous = marker, marker = TREE_CHAIN (marker))
2822     if (TREE_CODE (marker) == TREE_LIST 
2823         && !TREE_VALUE (marker) && !TREE_PURPOSE (marker))
2824       break;
2825   
2826   /* No static initialized, the list is fine as is */
2827   if (!previous)
2828     list = TREE_CHAIN (marker);
2829
2830   /* No marker? reverse the whole list */
2831   else if (!marker)
2832     list = nreverse (list);
2833
2834   /* Otherwise, reverse what's after the marker and the new reordered
2835      sublist will replace the marker. */
2836   else
2837     {
2838       TREE_CHAIN (previous) = NULL_TREE;
2839       list = nreverse (list);
2840       list = chainon (TREE_CHAIN (marker), list);
2841     }
2842   return list;
2843 }
2844
2845 /* Helper functions to dump the parser context stack.  */
2846
2847 #define TAB_CONTEXT(C) \
2848   {int i; for (i = 0; i < (C); i++) fputc (' ', stderr);}
2849
2850 static void
2851 java_debug_context_do (tab)
2852      int tab;
2853 {
2854   struct parser_ctxt *copy = ctxp;
2855   while (copy)
2856     {
2857       TAB_CONTEXT (tab);
2858       fprintf (stderr, "ctxt: 0x%0lX\n", (unsigned long)copy);
2859       TAB_CONTEXT (tab);
2860       fprintf (stderr, "filename: %s\n", copy->filename);
2861       TAB_CONTEXT (tab);
2862       fprintf (stderr, "lineno: %d\n", copy->lineno);
2863       TAB_CONTEXT (tab);
2864       fprintf (stderr, "package: %s\n",
2865                (copy->package ? 
2866                 IDENTIFIER_POINTER (copy->package) : "<none>"));
2867       TAB_CONTEXT (tab);
2868       fprintf (stderr, "context for saving: %d\n", copy->saved_data_ctx);
2869       TAB_CONTEXT (tab);
2870       fprintf (stderr, "saved data: %d\n", copy->saved_data);
2871       copy = copy->next;
2872       tab += 2;
2873     }
2874 }
2875
2876 /* Dump the stacked up parser contexts. Intended to be called from a
2877    debugger.  */
2878
2879 void
2880 java_debug_context ()
2881 {
2882   java_debug_context_do (0);
2883 }
2884
2885 \f
2886
2887 /* Flag for the error report routine to issue the error the first time
2888    it's called (overriding the default behavior which is to drop the
2889    first invocation and honor the second one, taking advantage of a
2890    richer context.  */
2891 static int force_error = 0;
2892
2893 /* Reporting an constructor invocation error.  */
2894 static void
2895 parse_ctor_invocation_error ()
2896 {
2897   if (DECL_CONSTRUCTOR_P (current_function_decl))
2898     yyerror ("Constructor invocation must be first thing in a constructor"); 
2899   else
2900     yyerror ("Only constructors can invoke constructors");
2901 }
2902
2903 /* Reporting JDK1.1 features not implemented.  */
2904
2905 static tree
2906 parse_jdk1_1_error (msg)
2907     const char *msg;
2908 {
2909   sorry (": `%s' JDK1.1(TM) feature", msg);
2910   java_error_count++;
2911   return empty_stmt_node;
2912 }
2913
2914 static int do_warning = 0;
2915
2916 void
2917 yyerror (msg)
2918      const char *msg;
2919 {
2920   static java_lc elc;
2921   static int  prev_lineno;
2922   static const char *prev_msg;
2923
2924   int save_lineno;
2925   char *remainder, *code_from_source;
2926   extern struct obstack temporary_obstack;
2927   
2928   if (!force_error && prev_lineno == lineno)
2929     return;
2930
2931   /* Save current error location but report latter, when the context is
2932      richer.  */
2933   if (ctxp->java_error_flag == 0)
2934     {
2935       ctxp->java_error_flag = 1;
2936       elc = ctxp->elc;
2937       /* Do something to use the previous line if we're reaching the
2938          end of the file... */
2939 #ifdef VERBOSE_SKELETON
2940       printf ("* Error detected (%s)\n", (msg ? msg : "(null)"));
2941 #endif
2942       return;
2943     }
2944
2945   /* Ignore duplicate message on the same line. BTW, this is dubious. FIXME */
2946   if (!force_error && msg == prev_msg && prev_lineno == elc.line)
2947     return;
2948
2949   ctxp->java_error_flag = 0;
2950   if (do_warning)
2951     java_warning_count++;
2952   else
2953     java_error_count++;
2954   
2955   if (elc.col == 0 && msg && msg[1] == ';')
2956     {
2957       elc.col  = ctxp->p_line->char_col-1;
2958       elc.line = ctxp->p_line->lineno;
2959     }
2960
2961   save_lineno = lineno;
2962   prev_lineno = lineno = elc.line;
2963   prev_msg = msg;
2964
2965   code_from_source = java_get_line_col (ctxp->filename, elc.line, elc.col);
2966   obstack_grow0 (&temporary_obstack, 
2967                  code_from_source, strlen (code_from_source));
2968   remainder = obstack_finish (&temporary_obstack);
2969   if (do_warning)
2970     warning ("%s.\n%s", msg, remainder);
2971   else
2972     error ("%s.\n%s", msg, remainder);
2973
2974   /* This allow us to cheaply avoid an extra 'Invalid expression
2975      statement' error report when errors have been already reported on
2976      the same line. This occurs when we report an error but don't have
2977      a synchronization point other than ';', which
2978      expression_statement is the only one to take care of.  */
2979   ctxp->prevent_ese = lineno = save_lineno;
2980 }
2981
2982 static void
2983 issue_warning_error_from_context (cl, msg, ap)
2984      tree cl;
2985      const char *msg;
2986      va_list ap;
2987 {
2988   const char *saved, *saved_input_filename;
2989   char buffer [4096];
2990   vsprintf (buffer, msg, ap);
2991   force_error = 1;
2992
2993   ctxp->elc.line = EXPR_WFL_LINENO (cl);
2994   ctxp->elc.col  = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 : 
2995                     (EXPR_WFL_COLNO (cl) == 0xffe ? -2 : EXPR_WFL_COLNO (cl)));
2996
2997   /* We have a CL, that's a good reason for using it if it contains data */
2998   saved = ctxp->filename;
2999   if (TREE_CODE (cl) == EXPR_WITH_FILE_LOCATION && EXPR_WFL_FILENAME_NODE (cl))
3000     ctxp->filename = EXPR_WFL_FILENAME (cl);
3001   saved_input_filename = input_filename;
3002   input_filename = ctxp->filename;
3003   java_error (NULL);
3004   java_error (buffer);
3005   ctxp->filename = saved;
3006   input_filename = saved_input_filename;
3007   force_error = 0;
3008 }
3009
3010 /* Issue an error message at a current source line CL */
3011
3012 void
3013 parse_error_context VPARAMS ((tree cl, const char *msg, ...))
3014 {
3015 #ifndef ANSI_PROTOTYPES
3016   tree cl;
3017   const char *msg;
3018 #endif
3019   va_list ap;
3020
3021   VA_START (ap, msg);
3022 #ifndef ANSI_PROTOTYPES
3023   cl = va_arg (ap, tree);
3024   msg = va_arg (ap, const char *);
3025 #endif
3026   issue_warning_error_from_context (cl, msg, ap);
3027   va_end (ap);
3028 }
3029
3030 /* Issue a warning at a current source line CL */
3031
3032 static void
3033 parse_warning_context VPARAMS ((tree cl, const char *msg, ...))
3034 {
3035 #ifndef ANSI_PROTOTYPES
3036   tree cl;
3037   const char *msg;
3038 #endif
3039   va_list ap;
3040
3041   VA_START (ap, msg);
3042 #ifndef ANSI_PROTOTYPES
3043   cl = va_arg (ap, tree);
3044   msg = va_arg (ap, const char *);
3045 #endif
3046
3047   force_error = do_warning = 1;
3048   issue_warning_error_from_context (cl, msg, ap);
3049   do_warning = force_error = 0;
3050   va_end (ap);
3051 }
3052
3053 static tree
3054 find_expr_with_wfl (node)
3055      tree node;
3056 {
3057   while (node)
3058     {
3059       char code;
3060       tree to_return;
3061
3062       switch (TREE_CODE (node))
3063         {
3064         case BLOCK:
3065           node = BLOCK_EXPR_BODY (node);
3066           continue;
3067
3068         case COMPOUND_EXPR:
3069           to_return = find_expr_with_wfl (TREE_OPERAND (node, 0));
3070           if (to_return)
3071             return to_return;
3072           node = TREE_OPERAND (node, 1);
3073           continue;
3074
3075         case LOOP_EXPR:
3076           node = TREE_OPERAND (node, 0);
3077           continue;
3078           
3079         case LABELED_BLOCK_EXPR:
3080           node = TREE_OPERAND (node, 1);
3081           continue;
3082
3083         default:
3084           code = TREE_CODE_CLASS (TREE_CODE (node));
3085           if (((code == '1') || (code == '2') || (code == 'e'))
3086               && EXPR_WFL_LINECOL (node))
3087             return node;
3088           return NULL_TREE;
3089         }
3090     }
3091   return NULL_TREE;
3092 }
3093
3094 /* Issue a missing return statement error. Uses METHOD to figure the
3095    last line of the method the error occurs in.  */
3096
3097 static void
3098 missing_return_error (method)
3099      tree method;
3100 {
3101   EXPR_WFL_SET_LINECOL (wfl_operator, DECL_SOURCE_LINE_LAST (method), -2);
3102   parse_error_context (wfl_operator, "Missing return statement");
3103 }
3104
3105 /* Issue an unreachable statement error. From NODE, find the next
3106    statement to report appropriately.  */
3107 static void
3108 unreachable_stmt_error (node)
3109      tree node;
3110 {
3111   /* Browse node to find the next expression node that has a WFL. Use
3112      the location to report the error */
3113   if (TREE_CODE (node) == COMPOUND_EXPR)
3114     node = find_expr_with_wfl (TREE_OPERAND (node, 1));
3115   else
3116     node = find_expr_with_wfl (node);
3117
3118   if (node)
3119     {
3120       EXPR_WFL_SET_LINECOL (wfl_operator, EXPR_WFL_LINENO (node), -2);
3121       parse_error_context (wfl_operator, "Unreachable statement");
3122     }
3123   else
3124     fatal ("Can't get valid statement - unreachable_stmt_error");
3125 }
3126
3127 int
3128 java_report_errors ()
3129 {
3130   if (java_error_count)
3131     fprintf (stderr, "%d error%s", 
3132              java_error_count, (java_error_count == 1 ? "" : "s"));
3133   if (java_warning_count)
3134     fprintf (stderr, "%s%d warning%s", (java_error_count ? ", " : ""),
3135              java_warning_count, (java_warning_count == 1 ? "" : "s"));
3136   if (java_error_count || java_warning_count)
3137     putc ('\n', stderr);
3138   return java_error_count;
3139 }
3140
3141 static char *
3142 java_accstring_lookup (flags)
3143      int flags;
3144 {
3145   static char buffer [80];
3146 #define COPY_RETURN(S) {strcpy (buffer, S); return buffer;}
3147
3148   /* Access modifier looked-up first for easier report on forbidden
3149      access. */
3150   if (flags & ACC_PUBLIC) COPY_RETURN ("public");
3151   if (flags & ACC_PRIVATE) COPY_RETURN ("private");
3152   if (flags & ACC_PROTECTED) COPY_RETURN ("protected");
3153   if (flags & ACC_STATIC) COPY_RETURN ("static");
3154   if (flags & ACC_FINAL) COPY_RETURN ("final");
3155   if (flags & ACC_SYNCHRONIZED) COPY_RETURN ("synchronized");
3156   if (flags & ACC_VOLATILE) COPY_RETURN ("volatile");
3157   if (flags & ACC_TRANSIENT) COPY_RETURN ("transient");
3158   if (flags & ACC_NATIVE) COPY_RETURN ("native");
3159   if (flags & ACC_INTERFACE) COPY_RETURN ("interface");
3160   if (flags & ACC_ABSTRACT) COPY_RETURN ("abstract");
3161
3162   buffer [0] = '\0';
3163   return buffer;
3164 #undef COPY_RETURN
3165 }
3166
3167 /* Issuing error messages upon redefinition of classes, interfaces or
3168    variables. */
3169
3170 static void
3171 classitf_redefinition_error (context, id, decl, cl)
3172      const char *context;
3173      tree id, decl, cl;
3174 {
3175   parse_error_context (cl, "%s `%s' already defined in %s:%d", 
3176                        context, IDENTIFIER_POINTER (id), 
3177                        DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
3178   /* Here we should point out where its redefined. It's a unicode. FIXME */
3179 }
3180
3181 static void
3182 variable_redefinition_error (context, name, type, line)
3183      tree context, name, type;
3184      int line;
3185 {
3186   const char *type_name;
3187
3188   /* Figure a proper name for type. We might haven't resolved it */
3189   if (TREE_CODE (type) == POINTER_TYPE && !TREE_TYPE (type))
3190     type_name = IDENTIFIER_POINTER (TYPE_NAME (type));
3191   else
3192     type_name = lang_printable_name (type, 0);
3193
3194   parse_error_context (context,
3195                        "Variable `%s' is already defined in this method and was declared `%s %s' at line %d", 
3196                        IDENTIFIER_POINTER (name),
3197                        type_name, IDENTIFIER_POINTER (name), line);
3198 }
3199
3200 static tree
3201 build_array_from_name (type, type_wfl, name, ret_name)
3202      tree type, type_wfl, name, *ret_name;
3203 {
3204   int more_dims = 0;
3205   const char *string;
3206
3207   /* Eventually get more dims */
3208   string = IDENTIFIER_POINTER (name);
3209   while (string [more_dims] == '[')
3210     more_dims++;
3211   
3212   /* If we have, then craft a new type for this variable */
3213   if (more_dims)
3214     {
3215       name = get_identifier (&string [more_dims]);
3216
3217       /* If we have a pointer, use its type */
3218       if (TREE_CODE (type) == POINTER_TYPE)
3219         type = TREE_TYPE (type);
3220
3221       /* Building the first dimension of a primitive type uses this
3222          function */
3223       if (JPRIMITIVE_TYPE_P (type))
3224         {
3225           type = build_java_array_type (type, -1);
3226           CLASS_LOADED_P (type) = 1;
3227           more_dims--;
3228         }
3229       /* Otherwise, if we have a WFL for this type, use it (the type
3230          is already an array on an unresolved type, and we just keep
3231          on adding dimensions) */
3232       else if (type_wfl)
3233         type = type_wfl;
3234
3235       /* Add all the dimensions */
3236       while (more_dims--)
3237         type = build_unresolved_array_type (type);
3238
3239       /* The type may have been incomplete in the first place */
3240       if (type_wfl)
3241         type = obtain_incomplete_type (type);
3242     }
3243
3244   if (ret_name)
3245     *ret_name = name;
3246   return type;
3247 }
3248
3249 /* Build something that the type identifier resolver will identify as
3250    being an array to an unresolved type. TYPE_WFL is a WFL on a
3251    identifier. */
3252
3253 static tree
3254 build_unresolved_array_type (type_or_wfl)
3255      tree type_or_wfl;
3256 {
3257   const char *ptr;
3258
3259   /* TYPE_OR_WFL might be an array on a resolved type. In this case,
3260      just create a array type */
3261   if (TREE_CODE (type_or_wfl) == RECORD_TYPE)
3262     {
3263       tree type = build_java_array_type (type_or_wfl, -1);
3264       CLASS_LOADED_P (type) = CLASS_LOADED_P (type_or_wfl);
3265       return type;
3266     }
3267
3268   obstack_1grow (&temporary_obstack, '[');
3269   obstack_grow0 (&temporary_obstack,
3270                  IDENTIFIER_POINTER (EXPR_WFL_NODE (type_or_wfl)),
3271                  IDENTIFIER_LENGTH (EXPR_WFL_NODE (type_or_wfl)));
3272   ptr = obstack_finish (&temporary_obstack);
3273   return build_expr_wfl (get_identifier (ptr),
3274                          EXPR_WFL_FILENAME (type_or_wfl),
3275                          EXPR_WFL_LINENO (type_or_wfl),
3276                          EXPR_WFL_COLNO (type_or_wfl));
3277 }
3278
3279 static void
3280 parser_add_interface (class_decl, interface_decl, wfl)
3281      tree class_decl, interface_decl, wfl;
3282 {
3283   if (maybe_add_interface (TREE_TYPE (class_decl), TREE_TYPE (interface_decl)))
3284     parse_error_context (wfl, "Interface `%s' repeated",
3285                          IDENTIFIER_POINTER (DECL_NAME (interface_decl)));
3286 }
3287
3288 /* Bulk of common class/interface checks. Return 1 if an error was
3289    encountered. TAG is 0 for a class, 1 for an interface.  */
3290
3291 static int
3292 check_class_interface_creation (is_interface, flags, raw_name, qualified_name, decl, cl)
3293      int is_interface, flags;
3294      tree raw_name, qualified_name, decl, cl;
3295 {
3296   tree node;
3297   int sca = 0;                  /* Static class allowed */
3298   int icaf = 0;                 /* Inner class allowed flags */
3299   int uaaf = CLASS_MODIFIERS;   /* Usually allowed access flags */
3300
3301   if (!quiet_flag)
3302     fprintf (stderr, " %s%s %s", 
3303              (CPC_INNER_P () ? "inner" : ""),
3304              (is_interface ? "interface" : "class"), 
3305              IDENTIFIER_POINTER (qualified_name));
3306
3307   /* Scope of an interface/class type name:
3308        - Can't be imported by a single type import
3309        - Can't already exists in the package */
3310   if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (raw_name)
3311       && (node = find_name_in_single_imports (raw_name)))
3312     {
3313       parse_error_context 
3314         (cl, "%s name `%s' clashes with imported type `%s'",
3315          (is_interface ? "Interface" : "Class"),
3316          IDENTIFIER_POINTER (raw_name), IDENTIFIER_POINTER (node));
3317       return 1;
3318     }
3319   if (decl && CLASS_COMPLETE_P (decl))
3320     {
3321       classitf_redefinition_error ((is_interface ? "Interface" : "Class"), 
3322                                    qualified_name, decl, cl);
3323       return 1;
3324     }
3325
3326   if (check_inner_class_redefinition (raw_name, cl))
3327     return 1;
3328
3329   /* If public, file name should match class/interface name, except
3330      when dealing with an inner class */
3331   if (!CPC_INNER_P () && (flags & ACC_PUBLIC ))
3332     {
3333       const char *f;
3334
3335       /* Contains OS dependent assumption on path separator. FIXME */
3336       for (f = &input_filename [strlen (input_filename)]; 
3337            f != input_filename && f[0] != '/' && f[0] != DIR_SEPARATOR;
3338            f--)
3339         ;
3340       if (f[0] == '/' || f[0] == DIR_SEPARATOR)
3341         f++;
3342       if (strncmp (IDENTIFIER_POINTER (raw_name), 
3343                    f , IDENTIFIER_LENGTH (raw_name)) ||
3344           f [IDENTIFIER_LENGTH (raw_name)] != '.')
3345         parse_error_context
3346           (cl, "Public %s `%s' must be defined in a file called `%s.java'", 
3347                              (is_interface ? "interface" : "class"),
3348                              IDENTIFIER_POINTER (qualified_name),
3349                              IDENTIFIER_POINTER (raw_name));
3350     }
3351
3352   /* Static classes can be declared only in top level classes. Note:
3353      once static, a inner class is a top level class. */
3354   if (flags & ACC_STATIC)
3355     {
3356       /* Catch the specific error of declaring an class inner class
3357          with no toplevel enclosing class. Prevent check_modifiers from
3358          complaining a second time */
3359       if (CPC_INNER_P () && !TOPLEVEL_CLASS_DECL_P (GET_CPC()))
3360         {
3361           parse_error_context (cl, "Inner class `%s' can't be static. Static classes can only occur in interfaces and top-level classes", 
3362                                IDENTIFIER_POINTER (qualified_name));
3363           sca = ACC_STATIC;
3364         }
3365       /* Else, in the context of a top-level class declaration, let
3366          `check_modifiers' do its job, otherwise, give it a go */
3367       else
3368         sca = (GET_CPC_LIST () ? ACC_STATIC : 0);
3369     }
3370
3371   /* Inner classes can be declared private or protected
3372      within their enclosing classes. */
3373   if (CPC_INNER_P ())
3374     {
3375       /* A class which is local to a block can't be public, private,
3376          protected or static. But it is created final, so allow this
3377          one. */
3378       if (current_function_decl)
3379         icaf = sca = uaaf = ACC_FINAL;
3380       else
3381         {
3382           check_modifiers_consistency (flags);
3383           icaf = ACC_PRIVATE|ACC_PROTECTED;
3384         }
3385     }
3386
3387   if (is_interface) 
3388     {
3389       if (CPC_INNER_P ())
3390         uaaf = INTERFACE_INNER_MODIFIERS;
3391       else
3392         uaaf = INTERFACE_MODIFIERS;
3393       
3394       check_modifiers ("Illegal modifier `%s' for interface declaration", 
3395                        flags, uaaf);
3396     }
3397   else
3398     check_modifiers ((current_function_decl ?
3399                       "Illegal modifier `%s' for local class declaration" :
3400                       "Illegal modifier `%s' for class declaration"),
3401                      flags, uaaf|sca|icaf);
3402   return 0;
3403 }
3404
3405 static void
3406 make_nested_class_name (cpc_list)
3407      tree cpc_list;
3408 {
3409   tree name;
3410
3411   if (!cpc_list)
3412     return;
3413   else
3414     make_nested_class_name (TREE_CHAIN (cpc_list));
3415
3416   /* Pick the qualified name when dealing with the first upmost
3417      enclosing class */
3418   name = (TREE_CHAIN (cpc_list) ? 
3419           TREE_PURPOSE (cpc_list) : DECL_NAME (TREE_VALUE (cpc_list)));
3420   obstack_grow (&temporary_obstack,
3421                 IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name));
3422   /* Why is NO_DOLLAR_IN_LABEL defined? */
3423 #if 0
3424 #ifdef NO_DOLLAR_IN_LABEL
3425   fatal ("make_nested_class_name: Can't use '$' as a separator "
3426          "for inner classes");
3427 #endif
3428 #endif
3429   obstack_1grow (&temporary_obstack, '$');
3430 }
3431
3432 /* Can't redefine a class already defined in an earlier scope. */
3433
3434 static int
3435 check_inner_class_redefinition (raw_name, cl)
3436      tree raw_name, cl;
3437 {
3438   tree scope_list;
3439
3440   for (scope_list = GET_CPC_LIST (); scope_list; 
3441        scope_list = GET_NEXT_ENCLOSING_CPC (scope_list))
3442     if (raw_name == GET_CPC_UN_NODE (scope_list))
3443       {
3444         parse_error_context 
3445           (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",
3446            IDENTIFIER_POINTER (raw_name));
3447         return 1;
3448       }
3449   return 0;
3450 }
3451
3452 static tree
3453 find_as_inner_class (enclosing, name, cl)
3454      tree enclosing, name, cl;
3455 {
3456   tree qual, to_return;
3457   if (!enclosing)
3458     return NULL_TREE;
3459
3460   name = TYPE_NAME (name);
3461
3462   /* First search: within the scope of `enclosing', search for name */
3463   if (QUALIFIED_P (name) && cl && EXPR_WFL_NODE (cl) == name)
3464     qual = EXPR_WFL_QUALIFICATION (cl);
3465   else if (cl)
3466     qual = build_tree_list (cl, NULL_TREE);
3467   else
3468     qual = build_tree_list (build_expr_wfl (name, NULL, 0, 0), NULL_TREE);
3469   
3470   if ((to_return = find_as_inner_class_do (qual, enclosing)))
3471     return to_return;
3472
3473   /* We're dealing with a qualified name. Try to resolve thing until
3474      we get something that is an enclosing class. */
3475   if (QUALIFIED_P (name) && cl && EXPR_WFL_NODE (cl) == name)
3476     {
3477       tree acc = NULL_TREE, decl = NULL_TREE, ptr;
3478
3479       for (qual = EXPR_WFL_QUALIFICATION (cl); qual && !decl; 
3480            qual = TREE_CHAIN (qual))
3481         {
3482           acc = merge_qualified_name (acc, 
3483                                       EXPR_WFL_NODE (TREE_PURPOSE (qual)));
3484           BUILD_PTR_FROM_NAME (ptr, acc);
3485           decl = do_resolve_class (NULL_TREE, ptr, NULL_TREE, cl);
3486         }
3487
3488       /* A NULL qual and a decl means that the search ended
3489          successfully?!? We have to do something then. FIXME */
3490       
3491       if (decl)
3492         enclosing = decl;
3493       else
3494         qual = EXPR_WFL_QUALIFICATION (cl);
3495     }
3496   /* Otherwise, create a qual for the other part of the resolution. */
3497   else
3498     qual = build_tree_list (build_expr_wfl (name, NULL, 0, 0), NULL_TREE);
3499
3500   if (!(to_return = find_as_inner_class_do (qual, enclosing)))
3501     {
3502       /* It might be the case that the enclosing class was loaded as
3503          bytecode, in which case it will be missing the
3504          DECL_INNER_CLASS_LIST. We build a fully qualified internal
3505          innerclass name and we try to load it. */
3506       tree fqin = identifier_subst (name, "", '.', '$', "");
3507       tree ptr;
3508       BUILD_PTR_FROM_NAME (ptr, fqin);
3509       to_return = resolve_class (NULL_TREE, ptr, NULL_TREE, cl);
3510     }
3511   return to_return;
3512 }
3513
3514 /* We go inside the list of sub classes and try to find a way
3515    through. */
3516
3517 static tree
3518 find_as_inner_class_do (qual, enclosing)
3519      tree qual, enclosing;
3520 {
3521   if (!qual)
3522     return NULL_TREE;
3523
3524   for (; qual && enclosing; qual = TREE_CHAIN (qual))
3525     {
3526       tree name_to_match = EXPR_WFL_NODE (TREE_PURPOSE (qual));
3527       tree next_enclosing = NULL_TREE;
3528       tree inner_list;
3529
3530       for (inner_list = DECL_INNER_CLASS_LIST (enclosing);
3531            inner_list; inner_list = TREE_CHAIN (inner_list))
3532         {
3533           if (TREE_VALUE (inner_list) == name_to_match)
3534             {
3535               next_enclosing = TREE_PURPOSE (inner_list);
3536               break;
3537             }
3538         }
3539       enclosing = next_enclosing;
3540     }
3541
3542   return (!qual && enclosing ? enclosing : NULL_TREE);
3543 }
3544
3545 /* Reach all inner classes and tie their unqualified name to a
3546    DECL. */
3547
3548 static void
3549 set_nested_class_simple_name_value (outer, set)
3550      tree outer;
3551      int set;
3552 {
3553   tree l;
3554
3555   for (l = DECL_INNER_CLASS_LIST (outer); l; l = TREE_CHAIN (l))
3556     IDENTIFIER_GLOBAL_VALUE (TREE_VALUE (l)) = (set ? 
3557                                                 TREE_PURPOSE (l) : NULL_TREE);
3558 }
3559
3560 static void
3561 link_nested_class_to_enclosing ()
3562 {
3563   if (GET_ENCLOSING_CPC ())
3564     {
3565       tree enclosing = GET_ENCLOSING_CPC_CONTEXT ();
3566       DECL_INNER_CLASS_LIST (enclosing) = 
3567         tree_cons (GET_CPC (), GET_CPC_UN (),
3568                    DECL_INNER_CLASS_LIST (enclosing));
3569       enclosing = enclosing;
3570     }
3571 }
3572
3573 static tree
3574 maybe_make_nested_class_name (name)
3575      tree name;
3576 {
3577   tree id = NULL_TREE;
3578
3579   if (CPC_INNER_P ())
3580     {
3581       make_nested_class_name (GET_CPC_LIST ());
3582       obstack_grow0 (&temporary_obstack,
3583                      IDENTIFIER_POINTER (name), 
3584                      IDENTIFIER_LENGTH (name));
3585       id = get_identifier (obstack_finish (&temporary_obstack));
3586       if (ctxp->package)
3587         QUALIFIED_P (id) = 1;
3588     }
3589   return id;
3590 }
3591
3592 /* If DECL is NULL, create and push a new DECL, record the current
3593    line CL and do other maintenance things.  */
3594
3595 static tree
3596 maybe_create_class_interface_decl (decl, raw_name, qualified_name, cl)
3597      tree decl, raw_name, qualified_name, cl;
3598 {
3599   if (!decl)
3600     decl = push_class (make_class (), qualified_name);
3601
3602   /* Take care of the file and line business */
3603   DECL_SOURCE_FILE (decl) = EXPR_WFL_FILENAME (cl);
3604   /* If we're emiting xrefs, store the line/col number information */
3605   if (flag_emit_xref)
3606     DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (cl);
3607   else
3608     DECL_SOURCE_LINE (decl) = EXPR_WFL_LINENO (cl);
3609   CLASS_FROM_SOURCE_P (TREE_TYPE (decl)) = 1;
3610   CLASS_FROM_CURRENTLY_COMPILED_SOURCE_P (TREE_TYPE (decl)) =
3611     IS_A_COMMAND_LINE_FILENAME_P (EXPR_WFL_FILENAME_NODE (cl));
3612
3613   PUSH_CPC (decl, raw_name);
3614   DECL_CONTEXT (decl) = GET_ENCLOSING_CPC_CONTEXT ();
3615
3616   /* Link the declaration to the already seen ones */
3617   TREE_CHAIN (decl) = ctxp->class_list;
3618   ctxp->class_list = decl;
3619
3620   /* Create a new nodes in the global lists */
3621   ctxp->gclass_list = tree_cons (NULL_TREE, decl, ctxp->gclass_list);
3622   all_class_list = tree_cons (NULL_TREE, decl, all_class_list);
3623
3624   /* Install a new dependency list element */
3625   create_jdep_list (ctxp);
3626
3627   SOURCE_FRONTEND_DEBUG (("Defining class/interface %s", 
3628                           IDENTIFIER_POINTER (qualified_name)));
3629   return decl;
3630 }
3631
3632 static void
3633 add_superinterfaces (decl, interface_list)
3634      tree decl, interface_list;
3635 {
3636   tree node;
3637   /* Superinterface(s): if present and defined, parser_check_super_interface ()
3638      takes care of ensuring that:
3639        - This is an accessible interface type,
3640        - Circularity detection.
3641    parser_add_interface is then called. If present but not defined,
3642    the check operation is delayed until the super interface gets
3643    defined.  */
3644   for (node = interface_list; node; node = TREE_CHAIN (node))
3645     {
3646       tree current = TREE_PURPOSE (node);
3647       tree idecl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (current));
3648       if (idecl && CLASS_LOADED_P (TREE_TYPE (idecl)))
3649         {
3650           if (!parser_check_super_interface (idecl, decl, current))
3651             parser_add_interface (decl, idecl, current);
3652         }
3653       else
3654         register_incomplete_type (JDEP_INTERFACE,
3655                                   current, decl, NULL_TREE);
3656     }
3657 }
3658
3659 /* Create an interface in pass1 and return its decl. Return the
3660    interface's decl in pass 2.  */
3661
3662 static tree
3663 create_interface (flags, id, super)
3664      int flags;
3665      tree id, super;
3666 {
3667   tree raw_name = EXPR_WFL_NODE (id);
3668   tree q_name = parser_qualified_classname (raw_name);
3669   tree decl = IDENTIFIER_CLASS_VALUE (q_name);
3670
3671   EXPR_WFL_NODE (id) = q_name;  /* Keep source location, even if refined. */
3672
3673   /* Basic checks: scope, redefinition, modifiers */ 
3674   if (check_class_interface_creation (1, flags, raw_name, q_name, decl, id))
3675     {
3676       PUSH_ERROR ();
3677       return NULL_TREE;
3678     }
3679
3680   /* Suspend the current parsing context if we're parsing an inner
3681      interface */
3682   if (CPC_INNER_P ())
3683     java_parser_context_suspend ();
3684
3685   /* Push a new context for (static) initialized upon declaration fields */
3686   java_parser_context_push_initialized_field ();
3687
3688   /* Interface modifiers check
3689        - public/abstract allowed (already done at that point)
3690        - abstract is obsolete (comes first, it's a warning, or should be)
3691        - Can't use twice the same (checked in the modifier rule) */
3692   if ((flags & ACC_ABSTRACT) && flag_redundant)
3693     parse_warning_context 
3694       (MODIFIER_WFL (ABSTRACT_TK),
3695        "Redundant use of `abstract' modifier. Interface `%s' is implicitely abstract", IDENTIFIER_POINTER (raw_name));
3696
3697   /* Create a new decl if DECL is NULL, otherwise fix it */
3698   decl = maybe_create_class_interface_decl (decl, raw_name, q_name, id);
3699
3700   /* Set super info and mark the class a complete */
3701   set_super_info (ACC_INTERFACE | flags, TREE_TYPE (decl), 
3702                   object_type_node, ctxp->interface_number);
3703   ctxp->interface_number = 0;
3704   CLASS_COMPLETE_P (decl) = 1;
3705   add_superinterfaces (decl, super);
3706
3707   return decl;
3708 }
3709
3710 /* Anonymous class counter. Will be reset to 1 every time a non
3711    anonymous class gets created. */
3712 static int anonymous_class_counter = 1;
3713
3714 /* Patch anonymous class CLASS, by either extending or implementing
3715    DEP.  */
3716
3717 static void
3718 patch_anonymous_class (type_decl, class_decl, wfl)
3719     tree type_decl, class_decl, wfl;
3720 {
3721   tree class = TREE_TYPE (class_decl);
3722   tree type =  TREE_TYPE (type_decl);
3723   tree binfo = TYPE_BINFO (class);
3724
3725   /* If it's an interface, implement it */
3726   if (CLASS_INTERFACE (type_decl))
3727     {
3728       tree s_binfo;
3729       int length;
3730
3731       if (parser_check_super_interface (type_decl, class_decl, wfl))
3732         return;
3733
3734       s_binfo = TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (class)), 0);
3735       length = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (class))+1;
3736       TYPE_BINFO_BASETYPES (class) = make_tree_vec (length);
3737       TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (class)), 0) = s_binfo;
3738       /* And add the interface */
3739       parser_add_interface (class_decl, type_decl, wfl);
3740     }
3741   /* Otherwise, it's a type we want to extend */
3742   else
3743     {
3744       if (parser_check_super (type_decl, class_decl, wfl))
3745         return;
3746       BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo), 0)) = type;
3747     }
3748 }
3749
3750 static tree
3751 create_anonymous_class (location, type_name)
3752     int location;
3753     tree type_name;
3754 {
3755   char buffer [80];
3756   tree super = NULL_TREE, itf = NULL_TREE;
3757   tree id, type_decl, class;
3758
3759   /* The unqualified name of the anonymous class. It's just a number. */
3760   sprintf (buffer, "%d", anonymous_class_counter++);
3761   id = build_wfl_node (get_identifier (buffer));
3762   EXPR_WFL_LINECOL (id) = location;
3763
3764   /* We know about the type to extend/implement. We go ahead */
3765   if ((type_decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (type_name))))
3766     {
3767       /* Create a class which either implements on extends the designated
3768          class. The class bears an innacessible name. */
3769       if (CLASS_INTERFACE (type_decl))
3770         {
3771           /* It's OK to modify it here. It's been already used and
3772              shouldn't be reused */
3773           ctxp->interface_number = 1;
3774           /* Interfaces should presented as a list of WFLs */
3775           itf = build_tree_list (type_name, NULL_TREE);
3776         }
3777       else
3778         super = type_name;
3779     }
3780
3781   class = create_class (ACC_FINAL, id, super, itf);
3782
3783   /* We didn't know anything about the stuff. We register a dependence. */
3784   if (!type_decl)
3785     register_incomplete_type (JDEP_ANONYMOUS, type_name, class, NULL_TREE);
3786
3787   ANONYMOUS_CLASS_P (TREE_TYPE (class)) = 1;
3788   return class;
3789 }
3790
3791 /* Create a class in pass1 and return its decl. Return class
3792    interface's decl in pass 2.  */
3793
3794 static tree
3795 create_class (flags, id, super, interfaces)
3796      int flags;
3797      tree id, super, interfaces;
3798 {
3799   tree raw_name = EXPR_WFL_NODE (id);
3800   tree class_id, decl;
3801   tree super_decl_type;
3802
3803   class_id = parser_qualified_classname (raw_name);
3804   decl = IDENTIFIER_CLASS_VALUE (class_id);
3805   EXPR_WFL_NODE (id) = class_id;
3806
3807   /* Basic check: scope, redefinition, modifiers */
3808   if (check_class_interface_creation (0, flags, raw_name, class_id, decl, id))
3809     {
3810       PUSH_ERROR ();
3811       return NULL_TREE;
3812     }
3813   
3814   /* Suspend the current parsing context if we're parsing an inner
3815      class or an anonymous class. */
3816   if (CPC_INNER_P ())
3817     java_parser_context_suspend ();
3818   /* Push a new context for (static) initialized upon declaration fields */
3819   java_parser_context_push_initialized_field ();
3820
3821   /* Class modifier check: 
3822        - Allowed modifier (already done at that point)
3823        - abstract AND final forbidden 
3824        - Public classes defined in the correct file */
3825   if ((flags & ACC_ABSTRACT) && (flags & ACC_FINAL))
3826     parse_error_context
3827       (id, "Class `%s' can't be declared both abstract and final",
3828        IDENTIFIER_POINTER (raw_name));
3829
3830   /* Create a new decl if DECL is NULL, otherwise fix it */
3831   decl = maybe_create_class_interface_decl (decl, raw_name, class_id, id);
3832
3833   /* If SUPER exists, use it, otherwise use Object */
3834   if (super)
3835     {
3836       /* Can't extend java.lang.Object */
3837       if (TREE_TYPE (IDENTIFIER_CLASS_VALUE (class_id)) == object_type_node)
3838         {
3839           parse_error_context (id, "Can't extend `java.lang.Object'");
3840           return NULL_TREE;
3841         }
3842
3843       super_decl_type = 
3844         register_incomplete_type (JDEP_SUPER, super, decl, NULL_TREE);
3845     }
3846   else if (TREE_TYPE (decl) != object_type_node)
3847     super_decl_type = object_type_node;
3848   /* We're defining java.lang.Object */
3849   else
3850     super_decl_type = NULL_TREE;
3851
3852   /* Set super info and mark the class a complete */
3853   set_super_info (flags, TREE_TYPE (decl), super_decl_type, 
3854                   ctxp->interface_number);
3855   ctxp->interface_number = 0;
3856   CLASS_COMPLETE_P (decl) = 1;
3857   add_superinterfaces (decl, interfaces);
3858
3859   /* Add the private this$<n> field, Replicate final locals still in
3860      scope as private final fields mangled like val$<local_name>.
3861      This doesn't not occur for top level (static) inner classes. */
3862   if (PURE_INNER_CLASS_DECL_P (decl))
3863     add_inner_class_fields (decl, current_function_decl);
3864
3865   /* If doing xref, store the location at which the inherited class
3866      (if any) was seen. */
3867   if (flag_emit_xref && super)
3868     DECL_INHERITED_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (super);
3869
3870   /* Eventually sets the @deprecated tag flag */
3871   CHECK_DEPRECATED (decl);
3872
3873   /* Reset the anonymous class counter when declaring non inner classes */
3874   if (!INNER_CLASS_DECL_P (decl))
3875     anonymous_class_counter = 1;
3876
3877   return decl;
3878 }
3879
3880 /* End a class declaration: register the statements used to create
3881    $finit$ and <clinit>, pop the current class and resume the prior
3882    parser context if necessary.  */
3883
3884 static void
3885 end_class_declaration (resume)
3886      int resume;
3887 {
3888   /* If an error occured, context weren't pushed and won't need to be
3889      popped by a resume. */
3890   int no_error_occured = ctxp->next && GET_CPC () != error_mark_node;
3891
3892   java_parser_context_pop_initialized_field ();
3893   POP_CPC ();
3894   if (resume && no_error_occured)
3895     java_parser_context_resume ();
3896
3897   /* We're ending a class declaration, this is a good time to reset
3898      the interface cout. Note that might have been already done in
3899      create_interface, but if at that time an inner class was being
3900      dealt with, the interface count was reset in a context created
3901      for the sake of handling inner classes declaration. */
3902   ctxp->interface_number = 0;
3903 }
3904
3905 static void
3906 add_inner_class_fields (class_decl, fct_decl)
3907      tree class_decl;
3908      tree fct_decl;
3909 {
3910   tree block, marker, f;
3911
3912   f = add_field (TREE_TYPE (class_decl),
3913                  build_current_thisn (TREE_TYPE (class_decl)),
3914                  build_pointer_type (TREE_TYPE (DECL_CONTEXT (class_decl))), 
3915                  ACC_PRIVATE);
3916   FIELD_THISN (f) = 1;
3917
3918   if (!fct_decl)
3919     return;
3920     
3921   for (block = GET_CURRENT_BLOCK (fct_decl); 
3922        block && TREE_CODE (block) == BLOCK; block = BLOCK_SUPERCONTEXT (block))
3923     {
3924       tree decl;
3925       for (decl = BLOCK_EXPR_DECLS (block); decl; decl = TREE_CHAIN (decl))
3926         {
3927           char *name, *pname;
3928           tree wfl, init, list;
3929           
3930           /* Avoid non final arguments. */
3931           if (!LOCAL_FINAL (decl))
3932             continue;
3933           
3934           MANGLE_OUTER_LOCAL_VARIABLE_NAME (name, DECL_NAME (decl));
3935           MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_ID (pname, DECL_NAME (decl));
3936           wfl = build_wfl_node (get_identifier (name));
3937           init = build_wfl_node (get_identifier (pname));
3938           /* Build an initialization for the field: it will be
3939              initialized by a parameter added to $finit$, bearing a
3940              mangled name of the field itself (param$<n>.) The
3941              parameter is provided to $finit$ by the constructor
3942              invoking it (hence the constructor will also feature a
3943              hidden parameter, set to the value of the outer context
3944              local at the time the inner class is created.)
3945              
3946              Note: we take into account all possible locals that can
3947              be accessed by the inner class. It's actually not trivial
3948              to minimize these aliases down to the ones really
3949              used. One way to do that would be to expand all regular
3950              methods first, then $finit$ to get a picture of what's
3951              used.  It works with the exception that we would have to
3952              go back on all constructor invoked in regular methods to
3953              have their invokation reworked (to include the right amount
3954              of alias initializer parameters.)
3955
3956              The only real way around, I think, is a first pass to
3957              identify locals really used in the inner class. We leave
3958              the flag FIELD_LOCAL_ALIAS_USED around for that future
3959              use.
3960              
3961              On the other hand, it only affect local inner classes,
3962              whose constructors (and $finit$ call) will be featuring
3963              unecessary arguments. It's easy for a developper to keep
3964              this number of parameter down by using the `final'
3965              keyword only when necessary. For the time being, we can
3966              issue a warning on unecessary finals. FIXME */
3967           init = build_assignment (ASSIGN_TK, EXPR_WFL_LINECOL (wfl), 
3968                                    wfl, init);
3969
3970           /* Register the field. The TREE_LIST holding the part
3971              initialized/initializer will be marked ARG_FINAL_P so
3972              that the created field can be marked
3973              FIELD_LOCAL_ALIAS. */
3974           list = build_tree_list (wfl, init);
3975           ARG_FINAL_P (list) = 1;
3976           register_fields (ACC_PRIVATE | ACC_FINAL, TREE_TYPE (decl), list);
3977         }
3978     }
3979
3980   if (!CPC_INITIALIZER_STMT (ctxp))
3981     return;
3982
3983   /* If we ever registered an alias field, insert and marker to
3984      remeber where the list ends. The second part of the list (the one
3985      featuring initialized fields) so it can be later reversed to
3986      enforce 8.5. The marker will be removed during that operation. */
3987   marker = build_tree_list (NULL_TREE, NULL_TREE);
3988   TREE_CHAIN (marker) = CPC_INITIALIZER_STMT (ctxp);
3989   SET_CPC_INITIALIZER_STMT (ctxp, marker);
3990 }
3991
3992 /* Can't use lookup_field () since we don't want to load the class and
3993    can't set the CLASS_LOADED_P flag */
3994
3995 static tree
3996 find_field (class, name)
3997      tree class;
3998      tree name;
3999 {
4000   tree decl;
4001   for (decl = TYPE_FIELDS (class); decl; decl = TREE_CHAIN (decl))
4002     {
4003       if (DECL_NAME (decl) == name)
4004         return decl;
4005     }
4006   return NULL_TREE;
4007 }
4008
4009 /* Wrap around lookup_field that doesn't potentially upset the value
4010    of CLASS */
4011
4012 static tree
4013 lookup_field_wrapper (class, name)
4014      tree class, name;
4015 {
4016   tree type = class;
4017   tree decl = NULL_TREE;
4018   java_parser_context_save_global ();
4019
4020   /* Last chance: if we're within the context of an inner class, we
4021      might be trying to access a local variable defined in an outer
4022      context. We try to look for it now. */
4023   if (INNER_CLASS_TYPE_P (class))
4024     {
4025       char *alias_buffer;
4026       tree new_name;
4027       MANGLE_OUTER_LOCAL_VARIABLE_NAME (alias_buffer, name);
4028       new_name = get_identifier (alias_buffer);
4029       decl = lookup_field (&type, new_name);
4030       if (decl && decl != error_mark_node)
4031         FIELD_LOCAL_ALIAS_USED (decl) = 1;
4032     }
4033   if (!decl || decl == error_mark_node)
4034     {
4035       type = class;
4036       decl = lookup_field (&type, name);
4037     }
4038
4039   java_parser_context_restore_global ();
4040   return decl == error_mark_node ? NULL : decl;
4041 }
4042
4043 /* Find duplicate field within the same class declarations and report
4044    the error. Returns 1 if a duplicated field was found, 0
4045    otherwise.  */
4046
4047 static int
4048 duplicate_declaration_error_p (new_field_name, new_type, cl)
4049      tree new_field_name, new_type, cl;
4050 {
4051   /* This might be modified to work with method decl as well */
4052   tree decl = find_field (TREE_TYPE (GET_CPC ()), new_field_name);
4053   if (decl)
4054     {
4055       char *t1 = xstrdup (purify_type_name
4056                          ((TREE_CODE (new_type) == POINTER_TYPE 
4057                            && TREE_TYPE (new_type) == NULL_TREE) ?
4058                           IDENTIFIER_POINTER (TYPE_NAME (new_type)) :
4059                           lang_printable_name (new_type, 1)));
4060       /* The type may not have been completed by the time we report
4061          the error */
4062       char *t2 = xstrdup (purify_type_name
4063                          ((TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE 
4064                            && TREE_TYPE (TREE_TYPE (decl)) == NULL_TREE) ?
4065                           IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl))) :
4066                           lang_printable_name (TREE_TYPE (decl), 1)));
4067       parse_error_context 
4068         (cl , "Duplicate variable declaration: `%s %s' was `%s %s' (%s:%d)", 
4069          t1, IDENTIFIER_POINTER (new_field_name),
4070          t2, IDENTIFIER_POINTER (DECL_NAME (decl)),
4071          DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
4072       free (t1);
4073       free (t2);
4074       return 1;
4075     }
4076   return 0;
4077 }
4078
4079 /* Field registration routine. If TYPE doesn't exist, field
4080    declarations are linked to the undefined TYPE dependency list, to
4081    be later resolved in java_complete_class () */
4082
4083 static void
4084 register_fields (flags, type, variable_list)
4085      int flags;
4086      tree type, variable_list;
4087 {
4088   tree current, saved_type;
4089   tree class_type = NULL_TREE;
4090   int saved_lineno = lineno;
4091   int must_chain = 0;
4092   tree wfl = NULL_TREE;
4093
4094   if (GET_CPC ())
4095     class_type = TREE_TYPE (GET_CPC ());
4096
4097   if (!class_type || class_type == error_mark_node)
4098     return;
4099
4100   /* If we're adding fields to interfaces, those fields are public,
4101      static, final */
4102   if (CLASS_INTERFACE (TYPE_NAME (class_type)))
4103     {
4104       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (PUBLIC_TK),
4105                                  flags, ACC_PUBLIC, "interface field(s)");
4106       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (STATIC_TK),
4107                                  flags, ACC_STATIC, "interface field(s)");
4108       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (FINAL_TK),
4109                                  flags, ACC_FINAL, "interface field(s)");
4110       check_modifiers ("Illegal interface member modifier `%s'", flags,
4111                        INTERFACE_FIELD_MODIFIERS);
4112       flags |= (ACC_PUBLIC | ACC_STATIC | ACC_FINAL);
4113     }
4114
4115   /* Obtain a suitable type for resolution, if necessary */
4116   SET_TYPE_FOR_RESOLUTION (type, wfl, must_chain);
4117
4118   /* If TYPE is fully resolved and we don't have a reference, make one */
4119   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4120
4121   for (current = variable_list, saved_type = type; current; 
4122        current = TREE_CHAIN (current), type = saved_type)
4123     {
4124       tree real_type;
4125       tree field_decl;
4126       tree cl = TREE_PURPOSE (current);
4127       tree init = TREE_VALUE (current);
4128       tree current_name = EXPR_WFL_NODE (cl);
4129
4130       /* Can't declare non-final static fields in inner classes */
4131       if ((flags & ACC_STATIC) && !TOPLEVEL_CLASS_TYPE_P (class_type)
4132           && !(flags & ACC_FINAL))
4133         parse_error_context 
4134           (cl, "Field `%s' can't be static in inner class `%s' unless it is final",
4135            IDENTIFIER_POINTER (EXPR_WFL_NODE (cl)),
4136            lang_printable_name (class_type, 0));
4137
4138       /* Process NAME, as it may specify extra dimension(s) for it */
4139       type = build_array_from_name (type, wfl, current_name, &current_name);
4140
4141       /* Type adjustment. We may have just readjusted TYPE because
4142          the variable specified more dimensions. Make sure we have
4143          a reference if we can and don't have one already. Also
4144          change the name if we have an init. */
4145       if (type != saved_type)
4146         {
4147           PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4148           if (init)
4149             EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = current_name;
4150         }
4151
4152       real_type = GET_REAL_TYPE (type);
4153       /* Check for redeclarations */
4154       if (duplicate_declaration_error_p (current_name, real_type, cl))
4155         continue;
4156
4157       /* Set lineno to the line the field was found and create a
4158          declaration for it. Eventually sets the @deprecated tag flag. */
4159       if (flag_emit_xref)
4160         lineno = EXPR_WFL_LINECOL (cl);
4161       else
4162         lineno = EXPR_WFL_LINENO (cl);
4163       field_decl = add_field (class_type, current_name, real_type, flags);
4164       CHECK_DEPRECATED (field_decl);
4165
4166       /* If the couple initializer/initialized is marked ARG_FINAL_P, we
4167          mark the created field FIELD_LOCAL_ALIAS, so that we can 
4168          hide parameters to this inner class $finit$ and constructors. */
4169       if (ARG_FINAL_P (current))
4170         FIELD_LOCAL_ALIAS (field_decl) = 1;
4171       
4172       /* Check if we must chain. */
4173       if (must_chain)
4174         register_incomplete_type (JDEP_FIELD, wfl, field_decl, type);
4175           
4176       /* If we have an initialization value tied to the field */
4177       if (init)
4178         {
4179           /* The field is declared static */
4180           if (flags & ACC_STATIC)
4181             {
4182               /* We include the field and its initialization part into
4183                  a list used to generate <clinit>. After <clinit> is
4184                  walked, field initializations will be processed and
4185                  fields initialized with known constants will be taken
4186                  out of <clinit> and have their DECL_INITIAL set
4187                  appropriately. */
4188               TREE_CHAIN (init) = CPC_STATIC_INITIALIZER_STMT (ctxp);
4189               SET_CPC_STATIC_INITIALIZER_STMT (ctxp, init);
4190               if (TREE_OPERAND (init, 1) 
4191                   && TREE_CODE (TREE_OPERAND (init, 1)) == NEW_ARRAY_INIT)
4192                 TREE_STATIC (TREE_OPERAND (init, 1)) = 1;
4193             }
4194           /* A non-static field declared with an immediate initialization is
4195              to be initialized in <init>, if any.  This field is remembered
4196              to be processed at the time of the generation of <init>. */
4197           else
4198             {
4199               TREE_CHAIN (init) = CPC_INITIALIZER_STMT (ctxp);
4200               SET_CPC_INITIALIZER_STMT (ctxp, init);
4201             }
4202           MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
4203           DECL_INITIAL (field_decl) = TREE_OPERAND (init, 1);
4204         }
4205     }
4206   lineno = saved_lineno;
4207 }
4208
4209 /* Generate $finit$, using the list of initialized fields to populate
4210    its body. $finit$'s parameter(s) list is adjusted to include the
4211    one(s) used to initialized the field(s) caching outer context
4212    local(s). */
4213
4214 static tree
4215 generate_finit (class_type)
4216      tree class_type;
4217 {
4218   int count = 0;
4219   tree list = TYPE_FINIT_STMT_LIST (class_type);
4220   tree mdecl, current, parms;
4221
4222   parms = build_alias_initializer_parameter_list (AIPL_FUNCTION_CREATION, 
4223                                                   class_type, NULL_TREE, 
4224                                                   &count);
4225   CRAFTED_PARAM_LIST_FIXUP (parms);
4226   mdecl = create_artificial_method (class_type, ACC_PRIVATE, void_type_node,
4227                                     finit_identifier_node, parms);
4228   fix_method_argument_names (parms, mdecl);
4229   layout_class_method (class_type, CLASSTYPE_SUPER (class_type),
4230                        mdecl, NULL_TREE);
4231   DECL_FUNCTION_NAP (mdecl) = count;
4232   start_artificial_method_body (mdecl);
4233
4234   for (current = list; current; current = TREE_CHAIN (current))
4235     java_method_add_stmt (mdecl, 
4236                           build_debugable_stmt (EXPR_WFL_LINECOL (current), 
4237                                                 current));
4238   end_artificial_method_body (mdecl);
4239   return mdecl;
4240 }
4241
4242 static void
4243 add_instance_initializer (mdecl)
4244      tree mdecl;
4245 {
4246   tree current;
4247   tree stmt_list = TYPE_II_STMT_LIST (DECL_CONTEXT (mdecl));
4248   tree compound = NULL_TREE;
4249
4250   if (stmt_list)
4251     {
4252       for (current = stmt_list; current; current = TREE_CHAIN (current))
4253         compound = add_stmt_to_compound (compound, NULL_TREE, current);
4254
4255       java_method_add_stmt (mdecl, build1 (INSTANCE_INITIALIZERS_EXPR,
4256                                            NULL_TREE, compound));
4257     }
4258 }
4259
4260 /* Shared accros method_declarator and method_header to remember the
4261    patch stage that was reached during the declaration of the method.
4262    A method DECL is built differently is there is no patch
4263    (JDEP_NO_PATCH) or a patch (JDEP_METHOD or JDEP_METHOD_RETURN)
4264    pending on the currently defined method.  */
4265
4266 static int patch_stage;
4267
4268 /* Check the method declaration and add the method to its current
4269    class.  If the argument list is known to contain incomplete types,
4270    the method is partially added and the registration will be resume
4271    once the method arguments resolved. If TYPE is NULL, we're dealing
4272    with a constructor.  */
4273
4274 static tree
4275 method_header (flags, type, mdecl, throws)
4276      int flags;
4277      tree type, mdecl, throws;
4278 {
4279   tree meth = TREE_VALUE (mdecl);
4280   tree id = TREE_PURPOSE (mdecl);
4281   tree type_wfl = NULL_TREE;
4282   tree meth_name = NULL_TREE;
4283   tree current, orig_arg, this_class = NULL;
4284   int saved_lineno;
4285   int constructor_ok = 0, must_chain;
4286   int count;
4287   
4288   check_modifiers_consistency (flags);
4289
4290   if (GET_CPC ())
4291     this_class = TREE_TYPE (GET_CPC ());
4292
4293   if (!this_class || this_class == error_mark_node)
4294     return NULL_TREE;
4295   
4296   /* There are some forbidden modifiers for an abstract method and its
4297      class must be abstract as well.  */
4298   if (type && (flags & ACC_ABSTRACT))
4299     {
4300       ABSTRACT_CHECK (flags, ACC_PRIVATE, id, "Private");
4301       ABSTRACT_CHECK (flags, ACC_STATIC, id, "Static");
4302       ABSTRACT_CHECK (flags, ACC_FINAL, id, "Final");
4303       ABSTRACT_CHECK (flags, ACC_NATIVE, id, "Native");
4304       ABSTRACT_CHECK (flags, ACC_SYNCHRONIZED,id, "Synchronized");
4305       if (!CLASS_ABSTRACT (TYPE_NAME (this_class))
4306           && !CLASS_INTERFACE (TYPE_NAME (this_class)))
4307         parse_error_context 
4308           (id, "Class `%s' must be declared abstract to define abstract method `%s'", 
4309            IDENTIFIER_POINTER (DECL_NAME (GET_CPC ())),
4310            IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
4311     }
4312
4313   /* Things to be checked when declaring a constructor */
4314   if (!type)
4315     {
4316       int ec = java_error_count;
4317       /* 8.6: Constructor declarations: we might be trying to define a
4318          method without specifying a return type. */
4319       if (EXPR_WFL_NODE (id) != GET_CPC_UN ())
4320         parse_error_context 
4321           (id, "Invalid method declaration, return type required");
4322       /* 8.6.3: Constructor modifiers */
4323       else
4324         {
4325           JCONSTRUCTOR_CHECK (flags, ACC_ABSTRACT, id, "abstract");
4326           JCONSTRUCTOR_CHECK (flags, ACC_STATIC, id, "static");
4327           JCONSTRUCTOR_CHECK (flags, ACC_FINAL, id, "final");
4328           JCONSTRUCTOR_CHECK (flags, ACC_NATIVE, id, "native");
4329           JCONSTRUCTOR_CHECK (flags, ACC_SYNCHRONIZED, id, "synchronized");
4330         }
4331       /* If we found error here, we don't consider it's OK to tread
4332          the method definition as a constructor, for the rest of this
4333          function */
4334       if (ec == java_error_count)
4335         constructor_ok = 1;
4336     }
4337
4338   /* Method declared within the scope of an interface are implicitly
4339      abstract and public. Conflicts with other erroneously provided
4340      modifiers are checked right after. */
4341
4342   if (CLASS_INTERFACE (TYPE_NAME (this_class)))
4343     {
4344       /* If FLAGS isn't set because of a modifier, turn the
4345          corresponding modifier WFL to NULL so we issue a warning on
4346          the obsolete use of the modifier */
4347       if (!(flags & ACC_PUBLIC))
4348         MODIFIER_WFL (PUBLIC_TK) = NULL;
4349       if (!(flags & ACC_ABSTRACT))
4350         MODIFIER_WFL (ABSTRACT_TK) = NULL;
4351       flags |= ACC_PUBLIC;
4352       flags |= ACC_ABSTRACT;
4353     }
4354
4355   /* Inner class can't declare static methods */
4356   if ((flags & ACC_STATIC) && !TOPLEVEL_CLASS_TYPE_P (this_class))
4357     {
4358       parse_error_context 
4359         (id, "Method `%s' can't be static in inner class `%s'. Only members of interfaces and top-level classes can be static",
4360          IDENTIFIER_POINTER (EXPR_WFL_NODE (id)),
4361          lang_printable_name (this_class, 0));
4362     }
4363
4364   /* Modifiers context reset moved up, so abstract method declaration
4365      modifiers can be later checked.  */
4366
4367   /* Set constructor returned type to void and method name to <init>,
4368      unless we found an error identifier the constructor (in which
4369      case we retain the original name) */
4370   if (!type)
4371     {
4372       type = void_type_node;
4373       if (constructor_ok)
4374         meth_name = init_identifier_node;
4375     }
4376   else
4377     meth_name = EXPR_WFL_NODE (id);
4378
4379   /* Do the returned type resolution and registration if necessary */
4380   SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
4381
4382   if (meth_name)
4383     type = build_array_from_name (type, type_wfl, meth_name, &meth_name);
4384   EXPR_WFL_NODE (id) = meth_name;
4385   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
4386
4387   if (must_chain)
4388     {
4389       patch_stage = JDEP_METHOD_RETURN;
4390       register_incomplete_type (patch_stage, type_wfl, id, type);
4391       TREE_TYPE (meth) = GET_REAL_TYPE (type);
4392     }
4393   else
4394     TREE_TYPE (meth) = type;
4395
4396   saved_lineno = lineno;
4397   /* When defining an abstract or interface method, the curly
4398      bracket at level 1 doesn't exist because there is no function
4399      body */
4400   lineno = (ctxp->first_ccb_indent1 ? ctxp->first_ccb_indent1 : 
4401             EXPR_WFL_LINENO (id));
4402
4403   /* Remember the original argument list */
4404   orig_arg = TYPE_ARG_TYPES (meth);
4405
4406   if (patch_stage)              /* includes ret type and/or all args */
4407     {
4408       jdep *jdep;
4409       meth = add_method_1 (this_class, flags, meth_name, meth);
4410       /* Patch for the return type */
4411       if (patch_stage == JDEP_METHOD_RETURN)
4412         {
4413           jdep = CLASSD_LAST (ctxp->classd_list);
4414           JDEP_GET_PATCH (jdep) = &TREE_TYPE (TREE_TYPE (meth));
4415         }
4416       /* This is the stop JDEP. METH allows the function's signature
4417          to be computed. */
4418       register_incomplete_type (JDEP_METHOD_END, NULL_TREE, meth, NULL_TREE);
4419     }
4420   else
4421     meth = add_method (this_class, flags, meth_name, 
4422                        build_java_signature (meth));
4423
4424   /* Remember final parameters */
4425   MARK_FINAL_PARMS (meth, orig_arg);
4426
4427   /* Fix the method argument list so we have the argument name
4428      information */
4429   fix_method_argument_names (orig_arg, meth);
4430
4431   /* Register the parameter number and re-install the current line
4432      number */
4433   DECL_MAX_LOCALS (meth) = ctxp->formal_parameter_number+1;
4434   lineno = saved_lineno;
4435
4436   /* Register exception specified by the `throws' keyword for
4437      resolution and set the method decl appropriate field to the list.
4438      Note: the grammar ensures that what we get here are class
4439      types. */
4440   if (throws)
4441     {
4442       throws = nreverse (throws);
4443       for (current = throws; current; current = TREE_CHAIN (current))
4444         {
4445           register_incomplete_type (JDEP_EXCEPTION, TREE_VALUE (current),
4446                                     NULL_TREE, NULL_TREE);
4447           JDEP_GET_PATCH (CLASSD_LAST (ctxp->classd_list)) = 
4448             &TREE_VALUE (current);
4449         }
4450       DECL_FUNCTION_THROWS (meth) = throws;
4451     }
4452
4453   /* We set the DECL_NAME to ID so we can track the location where
4454      the function was declared. This allow us to report
4455      redefinition error accurately. When method are verified,
4456      DECL_NAME is reinstalled properly (using the content of the
4457      WFL node ID) (see check_method_redefinition). We don't do that
4458      when Object is being defined. Constructor <init> names will be
4459      reinstalled the same way. */
4460   if (TREE_TYPE (GET_CPC ()) != object_type_node)
4461     DECL_NAME (meth) = id;
4462
4463   /* Set the flag if we correctly processed a constructor */
4464   if (constructor_ok)
4465     {
4466       DECL_CONSTRUCTOR_P (meth) = 1;
4467       /* Compute and store the number of artificial parameters declared
4468          for this constructor */
4469       for (count = 0, current = TYPE_FIELDS (this_class); current; 
4470            current = TREE_CHAIN (current))
4471         if (FIELD_LOCAL_ALIAS (current))
4472           count++;
4473       DECL_FUNCTION_NAP (meth) = count;
4474     }
4475
4476   /* Eventually set the @deprecated tag flag */
4477   CHECK_DEPRECATED (meth);
4478
4479   /* If doing xref, store column and line number information instead
4480      of the line number only. */
4481   if (flag_emit_xref)
4482     DECL_SOURCE_LINE (meth) = EXPR_WFL_LINECOL (id);
4483
4484   return meth;
4485 }
4486
4487 static void
4488 fix_method_argument_names (orig_arg, meth)
4489     tree orig_arg, meth;
4490 {
4491   tree arg = TYPE_ARG_TYPES (TREE_TYPE (meth));
4492   if (TREE_CODE (TREE_TYPE (meth)) == METHOD_TYPE)
4493     {
4494       TREE_PURPOSE (arg) = this_identifier_node;
4495       arg = TREE_CHAIN (arg);
4496     }
4497   while (orig_arg != end_params_node)
4498     {
4499       TREE_PURPOSE (arg) = TREE_PURPOSE (orig_arg);
4500       orig_arg = TREE_CHAIN (orig_arg);
4501       arg = TREE_CHAIN (arg);
4502     }
4503 }
4504
4505 /* Complete the method declaration with METHOD_BODY.  */
4506
4507 static void
4508 finish_method_declaration (method_body)
4509      tree method_body;
4510 {
4511   int flags;
4512
4513   if (!current_function_decl)
4514     return;
4515
4516   flags = get_access_flags_from_decl (current_function_decl);
4517
4518   /* 8.4.5 Method Body */
4519   if ((flags & ACC_ABSTRACT || flags & ACC_NATIVE) && method_body)
4520     {
4521       tree wfl = DECL_NAME (current_function_decl);
4522       parse_error_context (wfl, 
4523                            "%s method `%s' can't have a body defined",
4524                            (METHOD_NATIVE (current_function_decl) ?
4525                             "Native" : "Abstract"),
4526                            IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
4527       method_body = NULL_TREE;
4528     }
4529   else if (!(flags & ACC_ABSTRACT) && !(flags & ACC_NATIVE) && !method_body)
4530     {
4531       tree wfl = DECL_NAME (current_function_decl);
4532       parse_error_context
4533         (wfl, 
4534          "Non native and non abstract method `%s' must have a body defined",
4535          IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
4536       method_body = NULL_TREE;
4537     }
4538
4539   if (flag_emit_class_files && method_body 
4540       && TREE_CODE (method_body) == NOP_EXPR 
4541       && TREE_TYPE (current_function_decl) 
4542       && TREE_TYPE (TREE_TYPE (current_function_decl)) == void_type_node)
4543     method_body = build1 (RETURN_EXPR, void_type_node, NULL);
4544
4545   BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (current_function_decl)) = method_body;
4546   maybe_absorb_scoping_blocks ();
4547   /* Exit function's body */
4548   exit_block ();
4549   /* Merge last line of the function with first line, directly in the
4550      function decl. It will be used to emit correct debug info. */
4551   if (!flag_emit_xref)
4552     DECL_SOURCE_LINE_MERGE (current_function_decl, ctxp->last_ccb_indent1);
4553
4554   /* Since function's argument's list are shared, reset the
4555      ARG_FINAL_P parameter that might have been set on some of this
4556      function parameters. */
4557   UNMARK_FINAL_PARMS (current_function_decl);
4558   
4559   /* So we don't have an irrelevant function declaration context for
4560      the next static block we'll see. */
4561   current_function_decl = NULL_TREE;
4562 }
4563
4564 /* Build a an error message for constructor circularity errors.  */
4565
4566 static char *
4567 constructor_circularity_msg (from, to)
4568      tree from, to;
4569 {
4570   static char string [4096];
4571   char *t = xstrdup (lang_printable_name (from, 0));
4572   sprintf (string, "`%s' invokes `%s'", t, lang_printable_name (to, 0));
4573   free (t);
4574   return string;
4575 }
4576
4577 /* Verify a circular call to METH. Return 1 if an error is found, 0
4578    otherwise.  */
4579
4580 static int
4581 verify_constructor_circularity (meth, current)
4582      tree meth, current;
4583 {
4584   static tree list = NULL_TREE;
4585   tree c;
4586   for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
4587     {
4588       if (TREE_VALUE (c) == meth)
4589         {
4590           char *t;
4591           if (list)
4592             {
4593               tree liste;
4594               list = nreverse (list);
4595               for (liste = list; liste; liste = TREE_CHAIN (liste))
4596                 {
4597                   parse_error_context 
4598                     (TREE_PURPOSE (TREE_PURPOSE (liste)), "%s",
4599                      constructor_circularity_msg
4600                       (TREE_VALUE (liste), TREE_VALUE (TREE_PURPOSE (liste)))); 
4601                   java_error_count--;
4602                 }
4603             }
4604           t = xstrdup (lang_printable_name (meth, 0));
4605           parse_error_context (TREE_PURPOSE (c), 
4606                                "%s: recursive invocation of constructor `%s'",
4607                                constructor_circularity_msg (current, meth), t);
4608           free (t);
4609           list = NULL_TREE;
4610           return 1;
4611         }
4612     }
4613   for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
4614     {
4615       list = tree_cons (c, current, list);
4616       if (verify_constructor_circularity (meth, TREE_VALUE (c)))
4617         return 1;
4618       list = TREE_CHAIN (list);
4619     }
4620   return 0;
4621 }
4622
4623 /* Check modifiers that can be declared but exclusively */
4624
4625 static void
4626 check_modifiers_consistency (flags)
4627      int flags;
4628 {
4629   int acc_count = 0;
4630   tree cl = NULL_TREE;
4631
4632   THIS_MODIFIER_ONLY (flags, ACC_PUBLIC, PUBLIC_TK, acc_count, cl);
4633   THIS_MODIFIER_ONLY (flags, ACC_PRIVATE, PRIVATE_TK, acc_count, cl);
4634   THIS_MODIFIER_ONLY (flags, ACC_PROTECTED, PROTECTED_TK, acc_count, cl);
4635   if (acc_count > 1)
4636     parse_error_context
4637       (cl, "Inconsistent member declaration.  At most one of `public', `private', or `protected' may be specified");
4638
4639   acc_count = 0;
4640   cl = NULL_TREE;
4641   THIS_MODIFIER_ONLY (flags, ACC_FINAL, FINAL_TK, acc_count, cl);
4642   THIS_MODIFIER_ONLY (flags, ACC_VOLATILE, VOLATILE_TK, acc_count, cl);
4643   if (acc_count > 1)
4644     parse_error_context (cl,
4645                          "Inconsistent member declaration.  At most one of `final' or `volatile' may be specified");
4646 }
4647
4648 /* Check the methode header METH for abstract specifics features */
4649
4650 static void
4651 check_abstract_method_header (meth)
4652      tree meth;
4653 {
4654   int flags = get_access_flags_from_decl (meth);
4655   /* DECL_NAME might still be a WFL node */
4656   tree name = GET_METHOD_NAME (meth);
4657
4658   OBSOLETE_MODIFIER_WARNING2 (MODIFIER_WFL (ABSTRACT_TK), flags,
4659                               ACC_ABSTRACT, "abstract method",
4660                               IDENTIFIER_POINTER (name));
4661   OBSOLETE_MODIFIER_WARNING2 (MODIFIER_WFL (PUBLIC_TK), flags, 
4662                               ACC_PUBLIC, "abstract method",
4663                               IDENTIFIER_POINTER (name));
4664
4665   check_modifiers ("Illegal modifier `%s' for interface method",
4666                   flags, INTERFACE_METHOD_MODIFIERS);
4667 }
4668
4669 /* Create a FUNCTION_TYPE node and start augmenting it with the
4670    declared function arguments. Arguments type that can't be resolved
4671    are left as they are, but the returned node is marked as containing
4672    incomplete types.  */
4673
4674 static tree
4675 method_declarator (id, list)
4676      tree id, list;
4677 {
4678   tree arg_types = NULL_TREE, current, node;
4679   tree meth = make_node (FUNCTION_TYPE);
4680   jdep *jdep;
4681
4682   patch_stage = JDEP_NO_PATCH;
4683
4684   /* If we're dealing with an inner class constructor, we hide the
4685      this$<n> decl in the name field of its parameter declaration.  We
4686      also might have to hide the outer context local alias
4687      initializers. Not done when the class is a toplevel class. */
4688   if (PURE_INNER_CLASS_DECL_P (GET_CPC ()) 
4689       && EXPR_WFL_NODE (id) == GET_CPC_UN ())
4690     {
4691       tree aliases_list, type, thisn;
4692       /* First the aliases, linked to the regular parameters */
4693       aliases_list =
4694         build_alias_initializer_parameter_list (AIPL_FUNCTION_DECLARATION, 
4695                                                 TREE_TYPE (GET_CPC ()),
4696                                                 NULL_TREE, NULL);
4697       list = chainon (nreverse (aliases_list), list);
4698
4699       /* Then this$<n> */
4700       type = TREE_TYPE (DECL_CONTEXT (GET_CPC ()));
4701       thisn = build_current_thisn (TREE_TYPE (GET_CPC ()));
4702       list = tree_cons (build_wfl_node (thisn), build_pointer_type (type),
4703                         list);
4704     }
4705   
4706   for (current = list; current; current = TREE_CHAIN (current))
4707     {
4708       int must_chain = 0;
4709       tree wfl_name = TREE_PURPOSE (current);
4710       tree type = TREE_VALUE (current);
4711       tree name = EXPR_WFL_NODE (wfl_name);
4712       tree already, arg_node;
4713       tree type_wfl = NULL_TREE;
4714       tree real_type;
4715
4716       /* Obtain a suitable type for resolution, if necessary */
4717       SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
4718
4719       /* Process NAME, as it may specify extra dimension(s) for it */
4720       type = build_array_from_name (type, type_wfl, name, &name);
4721       EXPR_WFL_NODE (wfl_name) = name;
4722
4723       real_type = GET_REAL_TYPE (type);
4724       if (TREE_CODE (real_type) == RECORD_TYPE)
4725         {
4726           real_type = promote_type (real_type);
4727           if (TREE_CODE (type) == TREE_LIST)
4728             TREE_PURPOSE (type) = real_type;
4729         }
4730
4731       /* Check redefinition */
4732       for (already = arg_types; already; already = TREE_CHAIN (already))
4733         if (TREE_PURPOSE (already) == name)
4734           {
4735             parse_error_context
4736               (wfl_name, "Variable `%s' is used more than once in the argument list of method `%s'",
4737                IDENTIFIER_POINTER (name),
4738                IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
4739             break;
4740           }
4741
4742       /* If we've an incomplete argument type, we know there is a location
4743          to patch when the type get resolved, later.  */
4744       jdep = NULL;
4745       if (must_chain)
4746         {
4747           patch_stage = JDEP_METHOD;
4748           type = register_incomplete_type (patch_stage, 
4749                                            type_wfl, wfl_name, type);
4750           jdep = CLASSD_LAST (ctxp->classd_list);
4751           JDEP_MISC (jdep) = id;
4752         }
4753
4754       /* The argument node: a name and a (possibly) incomplete type.  */
4755       arg_node = build_tree_list (name, real_type);
4756       /* Remeber arguments declared final. */
4757       ARG_FINAL_P (arg_node) = ARG_FINAL_P (current);
4758       
4759       if (jdep)
4760         JDEP_GET_PATCH (jdep) = &TREE_VALUE (arg_node);
4761       TREE_CHAIN (arg_node) = arg_types;
4762       arg_types = arg_node;
4763     }
4764   TYPE_ARG_TYPES (meth) = chainon (nreverse (arg_types), end_params_node);
4765   node = build_tree_list (id, meth);
4766   return node;
4767 }
4768
4769 static int
4770 unresolved_type_p (wfl, returned)
4771      tree wfl;
4772      tree *returned;
4773      
4774 {
4775   if (TREE_CODE (wfl) == EXPR_WITH_FILE_LOCATION)
4776     {
4777       if (returned)
4778         {
4779           tree decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (wfl));
4780           if (decl && current_class && (decl == TYPE_NAME (current_class)))
4781             *returned = TREE_TYPE (decl);
4782           else if (GET_CPC_UN () == EXPR_WFL_NODE (wfl))
4783             *returned = TREE_TYPE (GET_CPC ());
4784           else
4785             *returned = NULL_TREE;
4786         }
4787       return 1;
4788     }
4789   if (returned)
4790     *returned = wfl;
4791   return 0;
4792 }
4793
4794 /* From NAME, build a qualified identifier node using the
4795    qualification from the current package definition. */
4796
4797 static tree
4798 parser_qualified_classname (name)
4799      tree name;
4800 {
4801   tree nested_class_name;
4802
4803   if ((nested_class_name = maybe_make_nested_class_name (name)))
4804     return nested_class_name;
4805
4806   if (ctxp->package)
4807     return merge_qualified_name (ctxp->package, name);
4808   else 
4809     return name;
4810 }
4811
4812 /* Called once the type a interface extends is resolved. Returns 0 if
4813    everything is OK.  */
4814
4815 static int
4816 parser_check_super_interface (super_decl, this_decl, this_wfl)
4817      tree super_decl, this_decl, this_wfl;
4818 {
4819   tree super_type = TREE_TYPE (super_decl);
4820
4821   /* Has to be an interface */
4822   if (!CLASS_INTERFACE (super_decl))
4823     {
4824       parse_error_context 
4825         (this_wfl, "Can't use %s `%s' to implement/extend %s `%s'",
4826          (TYPE_ARRAY_P (super_type) ? "array" : "class"),
4827          IDENTIFIER_POINTER (DECL_NAME (super_decl)),
4828          (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (this_decl))) ? 
4829           "interface" : "class"),
4830          IDENTIFIER_POINTER (DECL_NAME (this_decl)));
4831       return 1;
4832     }
4833
4834   /* Check scope: same package OK, other package: OK if public */
4835   if (check_pkg_class_access (DECL_NAME (super_decl), lookup_cl (this_decl)))
4836     return 1;
4837
4838   SOURCE_FRONTEND_DEBUG (("Completing interface %s with %s",
4839                           IDENTIFIER_POINTER (DECL_NAME (this_decl)),
4840                           IDENTIFIER_POINTER (DECL_NAME (super_decl))));
4841   return 0;
4842 }
4843
4844 /* Makes sure that SUPER_DECL is suitable to extend THIS_DECL. Returns
4845    0 if everthing is OK.  */
4846
4847 static int
4848 parser_check_super (super_decl, this_decl, wfl)
4849      tree super_decl, this_decl, wfl;
4850 {
4851   tree super_type = TREE_TYPE (super_decl);
4852
4853   /* SUPER should be a CLASS (neither an array nor an interface) */
4854   if (TYPE_ARRAY_P (super_type) || CLASS_INTERFACE (TYPE_NAME (super_type)))
4855     {
4856       parse_error_context 
4857         (wfl, "Class `%s' can't subclass %s `%s'",
4858          IDENTIFIER_POINTER (DECL_NAME (this_decl)),
4859          (CLASS_INTERFACE (TYPE_NAME (super_type)) ? "interface" : "array"),
4860          IDENTIFIER_POINTER (DECL_NAME (super_decl)));
4861       return 1;
4862     }
4863
4864   if (CLASS_FINAL (TYPE_NAME (super_type)))
4865     {
4866       parse_error_context (wfl, "Can't subclass final classes: %s",
4867                            IDENTIFIER_POINTER (DECL_NAME (super_decl)));
4868       return 1;
4869     }
4870
4871   /* Check scope: same package OK, other package: OK if public */
4872   if (check_pkg_class_access (DECL_NAME (super_decl), wfl))
4873     return 1;
4874   
4875   SOURCE_FRONTEND_DEBUG (("Completing class %s with %s",
4876                           IDENTIFIER_POINTER (DECL_NAME (this_decl)),
4877                           IDENTIFIER_POINTER (DECL_NAME (super_decl))));
4878   return 0;
4879 }
4880
4881 /* Create a new dependency list and link it (in a LIFO manner) to the
4882    CTXP list of type dependency list.  */
4883
4884 static void
4885 create_jdep_list (ctxp)
4886      struct parser_ctxt *ctxp;
4887 {
4888   jdeplist *new = (jdeplist *)xmalloc (sizeof (jdeplist));      
4889   new->first = new->last = NULL;
4890   new->next = ctxp->classd_list;
4891   ctxp->classd_list = new;
4892 }
4893
4894 static jdeplist *
4895 reverse_jdep_list (ctxp)
4896      struct parser_ctxt *ctxp;
4897 {
4898   register jdeplist *prev = NULL, *current, *next;
4899   for (current = ctxp->classd_list; current; current = next)
4900     {
4901       next = current->next;
4902       current->next = prev;
4903       prev = current;
4904     }
4905   return prev;
4906 }
4907
4908 /* Create a fake pointer based on the ID stored in
4909    TYPE_NAME. TYPE_NAME can be a WFL or a incomplete type asking to be
4910    registered again. */
4911
4912 static tree
4913 obtain_incomplete_type (type_name)
4914      tree type_name;
4915 {
4916   tree ptr, name;
4917
4918   if (TREE_CODE (type_name) == EXPR_WITH_FILE_LOCATION)
4919     name = EXPR_WFL_NODE (type_name);
4920   else if (INCOMPLETE_TYPE_P (type_name))
4921     name = TYPE_NAME (type_name);
4922   else
4923     fatal ("invalid type name - obtain_incomplete_type");
4924
4925   for (ptr = ctxp->incomplete_class; ptr; ptr = TREE_CHAIN (ptr))
4926     if (TYPE_NAME (ptr) == name)
4927       break;
4928
4929   if (!ptr)
4930     {
4931       push_obstacks (&permanent_obstack, &permanent_obstack);
4932       BUILD_PTR_FROM_NAME (ptr, name);
4933       layout_type (ptr);
4934       pop_obstacks ();
4935       TREE_CHAIN (ptr) = ctxp->incomplete_class;
4936       ctxp->incomplete_class = ptr;
4937     }
4938
4939   return ptr;
4940 }
4941
4942 /* Register a incomplete type whose name is WFL. Reuse PTR if PTR is
4943    non NULL instead of computing a new fake type based on WFL. The new
4944    dependency is inserted in the current type dependency list, in FIFO
4945    manner.  */
4946
4947 static tree
4948 register_incomplete_type (kind, wfl, decl, ptr)
4949      int kind;
4950      tree wfl, decl, ptr;
4951 {
4952   jdep *new = (jdep *)xmalloc (sizeof (jdep));
4953
4954   if (!ptr && kind != JDEP_METHOD_END) /* JDEP_METHOD_END is a mere marker */
4955     ptr = obtain_incomplete_type (wfl);
4956
4957   JDEP_KIND (new) = kind;
4958   JDEP_DECL (new) = decl;
4959   JDEP_SOLV (new) = ptr;
4960   JDEP_WFL (new) = wfl;
4961   JDEP_CHAIN (new) = NULL;
4962   JDEP_MISC (new) = NULL_TREE;
4963   /* For some dependencies, set the enclosing class of the current
4964      class to be the enclosing context */
4965   if ((kind == JDEP_SUPER || kind == JDEP_INTERFACE || kind == JDEP_ANONYMOUS)
4966       && GET_ENCLOSING_CPC ())
4967     JDEP_ENCLOSING (new) = TREE_VALUE (GET_ENCLOSING_CPC ());
4968   else
4969     JDEP_ENCLOSING (new) = GET_CPC ();
4970   JDEP_GET_PATCH (new) = (tree *)NULL;
4971
4972   JDEP_INSERT (ctxp->classd_list, new);
4973
4974   return ptr;
4975 }
4976
4977 void
4978 java_check_circular_reference ()
4979 {
4980   tree current;
4981   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
4982     {
4983       tree type = TREE_TYPE (current);
4984       if (CLASS_INTERFACE (current))
4985         {
4986           /* Check all interfaces this class extends */
4987           tree basetype_vec = TYPE_BINFO_BASETYPES (type);
4988           int n, i;
4989
4990           if (!basetype_vec)
4991             return;
4992           n = TREE_VEC_LENGTH (basetype_vec);
4993           for (i = 0; i < n; i++)
4994             {
4995               tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
4996               if (vec_elt && BINFO_TYPE (vec_elt) != object_type_node 
4997                   && interface_of_p (type, BINFO_TYPE (vec_elt)))
4998                 parse_error_context (lookup_cl (current),
4999                                      "Cyclic interface inheritance");
5000             }
5001         }
5002       else
5003         if (inherits_from_p (CLASSTYPE_SUPER (type), type))
5004           parse_error_context (lookup_cl (current), 
5005                                "Cyclic class inheritance%s",
5006                                (cyclic_inheritance_report ?
5007                                 cyclic_inheritance_report : ""));
5008     }
5009 }
5010
5011 /* Augment the parameter list PARM with parameters crafted to
5012    initialize outer context locals aliases. Through ARTIFICIAL, a
5013    count is kept of the number of crafted parameters. MODE governs
5014    what eventually gets created: something suitable for a function
5015    creation or a function invocation, either the constructor or
5016    $finit$.  */
5017
5018 static tree
5019 build_alias_initializer_parameter_list (mode, class_type, parm, artificial)
5020     int mode;
5021     tree class_type, parm;
5022     int *artificial;
5023 {
5024   tree field;
5025   for (field = TYPE_FIELDS (class_type); field; field = TREE_CHAIN (field))
5026     if (FIELD_LOCAL_ALIAS (field))
5027       {
5028         char *buffer = IDENTIFIER_POINTER (DECL_NAME (field));
5029         tree purpose = NULL_TREE, value = NULL_TREE, name = NULL_TREE;
5030
5031         switch (mode)
5032           {
5033           case AIPL_FUNCTION_DECLARATION:
5034             MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (buffer, &buffer [4]);
5035             purpose = build_wfl_node (get_identifier (buffer));
5036             if (TREE_CODE (TREE_TYPE (field)) == POINTER_TYPE)
5037               value = build_wfl_node (TYPE_NAME (TREE_TYPE (field)));
5038             else
5039               value = TREE_TYPE (field);
5040             break;
5041
5042           case AIPL_FUNCTION_CREATION:
5043             MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (buffer, &buffer [4]);
5044             purpose = get_identifier (buffer);
5045             value = TREE_TYPE (field);
5046             break;
5047
5048           case AIPL_FUNCTION_FINIT_INVOCATION:
5049             MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (buffer, &buffer [4]);
5050             /* Now, this is wrong. purpose should always be the NAME
5051                of something and value its matching value (decl, type,
5052                etc...) FIXME -- but there is a lot to fix. */
5053
5054             /* When invoked for this kind of operation, we already
5055                know whether a field is used or not. */
5056             purpose = TREE_TYPE (field);
5057             value = build_wfl_node (get_identifier (buffer));
5058             break;
5059
5060           case AIPL_FUNCTION_CTOR_INVOCATION:
5061             /* There are two case: the constructor invokation happends
5062                outside the local inner, in which case, locales from the outer
5063                context are directly used.
5064
5065                Otherwise, we fold to using the alias directly. */
5066             if (class_type == current_class)
5067               value = field;
5068             else
5069               {
5070                 name = get_identifier (&buffer[4]);
5071                 value = IDENTIFIER_LOCAL_VALUE (name);
5072               }
5073             break;
5074           }
5075         parm = tree_cons (purpose, value, parm);
5076         if (artificial)
5077           *artificial +=1;
5078       }
5079   return parm;
5080 }
5081
5082 /* Craft a constructor for CLASS_DECL -- what we should do when none
5083    where found. ARGS is non NULL when a special signature must be
5084    enforced. This is the case for anonymous classes.  */
5085
5086 static void
5087 craft_constructor (class_decl, args)
5088      tree class_decl, args;
5089 {
5090   tree class_type = TREE_TYPE (class_decl);
5091   tree parm = NULL_TREE;
5092   int flags = (get_access_flags_from_decl (class_decl) & ACC_PUBLIC ?
5093                ACC_PUBLIC : 0);
5094   int i = 0, artificial = 0;
5095   tree decl, ctor_name;
5096   char buffer [80];
5097   
5098   push_obstacks (&permanent_obstack, &permanent_obstack);
5099
5100   /* The constructor name is <init> unless we're dealing with an
5101      anonymous class, in which case the name will be fixed after having
5102      be expanded. */
5103   if (ANONYMOUS_CLASS_P (class_type))
5104     ctor_name = DECL_NAME (class_decl);
5105   else
5106     ctor_name = init_identifier_node;
5107
5108   /* If we're dealing with an inner class constructor, we hide the
5109      this$<n> decl in the name field of its parameter declaration. */
5110   if (PURE_INNER_CLASS_TYPE_P (class_type))
5111     {
5112       tree type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class_type)));
5113       parm = tree_cons (build_current_thisn (class_type),
5114                         build_pointer_type (type), parm);
5115
5116       /* Some more arguments to be hidden here. The values of the local
5117          variables of the outer context that the inner class needs to see. */
5118       parm = build_alias_initializer_parameter_list (AIPL_FUNCTION_CREATION,
5119                                                      class_type, parm, 
5120                                                      &artificial);
5121     }
5122
5123   /* Then if there are any args to be enforced, enforce them now */
5124   for (; args && args != end_params_node; args = TREE_CHAIN (args))
5125     {
5126       sprintf (buffer, "parm%d", i++);
5127       parm = tree_cons (get_identifier (buffer), TREE_VALUE (args), parm);
5128     }
5129
5130   CRAFTED_PARAM_LIST_FIXUP (parm);
5131   decl = create_artificial_method (class_type, flags, void_type_node, 
5132                                    ctor_name, parm);
5133   fix_method_argument_names (parm, decl);
5134   /* Now, mark the artificial parameters. */
5135   DECL_FUNCTION_NAP (decl) = artificial;
5136
5137   pop_obstacks ();
5138   DECL_CONSTRUCTOR_P (decl) = 1;
5139 }
5140
5141
5142 /* Fix the constructors. This will be called right after circular
5143    references have been checked. It is necessary to fix constructors
5144    early even if no code generation will take place for that class:
5145    some generated constructor might be required by the class whose
5146    compilation triggered this one to be simply loaded.  */
5147
5148 void
5149 java_fix_constructors ()
5150 {
5151   tree current;
5152
5153   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
5154     {
5155       tree class_type = TREE_TYPE (current);
5156       int saw_ctor = 0;
5157       tree decl;
5158
5159       if (CLASS_INTERFACE (TYPE_NAME (class_type)))
5160         continue;
5161
5162       for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
5163         {
5164           if (DECL_CONSTRUCTOR_P (decl))
5165             {
5166               fix_constructors (decl);
5167               saw_ctor = 1;
5168             }
5169         }
5170
5171       /* Anonymous class constructor can't be generated that early. */
5172       if (!saw_ctor && !ANONYMOUS_CLASS_P (class_type))
5173         craft_constructor (current, NULL_TREE);
5174     }
5175 }
5176
5177 /* safe_layout_class just makes sure that we can load a class without
5178    disrupting the current_class, input_file, lineno, etc, information
5179    about the class processed currently.  */
5180
5181 void
5182 safe_layout_class (class)
5183      tree class;
5184 {
5185   tree save_current_class = current_class;
5186   const char *save_input_filename = input_filename;
5187   int save_lineno = lineno;
5188
5189   push_obstacks (&permanent_obstack, &permanent_obstack);
5190
5191   layout_class (class);
5192   pop_obstacks ();
5193
5194   current_class = save_current_class;
5195   input_filename = save_input_filename;
5196   lineno = save_lineno;
5197   CLASS_LOADED_P (class) = 1;
5198 }
5199
5200 static tree
5201 jdep_resolve_class (dep)
5202      jdep *dep;
5203 {
5204   tree decl;
5205
5206   if (JDEP_RESOLVED_P (dep))
5207     decl = JDEP_RESOLVED_DECL (dep);
5208   else
5209     {
5210       decl = resolve_class (JDEP_ENCLOSING (dep), JDEP_TO_RESOLVE (dep),
5211                             JDEP_DECL (dep), JDEP_WFL (dep));
5212       JDEP_RESOLVED (dep, decl);
5213     }
5214     
5215   if (!decl)
5216     complete_class_report_errors (dep);
5217
5218   if (PURE_INNER_CLASS_DECL_P (decl))
5219     check_inner_class_access (decl, JDEP_ENCLOSING (dep), JDEP_WFL (dep));
5220   return decl;
5221 }
5222
5223 /* Complete unsatisfied class declaration and their dependencies */
5224
5225 void
5226 java_complete_class ()
5227 {
5228   tree cclass;
5229   jdeplist *cclassd;
5230   int error_found;
5231   tree type;
5232
5233   push_obstacks (&permanent_obstack, &permanent_obstack);
5234
5235   /* Process imports */
5236   process_imports ();
5237
5238   /* Rever things so we have the right order */
5239   ctxp->class_list = nreverse (ctxp->class_list);
5240   ctxp->classd_list = reverse_jdep_list (ctxp);
5241
5242   for (cclassd = ctxp->classd_list, cclass = ctxp->class_list; 
5243        cclass && cclassd; 
5244        cclass = TREE_CHAIN (cclass), cclassd = CLASSD_CHAIN (cclassd))
5245     {
5246       jdep *dep;
5247       for (dep = CLASSD_FIRST (cclassd); dep; dep = JDEP_CHAIN (dep))
5248         {
5249           tree decl;
5250           if (!(decl = jdep_resolve_class (dep)))
5251             continue;
5252
5253           /* Now it's time to patch */
5254           switch (JDEP_KIND (dep))
5255             {
5256             case JDEP_SUPER:
5257               /* Simply patch super */
5258               if (parser_check_super (decl, JDEP_DECL (dep), JDEP_WFL (dep)))
5259                 continue;
5260               BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO 
5261                 (TREE_TYPE (JDEP_DECL (dep)))), 0)) = TREE_TYPE (decl);
5262               break;
5263
5264             case JDEP_FIELD:
5265               {
5266                 /* We do part of the job done in add_field */
5267                 tree field_decl = JDEP_DECL (dep);
5268                 tree field_type = TREE_TYPE (decl);
5269                 push_obstacks (&permanent_obstack, &permanent_obstack);
5270                 if (TREE_CODE (field_type) == RECORD_TYPE)
5271                   field_type = promote_type (field_type);
5272                 pop_obstacks ();
5273                 TREE_TYPE (field_decl) = field_type;
5274                 DECL_ALIGN (field_decl) = 0;
5275                 DECL_USER_ALIGN (field_decl) = 0;
5276                 layout_decl (field_decl, 0);
5277                 SOURCE_FRONTEND_DEBUG 
5278                   (("Completed field/var decl `%s' with `%s'",
5279                     IDENTIFIER_POINTER (DECL_NAME (field_decl)),
5280                     IDENTIFIER_POINTER (DECL_NAME (decl))));
5281                 break;
5282               }
5283             case JDEP_METHOD:   /* We start patching a method */
5284             case JDEP_METHOD_RETURN:
5285               error_found = 0;
5286               while (1)
5287                 {
5288                   if (decl)
5289                     {
5290                       type = TREE_TYPE(decl);
5291                       if (TREE_CODE (type) == RECORD_TYPE)
5292                         type = promote_type (type);
5293                       JDEP_APPLY_PATCH (dep, type);
5294                       SOURCE_FRONTEND_DEBUG 
5295                         (((JDEP_KIND (dep) == JDEP_METHOD_RETURN ?
5296                            "Completing fct `%s' with ret type `%s'":
5297                            "Completing arg `%s' with type `%s'"),
5298                           IDENTIFIER_POINTER (EXPR_WFL_NODE 
5299                                               (JDEP_DECL_WFL (dep))),
5300                           IDENTIFIER_POINTER (DECL_NAME (decl))));
5301                     }
5302                   else
5303                     error_found = 1;
5304                   dep = JDEP_CHAIN (dep);
5305                   if (JDEP_KIND (dep) == JDEP_METHOD_END)
5306                     break;
5307                   else
5308                     decl = jdep_resolve_class (dep);
5309                 }
5310               if (!error_found)
5311                 {
5312                   tree mdecl = JDEP_DECL (dep), signature;
5313                   push_obstacks (&permanent_obstack, &permanent_obstack);
5314                   /* Recompute and reset the signature, check first that
5315                      all types are now defined. If they're not,
5316                      dont build the signature. */
5317                   if (check_method_types_complete (mdecl))
5318                     {
5319                       signature = build_java_signature (TREE_TYPE (mdecl));
5320                       set_java_signature (TREE_TYPE (mdecl), signature);
5321                     }
5322                   pop_obstacks ();
5323                 }
5324               else
5325                 continue;
5326               break;
5327
5328             case JDEP_INTERFACE:
5329               if (parser_check_super_interface (decl, JDEP_DECL (dep),
5330                                                 JDEP_WFL (dep)))
5331                 continue;
5332               parser_add_interface (JDEP_DECL (dep), decl, JDEP_WFL (dep));
5333               break;
5334
5335             case JDEP_PARM:
5336             case JDEP_VARIABLE:
5337               type = TREE_TYPE(decl);
5338               if (TREE_CODE (type) == RECORD_TYPE)
5339                 type = promote_type (type);
5340               JDEP_APPLY_PATCH (dep, type);
5341               break;
5342
5343             case JDEP_TYPE:
5344               JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
5345               SOURCE_FRONTEND_DEBUG 
5346                 (("Completing a random type dependency on a '%s' node",
5347                   tree_code_name [TREE_CODE (JDEP_DECL (dep))]));
5348               break;
5349
5350             case JDEP_EXCEPTION:
5351               JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
5352               SOURCE_FRONTEND_DEBUG 
5353                 (("Completing `%s' `throws' argument node",
5354                   IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)))));
5355               break;
5356
5357             case JDEP_ANONYMOUS:
5358               patch_anonymous_class (decl, JDEP_DECL (dep), JDEP_WFL (dep));
5359               break;
5360
5361             default:
5362               fatal ("Can't handle patch code %d - java_complete_class",
5363                      JDEP_KIND (dep));
5364             }
5365         }
5366     }
5367   pop_obstacks ();
5368   return;
5369 }
5370
5371 /* Resolve class CLASS_TYPE. Handle the case of trying to resolve an
5372    array.  */
5373
5374 static tree
5375 resolve_class (enclosing, class_type, decl, cl)
5376      tree enclosing, class_type, decl, cl;
5377 {
5378   const char *name = IDENTIFIER_POINTER (TYPE_NAME (class_type));
5379   const char *base = name;
5380   tree resolved_type = TREE_TYPE (class_type);
5381   tree resolved_type_decl;
5382   
5383   if (resolved_type != NULL_TREE)
5384     {
5385       tree resolved_type_decl = TYPE_NAME (resolved_type);
5386       if (resolved_type_decl == NULL_TREE
5387           || TREE_CODE (resolved_type_decl) == IDENTIFIER_NODE)
5388         {
5389           resolved_type_decl = build_decl (TYPE_DECL,
5390                                            TYPE_NAME (class_type),
5391                                            resolved_type);
5392         }
5393       return resolved_type_decl;
5394     }
5395
5396   /* 1- Check to see if we have an array. If true, find what we really
5397      want to resolve  */
5398   while (name[0] == '[')
5399     name++;
5400   if (base != name)
5401     TYPE_NAME (class_type) = get_identifier (name);
5402
5403   /* 2- Resolve the bare type */
5404   if (!(resolved_type_decl = do_resolve_class (enclosing, class_type, 
5405                                                decl, cl)))
5406     return NULL_TREE;
5407   resolved_type = TREE_TYPE (resolved_type_decl);
5408
5409   /* 3- If we have and array, reconstruct the array down to its nesting */
5410   if (base != name)
5411     {
5412       while (base != name)
5413         {
5414           if (TREE_CODE (resolved_type) == RECORD_TYPE)
5415             resolved_type  = promote_type (resolved_type);
5416           resolved_type = build_java_array_type (resolved_type, -1);
5417           CLASS_LOADED_P (resolved_type) = 1;
5418           name--;
5419         }
5420       /* Build a fake decl for this, since this is what is expected to
5421          be returned.  */
5422       resolved_type_decl =
5423         build_decl (TYPE_DECL, TYPE_NAME (resolved_type), resolved_type);
5424       /* Figure how those two things are important for error report. FIXME */
5425       DECL_SOURCE_LINE (resolved_type_decl) = 0;
5426       DECL_SOURCE_FILE (resolved_type_decl) = input_filename;
5427       TYPE_NAME (class_type) = TYPE_NAME (resolved_type);
5428     }
5429   TREE_TYPE (class_type) = resolved_type;
5430   return resolved_type_decl;
5431 }
5432
5433 /* Effectively perform the resolution of class CLASS_TYPE. DECL or CL
5434    are used to report error messages.  */
5435
5436 tree
5437 do_resolve_class (enclosing, class_type, decl, cl)
5438      tree enclosing, class_type, decl, cl;
5439 {
5440   tree new_class_decl;
5441
5442   /* Do not try to replace TYPE_NAME (class_type) by a variable, since
5443      it is changed by find_in_imports{_on_demand} and (but it doesn't
5444      really matter) qualify_and_find */
5445
5446   /* 0- Search in the current class as an inner class */
5447
5448   /* Maybe some code here should be added to load the class or
5449      something, at least if the class isn't an inner class and ended
5450      being loaded from class file. FIXME. */
5451   while (enclosing)
5452     {
5453       tree name;
5454
5455       if ((new_class_decl = find_as_inner_class (enclosing, class_type, cl)))
5456         return new_class_decl;
5457
5458       /* Explore enclosing contexts. */
5459       while (INNER_CLASS_DECL_P (enclosing))
5460         {
5461           enclosing = DECL_CONTEXT (enclosing);
5462           if ((new_class_decl = find_as_inner_class (enclosing, 
5463                                                      class_type, cl)))
5464             return new_class_decl;
5465         }
5466
5467       /* Now go to the upper classes, bail out if necessary. */
5468       enclosing = CLASSTYPE_SUPER (TREE_TYPE (enclosing));
5469       if (!enclosing || enclosing == object_type_node)
5470         break;
5471       
5472       if (TREE_CODE (enclosing) == RECORD_TYPE)
5473         {
5474           enclosing = TYPE_NAME (enclosing);
5475           continue;
5476         }
5477
5478       if (TREE_CODE (enclosing) == IDENTIFIER_NODE)
5479         BUILD_PTR_FROM_NAME (name, enclosing);
5480       else
5481         name = enclosing;
5482       enclosing = do_resolve_class (NULL, name, NULL, NULL);
5483     }
5484
5485   /* 1- Check for the type in single imports. This will change
5486      TYPE_NAME() if something relevant is found */
5487   find_in_imports (class_type);
5488
5489   /* 2- And check for the type in the current compilation unit */
5490   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
5491     {
5492       if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
5493           !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
5494         load_class (TYPE_NAME (class_type), 0);
5495       return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5496     }
5497
5498   /* 3- Search according to the current package definition */
5499   if (!QUALIFIED_P (TYPE_NAME (class_type)))
5500     {
5501       if ((new_class_decl = qualify_and_find (class_type, ctxp->package,
5502                                              TYPE_NAME (class_type))))
5503         return new_class_decl;
5504     }
5505
5506   /* 4- Check the import on demands. Don't allow bar.baz to be
5507      imported from foo.* */
5508   if (!QUALIFIED_P (TYPE_NAME (class_type)))
5509     if (find_in_imports_on_demand (class_type))
5510       return NULL_TREE;
5511
5512   /* If found in find_in_imports_on_demant, the type has already been
5513      loaded. */
5514   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
5515     return new_class_decl;
5516
5517   /* 5- Try with a name qualified with the package name we've seen so far */
5518   if (!QUALIFIED_P (TYPE_NAME (class_type)))
5519     {
5520       tree package;
5521
5522       /* If there is a current package (ctxp->package), it's the first
5523          element of package_list and we can skip it. */
5524       for (package = (ctxp->package ? 
5525                       TREE_CHAIN (package_list) : package_list);
5526            package; package = TREE_CHAIN (package))
5527         if ((new_class_decl = qualify_and_find (class_type,
5528                                                TREE_PURPOSE (package), 
5529                                                TYPE_NAME (class_type))))
5530           return new_class_decl;
5531     }
5532
5533   /* 5- Check an other compilation unit that bears the name of type */
5534   load_class (TYPE_NAME (class_type), 0);
5535   if (check_pkg_class_access (TYPE_NAME (class_type), 
5536                               (cl ? cl : lookup_cl (decl))))
5537     return NULL_TREE;
5538
5539   /* 6- Last call for a resolution */
5540   return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5541 }
5542
5543 static tree
5544 qualify_and_find (class_type, package, name)
5545      tree class_type, package, name;
5546 {
5547   tree new_qualified = merge_qualified_name (package, name);
5548   tree new_class_decl;
5549
5550   if (!IDENTIFIER_CLASS_VALUE (new_qualified))
5551     load_class (new_qualified, 0);
5552   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (new_qualified)))
5553     {
5554       if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
5555           !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
5556         load_class (new_qualified, 0);
5557       TYPE_NAME (class_type) = new_qualified;
5558       return IDENTIFIER_CLASS_VALUE (new_qualified);
5559     }
5560   return NULL_TREE;
5561 }
5562
5563 /* Resolve NAME and lay it out (if not done and if not the current
5564    parsed class). Return a decl node. This function is meant to be
5565    called when type resolution is necessary during the walk pass.  */
5566
5567 static tree
5568 resolve_and_layout (something, cl)
5569      tree something;
5570      tree cl;
5571 {
5572   tree decl;
5573
5574   /* Don't do that on the current class */
5575   if (something == current_class)
5576     return TYPE_NAME (current_class);
5577
5578   /* Don't do anything for void and other primitive types */
5579   if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
5580     return NULL_TREE;
5581
5582   /* Pointer types can be reall pointer types or fake pointers. When
5583      finding a real pointer, recheck for primitive types */
5584   if (TREE_CODE (something) == POINTER_TYPE)
5585     {
5586       if (TREE_TYPE (something))
5587         {
5588           something = TREE_TYPE (something);
5589           if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
5590             return NULL_TREE;
5591         }
5592       else
5593         something = TYPE_NAME (something);
5594     }
5595
5596   /* Don't do anything for arrays of primitive types */
5597   if (TREE_CODE (something) == RECORD_TYPE && TYPE_ARRAY_P (something)
5598       && JPRIMITIVE_TYPE_P (TYPE_ARRAY_ELEMENT (something)))
5599     return NULL_TREE;
5600
5601   /* Something might be a WFL */
5602   if (TREE_CODE (something) == EXPR_WITH_FILE_LOCATION)
5603     something = EXPR_WFL_NODE (something);
5604
5605   /* Otherwise, if something is not and IDENTIFIER_NODE, it can be a a
5606      TYPE_DECL or a real TYPE */
5607   else if (TREE_CODE (something) != IDENTIFIER_NODE)
5608     something = (TREE_CODE (TYPE_NAME (something)) == TYPE_DECL ?
5609             DECL_NAME (TYPE_NAME (something)) : TYPE_NAME (something));
5610
5611   if (!(decl = resolve_no_layout (something, cl)))
5612     return NULL_TREE;
5613
5614   /* Resolve and layout if necessary */
5615   layout_class_methods (TREE_TYPE (decl));
5616   /* Check methods, but only once */
5617   if (CLASS_FROM_SOURCE_P (TREE_TYPE (decl)) 
5618       && !CLASS_LOADED_P (TREE_TYPE (decl)))
5619     CHECK_METHODS (decl);
5620   if (TREE_TYPE (decl) != current_class && !CLASS_LOADED_P (TREE_TYPE (decl)))
5621     safe_layout_class (TREE_TYPE (decl));
5622
5623   return decl;
5624 }
5625
5626 /* Resolve a class, returns its decl but doesn't perform any
5627    layout. The current parsing context is saved and restored */
5628
5629 static tree
5630 resolve_no_layout (name, cl)
5631      tree name, cl;
5632 {
5633   tree ptr, decl;
5634   BUILD_PTR_FROM_NAME (ptr, name);
5635   java_parser_context_save_global ();
5636   decl = resolve_class (TYPE_NAME (current_class), ptr, NULL_TREE, cl);
5637   java_parser_context_restore_global ();
5638   
5639   return decl;
5640 }
5641
5642 /* Called when reporting errors. Skip leader '[' in a complex array
5643    type description that failed to be resolved.  */
5644
5645 static const char *
5646 purify_type_name (name)
5647      const char *name;
5648 {
5649   while (*name && *name == '[')
5650     name++;
5651   return name;
5652 }
5653
5654 /* The type CURRENT refers to can't be found. We print error messages.  */
5655
5656 static void
5657 complete_class_report_errors (dep)
5658      jdep *dep;
5659 {
5660   const char *name;
5661
5662   if (!JDEP_WFL (dep))
5663     return;
5664
5665   name = IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)));
5666   switch (JDEP_KIND (dep))
5667     {
5668     case JDEP_SUPER:
5669       parse_error_context  
5670         (JDEP_WFL (dep), "Superclass `%s' of class `%s' not found",
5671          purify_type_name (name),
5672          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5673       break;
5674     case JDEP_FIELD:
5675       parse_error_context
5676         (JDEP_WFL (dep), "Type `%s' not found in declaration of field `%s'",
5677          purify_type_name (name),
5678          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5679       break;
5680     case JDEP_METHOD:           /* Covers arguments */
5681       parse_error_context
5682         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the argument `%s' of method `%s'",
5683          purify_type_name (name),
5684          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))),
5685          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_MISC (dep))));
5686       break;
5687     case JDEP_METHOD_RETURN:    /* Covers return type */
5688       parse_error_context
5689         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the return type of method `%s'", 
5690          purify_type_name (name),
5691          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))));
5692       break;
5693     case JDEP_INTERFACE:
5694       parse_error_context
5695         (JDEP_WFL (dep), "Superinterface `%s' of %s `%s' not found",
5696          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))),
5697          (CLASS_OR_INTERFACE (JDEP_DECL (dep), "class", "interface")),
5698          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5699       break;
5700     case JDEP_VARIABLE:
5701       parse_error_context
5702         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the local variable `%s'", 
5703          purify_type_name (IDENTIFIER_POINTER 
5704                            (EXPR_WFL_NODE (JDEP_WFL (dep)))),
5705          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
5706       break;
5707     case JDEP_EXCEPTION:        /* As specified by `throws' */
5708       parse_error_context 
5709           (JDEP_WFL (dep), "Class `%s' not found in `throws'",
5710          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))));
5711       break;
5712     default:
5713       /* Fix for -Wall. Just break doing nothing. The error will be
5714          caught later */
5715       break;
5716     }
5717 }
5718
5719 /* Return a static string containing the DECL prototype string. If
5720    DECL is a constructor, use the class name instead of the form
5721    <init> */
5722
5723 static const char *
5724 get_printable_method_name (decl)
5725      tree decl;
5726 {
5727   const char *to_return;
5728   tree name = NULL_TREE;
5729
5730   if (DECL_CONSTRUCTOR_P (decl))
5731     {
5732       name = DECL_NAME (decl);
5733       DECL_NAME (decl) = DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)));
5734     }
5735       
5736   to_return = lang_printable_name (decl, 0);
5737   if (DECL_CONSTRUCTOR_P (decl))
5738     DECL_NAME (decl) = name;
5739   
5740   return to_return;
5741 }
5742
5743 /* Reinstall the proper DECL_NAME on METHOD. Return 0 if the method
5744    nevertheless needs to be verfied, 1 otherwise.  */
5745
5746 static int
5747 reset_method_name (method)
5748      tree method;
5749 {
5750   if (!DECL_CLINIT_P (method) && !DECL_FINIT_P (method))
5751     {
5752       /* NAME is just the plain name when Object is being defined */
5753       if (DECL_CONTEXT (method) != object_type_node)
5754         DECL_NAME (method) = (DECL_CONSTRUCTOR_P (method) ? 
5755                               init_identifier_node : GET_METHOD_NAME (method));
5756       return 0;
5757     }
5758   else 
5759     return 1;
5760 }
5761
5762 /* Return the name of METHOD_DECL, when DECL_NAME is a WFL */
5763
5764 tree
5765 java_get_real_method_name (method_decl)
5766      tree method_decl;
5767 {
5768   tree method_name = DECL_NAME (method_decl);
5769   if (DECL_CONSTRUCTOR_P (method_decl))
5770     return init_identifier_node;
5771
5772   /* Explain here why METHOD_DECL doesn't have the DECL_CONSTRUCTUR_P
5773      and still can be a constructor. FIXME */
5774
5775   /* Don't confuse method only bearing the name of their class as
5776      constructors */
5777   else if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (method_decl))
5778            && ctxp
5779            && GET_CPC_UN () == EXPR_WFL_NODE (method_name)
5780            && get_access_flags_from_decl (method_decl) <= ACC_PROTECTED
5781            && TREE_TYPE (TREE_TYPE (method_decl)) == void_type_node)
5782     return init_identifier_node;
5783   else
5784     return EXPR_WFL_NODE (method_name);
5785 }
5786
5787 /* Track method being redefined inside the same class. As a side
5788    effect, set DECL_NAME to an IDENTIFIER (prior entering this
5789    function it's a FWL, so we can track errors more accurately.)  */
5790
5791 static int
5792 check_method_redefinition (class, method)
5793      tree class, method;
5794 {
5795   tree redef, name;
5796   tree cl = DECL_NAME (method);
5797   tree sig = TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (method));
5798   /* decl name of artificial <clinit> and $finit$ doesn't need to be
5799      fixed and checked */
5800
5801   /* Reset the method name before running the check. If it returns 1,
5802      the method doesn't need to be verified with respect to method
5803      redeclaration and we return 0 */
5804   if (reset_method_name (method))
5805     return 0;
5806
5807   name = DECL_NAME (method);
5808   for (redef = TYPE_METHODS (class); redef; redef = TREE_CHAIN (redef))
5809     {
5810       if (redef == method)
5811         break;
5812       if (DECL_NAME (redef) == name 
5813           && sig == TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (redef)))
5814         {
5815           parse_error_context 
5816             (cl, "Duplicate %s declaration `%s'",
5817              (DECL_CONSTRUCTOR_P (redef) ? "constructor" : "method"),
5818              get_printable_method_name (redef));
5819           return 1;
5820         }
5821     }
5822   return 0;
5823 }
5824
5825 static void
5826 check_abstract_method_definitions (do_interface, class_decl, type)
5827      int do_interface;
5828      tree class_decl, type;
5829 {
5830   tree class = TREE_TYPE (class_decl);
5831   tree method, end_type;
5832
5833   end_type = (do_interface ? object_type_node : type);
5834   for (method = TYPE_METHODS (type); method; method = TREE_CHAIN (method))
5835     {
5836       tree other_super, other_method, method_sig, method_name;
5837       int found = 0;
5838       int end_type_reached = 0;
5839       
5840       if (!METHOD_ABSTRACT (method) || METHOD_FINAL (method))
5841         continue;
5842       
5843       /* Now verify that somewhere in between TYPE and CLASS,
5844          abstract method METHOD gets a non abstract definition
5845          that is inherited by CLASS.  */
5846       
5847       method_sig = build_java_signature (TREE_TYPE (method));
5848       method_name = DECL_NAME (method);
5849       if (TREE_CODE (method_name) == EXPR_WITH_FILE_LOCATION)
5850         method_name = EXPR_WFL_NODE (method_name);
5851
5852       other_super = class;
5853       do {
5854         if (other_super == end_type)
5855           end_type_reached = 1;
5856         
5857         /* Method search */
5858         for (other_method = TYPE_METHODS (other_super); other_method;
5859             other_method = TREE_CHAIN (other_method))
5860           {
5861             tree s = build_java_signature (TREE_TYPE (other_method));
5862             tree other_name = DECL_NAME (other_method);
5863             
5864             if (TREE_CODE (other_name) == EXPR_WITH_FILE_LOCATION)
5865               other_name = EXPR_WFL_NODE (other_name);
5866             if (!DECL_CLINIT_P (other_method)
5867                 && !DECL_CONSTRUCTOR_P (other_method)
5868                 && method_name == other_name
5869                 && method_sig == s
5870                 && !METHOD_ABSTRACT (other_method))
5871              {
5872                found = 1;
5873                break;
5874              }
5875           }
5876         other_super = CLASSTYPE_SUPER (other_super);
5877       } while (!end_type_reached);
5878  
5879       /* Report that abstract METHOD didn't find an implementation
5880          that CLASS can use. */
5881       if (!found)
5882         {
5883           char *t = xstrdup (lang_printable_name 
5884                             (TREE_TYPE (TREE_TYPE (method)), 0));
5885           tree ccn = DECL_NAME (TYPE_NAME (DECL_CONTEXT (method)));
5886           tree saved_wfl = NULL_TREE;
5887           
5888           if (TREE_CODE (DECL_NAME (method)) == EXPR_WITH_FILE_LOCATION)
5889             {
5890               saved_wfl = DECL_NAME (method);
5891               DECL_NAME (method) = EXPR_WFL_NODE (DECL_NAME (method));
5892             }
5893           
5894           parse_error_context 
5895             (lookup_cl (class_decl),
5896              "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",
5897              IDENTIFIER_POINTER (DECL_NAME (class_decl)),
5898              t, lang_printable_name (method, 0), 
5899              (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))) ? 
5900               "interface" : "class"),
5901              IDENTIFIER_POINTER (ccn),
5902              (CLASS_INTERFACE (class_decl) ? "interface" : "class"),
5903              IDENTIFIER_POINTER (DECL_NAME (class_decl)));
5904           
5905           free (t);
5906           
5907           if (saved_wfl)
5908             DECL_NAME (method) = saved_wfl;
5909         }
5910     }
5911 }
5912
5913 /* Check that CLASS_DECL somehow implements all inherited abstract
5914    methods.  */
5915
5916 static void
5917 java_check_abstract_method_definitions (class_decl)
5918      tree class_decl;
5919 {
5920   tree class = TREE_TYPE (class_decl);
5921   tree super, vector;
5922   int i;
5923
5924   if (CLASS_ABSTRACT (class_decl))
5925     return;
5926
5927   /* Check for inherited types */
5928   super = class;
5929   do {
5930     super = CLASSTYPE_SUPER (super);
5931     check_abstract_method_definitions (0, class_decl, super);
5932   } while (super != object_type_node);
5933
5934   /* Check for implemented interfaces. */
5935   vector = TYPE_BINFO_BASETYPES (class);
5936   for (i = 1; i < TREE_VEC_LENGTH (vector); i++)
5937     {
5938       super = BINFO_TYPE (TREE_VEC_ELT (vector, i));
5939       check_abstract_method_definitions (1, class_decl, super);
5940     }
5941 }
5942
5943 /* Check all the types method DECL uses and return 1 if all of them
5944    are now complete, 0 otherwise. This is used to check whether its
5945    safe to build a method signature or not.  */
5946
5947 static int
5948 check_method_types_complete (decl)
5949      tree decl;
5950 {
5951   tree type = TREE_TYPE (decl);
5952   tree args;
5953
5954   if (!INCOMPLETE_TYPE_P (TREE_TYPE (type)))
5955     return 0;
5956   
5957   args = TYPE_ARG_TYPES (type);
5958   if (TREE_CODE (type) == METHOD_TYPE)
5959     args = TREE_CHAIN (args);
5960   for (; args != end_params_node; args = TREE_CHAIN (args))
5961     if (INCOMPLETE_TYPE_P (TREE_VALUE (args)))
5962       return 0;
5963
5964   return 1;
5965 }
5966
5967 /* Check all the methods of CLASS_DECL. Methods are first completed
5968    then checked according to regular method existance rules.  If no
5969    constructor for CLASS_DECL were encountered, then build its
5970    declaration.  */
5971
5972 static void
5973 java_check_regular_methods (class_decl)
5974      tree class_decl;
5975 {
5976   int saw_constructor = ANONYMOUS_CLASS_P (TREE_TYPE (class_decl));
5977   tree method;
5978   tree class = CLASS_TO_HANDLE_TYPE (TREE_TYPE (class_decl));
5979   tree saved_found_wfl = NULL_TREE, found = NULL_TREE;
5980   tree mthrows;
5981
5982   /* It is not necessary to check methods defined in java.lang.Object */
5983   if (class == object_type_node)
5984     return;
5985
5986   if (!TYPE_NVIRTUALS (class))
5987     TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
5988
5989   /* Should take interfaces into account. FIXME */
5990   for (method = TYPE_METHODS (class); method; method = TREE_CHAIN (method))
5991     {
5992       tree sig;
5993       tree method_wfl = DECL_NAME (method);
5994       int aflags;
5995
5996       /* If we previously found something and its name was saved,
5997          reinstall it now */
5998       if (found && saved_found_wfl)
5999         {
6000           DECL_NAME (found) = saved_found_wfl;
6001           saved_found_wfl = NULL_TREE;
6002         }
6003
6004       /* Check for redefinitions */
6005       if (check_method_redefinition (class, method))
6006         continue;
6007
6008       /* If we see one constructor a mark so we don't generate the
6009          default one. Also skip other verifications: constructors
6010          can't be inherited hence hiden or overriden */
6011      if (DECL_CONSTRUCTOR_P (method))
6012        {
6013          saw_constructor = 1;
6014          continue;
6015        }
6016
6017       /* We verify things thrown by the method. They must inherits from
6018          java.lang.Throwable */
6019       for (mthrows = DECL_FUNCTION_THROWS (method);
6020            mthrows; mthrows = TREE_CHAIN (mthrows))
6021         {
6022           if (!inherits_from_p (TREE_VALUE (mthrows), throwable_type_node))
6023             parse_error_context 
6024               (TREE_PURPOSE (mthrows), "Class `%s' in `throws' clause must be a subclass of class `java.lang.Throwable'",
6025                IDENTIFIER_POINTER 
6026                  (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))));
6027         }
6028
6029       sig = build_java_argument_signature (TREE_TYPE (method));
6030       found = lookup_argument_method2 (class, DECL_NAME (method), sig);
6031
6032       /* Inner class can't declare static methods */
6033       if (METHOD_STATIC (method) && !TOPLEVEL_CLASS_DECL_P (class_decl))
6034         {
6035           char *t = xstrdup (lang_printable_name (class, 0));
6036           parse_error_context 
6037             (method_wfl, "Method `%s' can't be static in inner class `%s'. Only members of interfaces and top-level classes can be static",
6038              lang_printable_name (method, 0), t);
6039           free (t);
6040         }
6041
6042       /* Nothing overrides or it's a private method. */
6043       if (!found)
6044         continue;
6045       if (METHOD_PRIVATE (found))
6046         {
6047           found = NULL_TREE;
6048           continue;
6049         }
6050
6051       /* If found wasn't verified, it's DECL_NAME won't be set properly. 
6052          We set it temporarily for the sake of the error report. */
6053       saved_found_wfl = DECL_NAME (found);
6054       reset_method_name (found);
6055
6056       /* If `found' is declared in an interface, make sure the
6057          modifier matches. */
6058       if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (found))) 
6059           && clinit_identifier_node != DECL_NAME (found)
6060           && !METHOD_PUBLIC (method))
6061         {
6062           tree found_decl = TYPE_NAME (DECL_CONTEXT (found));
6063           parse_error_context (method_wfl, "Class `%s' must override `%s' with a public method in order to implement interface `%s'",
6064                                IDENTIFIER_POINTER (DECL_NAME (class_decl)),
6065                                lang_printable_name (method, 0),
6066                                IDENTIFIER_POINTER (DECL_NAME (found_decl)));
6067         }
6068
6069       /* Can't override a method with the same name and different return
6070          types. */
6071       if (TREE_TYPE (TREE_TYPE (found)) != TREE_TYPE (TREE_TYPE (method)))
6072         {
6073           char *t = xstrdup 
6074             (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
6075           parse_error_context 
6076             (method_wfl,
6077              "Method `%s' was defined with return type `%s' in class `%s'", 
6078              lang_printable_name (found, 0), t,
6079              IDENTIFIER_POINTER 
6080                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6081           free (t);
6082         }
6083
6084       aflags = get_access_flags_from_decl (found);
6085       /* If the method has default, access in an other package, then
6086          issue a warning that the current method doesn't override the
6087          one that was found elsewhere. Do not issue this warning when
6088          the match was found in java.lang.Object.  */
6089       if (DECL_CONTEXT (found) != object_type_node
6090           && ((aflags & ACC_VISIBILITY) == 0)
6091           && !class_in_current_package (DECL_CONTEXT (found))
6092           && !DECL_CLINIT_P (found)
6093           && flag_not_overriding)
6094         {
6095           parse_warning_context 
6096             (method_wfl, "Method `%s' in class `%s' does not override the corresponding method in class `%s', which is private to a different package",
6097              lang_printable_name (found, 0),
6098              IDENTIFIER_POINTER (DECL_NAME (class_decl)),
6099              IDENTIFIER_POINTER (DECL_NAME 
6100                                  (TYPE_NAME (DECL_CONTEXT (found)))));
6101           continue;
6102         }
6103
6104       /* Can't override final. Can't override static. */
6105       if (METHOD_FINAL (found) || METHOD_STATIC (found))
6106         {
6107           /* Static *can* override static */
6108           if (METHOD_STATIC (found) && METHOD_STATIC (method))
6109             continue;
6110           parse_error_context 
6111             (method_wfl,
6112              "%s methods can't be overriden. Method `%s' is %s in class `%s'",
6113              (METHOD_FINAL (found) ? "Final" : "Static"),
6114              lang_printable_name (found, 0),
6115              (METHOD_FINAL (found) ? "final" : "static"),
6116              IDENTIFIER_POINTER
6117                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6118           continue;
6119         }
6120
6121       /* Static method can't override instance method. */
6122       if (METHOD_STATIC (method))
6123         {
6124           parse_error_context 
6125             (method_wfl,
6126              "Instance methods can't be overriden by a static method. Method `%s' is an instance method in class `%s'",
6127              lang_printable_name (found, 0),
6128              IDENTIFIER_POINTER
6129                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6130           continue;
6131         }
6132
6133       /* - Overriding/hiding public must be public
6134          - Overriding/hiding protected must be protected or public
6135          - If the overriden or hidden method has default (package)
6136            access, then the overriding or hiding method must not be
6137            private; otherwise, a compile-time error occurs.  If
6138            `found' belongs to an interface, things have been already
6139            taken care of.  */
6140       if (!CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (found)))
6141           && ((METHOD_PUBLIC (found) && !METHOD_PUBLIC (method))
6142               || (METHOD_PROTECTED (found) 
6143                   && !(METHOD_PUBLIC (method) || METHOD_PROTECTED (method)))
6144               || (!(aflags & (ACC_PUBLIC | ACC_PRIVATE | ACC_STATIC))
6145                   && METHOD_PRIVATE (method))))
6146         {
6147           parse_error_context 
6148             (method_wfl,
6149              "Methods can't be overridden to be more private. Method `%s' is not %s in class `%s'", lang_printable_name (method, 0),
6150              (METHOD_PUBLIC (method) ? "public" : 
6151               (METHOD_PRIVATE (method) ? "private" : "protected")),
6152              IDENTIFIER_POINTER (DECL_NAME 
6153                                  (TYPE_NAME (DECL_CONTEXT (found)))));
6154           continue;
6155         }
6156
6157       /* Overriding methods must have compatible `throws' clauses on checked
6158          exceptions, if any */
6159       check_throws_clauses (method, method_wfl, found);
6160
6161       /* Inheriting multiple methods with the same signature. FIXME */
6162     }
6163   
6164   /* Don't forget eventual pending found and saved_found_wfl. Take
6165      into account that we might have exited because we saw an
6166      artificial method as the last entry. */
6167
6168   if (found && !DECL_ARTIFICIAL (found) && saved_found_wfl)
6169     DECL_NAME (found) = saved_found_wfl;
6170
6171   if (!TYPE_NVIRTUALS (class))
6172     TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
6173
6174   /* Search for inherited abstract method not yet implemented in this
6175      class.  */
6176   java_check_abstract_method_definitions (class_decl);
6177
6178   if (!saw_constructor)
6179     fatal ("No constructor found");
6180 }
6181
6182 /* Return a non zero value if the `throws' clause of METHOD (if any)
6183    is incompatible with the `throws' clause of FOUND (if any).  */
6184
6185 static void
6186 check_throws_clauses (method, method_wfl, found)
6187      tree method, method_wfl, found;
6188 {
6189   tree mthrows, fthrows;
6190
6191   /* Can't check these things with class loaded from bytecode. FIXME */
6192   if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (found)))
6193     return;
6194
6195   for (mthrows = DECL_FUNCTION_THROWS (method);
6196        mthrows; mthrows = TREE_CHAIN (mthrows))
6197     {
6198       /* We don't verify unchecked expressions */
6199       if (IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (mthrows)))
6200         continue;
6201       /* Checked expression must be compatible */
6202       for (fthrows = DECL_FUNCTION_THROWS (found); 
6203            fthrows; fthrows = TREE_CHAIN (fthrows))
6204         if (inherits_from_p (TREE_VALUE (mthrows), TREE_VALUE (fthrows)))
6205           break;
6206       if (!fthrows)
6207         {
6208           parse_error_context 
6209             (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'",
6210              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))),
6211              lang_printable_name (found, 0),
6212              IDENTIFIER_POINTER 
6213                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6214         }
6215     }
6216 }
6217
6218 /* Check abstract method of interface INTERFACE */
6219
6220 static void
6221 java_check_abstract_methods (interface_decl)
6222      tree interface_decl;
6223 {
6224   int i, n;
6225   tree method, basetype_vec, found;
6226   tree interface = TREE_TYPE (interface_decl);
6227
6228   for (method = TYPE_METHODS (interface); method; method = TREE_CHAIN (method))
6229     {
6230       tree method_wfl = DECL_NAME (method);
6231
6232       /* 2- Check for double definition inside the defining interface */
6233       if (check_method_redefinition (interface, method))
6234         continue;
6235
6236       /* 3- Overriding is OK as far as we preserve the return type and
6237          the thrown exceptions (FIXME) */
6238       found = lookup_java_interface_method2 (interface, method);
6239       if (found)
6240         {
6241           char *t;
6242           tree saved_found_wfl = DECL_NAME (found);
6243           reset_method_name (found);
6244           t = xstrdup (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
6245           parse_error_context 
6246             (method_wfl,
6247              "Method `%s' was defined with return type `%s' in class `%s'",
6248              lang_printable_name (found, 0), t,
6249              IDENTIFIER_POINTER 
6250                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6251           free (t);
6252           DECL_NAME (found) = saved_found_wfl;
6253           continue;
6254         }
6255     }
6256
6257   /* 4- Inherited methods can't differ by their returned types */
6258   if (!(basetype_vec = TYPE_BINFO_BASETYPES (interface)))
6259     return;
6260   n = TREE_VEC_LENGTH (basetype_vec);
6261   for (i = 0; i < n; i++)
6262     {
6263       tree sub_interface_method, sub_interface;
6264       tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
6265       if (!vec_elt)
6266         continue;
6267       sub_interface = BINFO_TYPE (vec_elt);
6268       for (sub_interface_method = TYPE_METHODS (sub_interface); 
6269            sub_interface_method;
6270            sub_interface_method = TREE_CHAIN (sub_interface_method))
6271         {
6272           found = lookup_java_interface_method2 (interface, 
6273                                                  sub_interface_method);
6274           if (found && (found != sub_interface_method))
6275             {
6276               tree saved_found_wfl = DECL_NAME (found);
6277               reset_method_name (found);
6278               parse_error_context 
6279                 (lookup_cl (sub_interface_method),
6280                  "Interface `%s' inherits method `%s' from interface `%s'. This method is redefined with a different return type in interface `%s'",
6281                  IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (interface))),
6282                  lang_printable_name (found, 0),
6283                  IDENTIFIER_POINTER 
6284                    (DECL_NAME (TYPE_NAME 
6285                                (DECL_CONTEXT (sub_interface_method)))),
6286                  IDENTIFIER_POINTER 
6287                    (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
6288               DECL_NAME (found) = saved_found_wfl;
6289             }
6290         }
6291     }
6292 }
6293
6294 /* Lookup methods in interfaces using their name and partial
6295    signature. Return a matching method only if their types differ.  */
6296
6297 static tree
6298 lookup_java_interface_method2 (class, method_decl)
6299      tree class, method_decl;
6300 {
6301   int i, n;
6302   tree basetype_vec = TYPE_BINFO_BASETYPES (class), to_return;
6303
6304   if (!basetype_vec)
6305     return NULL_TREE;
6306
6307   n = TREE_VEC_LENGTH (basetype_vec);
6308   for (i = 0; i < n; i++)
6309     {
6310       tree vec_elt = TREE_VEC_ELT (basetype_vec, i), to_return;
6311       if ((BINFO_TYPE (vec_elt) != object_type_node)
6312           && (to_return = 
6313               lookup_java_method2 (BINFO_TYPE (vec_elt), method_decl, 1)))
6314         return to_return;
6315     }
6316   for (i = 0; i < n; i++)
6317     {
6318       to_return = lookup_java_interface_method2 
6319         (BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i)), method_decl);
6320       if (to_return)
6321         return to_return;
6322     }
6323
6324   return NULL_TREE;
6325 }
6326
6327 /* Lookup method using their name and partial signature. Return a
6328    matching method only if their types differ.  */
6329
6330 static tree
6331 lookup_java_method2 (clas, method_decl, do_interface)
6332      tree clas, method_decl;
6333      int do_interface;
6334 {
6335   tree method, method_signature, method_name, method_type, name;
6336
6337   method_signature = build_java_argument_signature (TREE_TYPE (method_decl));
6338   name = DECL_NAME (method_decl);
6339   method_name = (TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ? 
6340                  EXPR_WFL_NODE (name) : name);
6341   method_type = TREE_TYPE (TREE_TYPE (method_decl));
6342
6343   while (clas != NULL_TREE)
6344     {
6345       for (method = TYPE_METHODS (clas);
6346            method != NULL_TREE;  method = TREE_CHAIN (method))
6347         {
6348           tree method_sig = build_java_argument_signature (TREE_TYPE (method));
6349           tree name = DECL_NAME (method);
6350           if ((TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
6351                EXPR_WFL_NODE (name) : name) == method_name
6352               && method_sig == method_signature 
6353               && TREE_TYPE (TREE_TYPE (method)) != method_type)
6354             return method;
6355         }
6356       clas = (do_interface ? NULL_TREE : CLASSTYPE_SUPER (clas));
6357     }
6358   return NULL_TREE;
6359 }
6360
6361 /* Return the line that matches DECL line number, and try its best to
6362    position the column number. Used during error reports.  */
6363
6364 static tree
6365 lookup_cl (decl)
6366      tree decl;
6367 {
6368   static tree cl = NULL_TREE;
6369   char *line, *found;
6370   
6371   if (!decl)
6372     return NULL_TREE;
6373
6374   if (cl == NULL_TREE)
6375     cl = build_expr_wfl (NULL_TREE, NULL, 0, 0);
6376
6377   EXPR_WFL_FILENAME_NODE (cl) = get_identifier (DECL_SOURCE_FILE (decl));
6378   EXPR_WFL_SET_LINECOL (cl, DECL_SOURCE_LINE_FIRST (decl), -1);
6379
6380   line = java_get_line_col (IDENTIFIER_POINTER (EXPR_WFL_FILENAME_NODE (cl)),
6381                             EXPR_WFL_LINENO (cl), EXPR_WFL_COLNO (cl));
6382
6383   found = strstr ((const char *)line, 
6384                   (const char *)IDENTIFIER_POINTER (DECL_NAME (decl)));
6385   if (found)
6386     EXPR_WFL_SET_LINECOL (cl, EXPR_WFL_LINENO (cl), found - line);
6387
6388   return cl;
6389 }
6390
6391 /* Look for a simple name in the single-type import list */
6392
6393 static tree
6394 find_name_in_single_imports (name)
6395      tree name;
6396 {
6397   tree node;
6398
6399   for (node = ctxp->import_list; node; node = TREE_CHAIN (node))
6400     if (TREE_VALUE (node) == name)
6401       return (EXPR_WFL_NODE (TREE_PURPOSE (node)));
6402
6403   return NULL_TREE;
6404 }
6405
6406 /* Process all single-type import. */
6407
6408 static int
6409 process_imports ()
6410 {
6411   tree import;
6412   int error_found;
6413
6414   for (import = ctxp->import_list; import; import = TREE_CHAIN (import))
6415     {
6416       tree to_be_found = EXPR_WFL_NODE (TREE_PURPOSE (import));
6417
6418       /* Don't load twice something already defined. */
6419       if (IDENTIFIER_CLASS_VALUE (to_be_found))
6420         continue;
6421       QUALIFIED_P (to_be_found) = 1;
6422       load_class (to_be_found, 0);
6423       error_found =
6424         check_pkg_class_access (to_be_found, TREE_PURPOSE (import));
6425       if (!IDENTIFIER_CLASS_VALUE (to_be_found))
6426         {
6427           parse_error_context (TREE_PURPOSE (import),
6428                                "Class or interface `%s' not found in import",
6429                                IDENTIFIER_POINTER (to_be_found));
6430           return 1;
6431         }
6432       if (error_found)
6433         return 1;
6434     }
6435   return 0;
6436 }
6437
6438 /* Possibly find and mark a class imported by a single-type import
6439    statement.  */
6440
6441 static void
6442 find_in_imports (class_type)
6443      tree class_type;
6444 {
6445   tree import;
6446
6447   for (import = ctxp->import_list; import; import = TREE_CHAIN (import))
6448     if (TREE_VALUE (import) == TYPE_NAME (class_type))
6449       {
6450         TYPE_NAME (class_type) = EXPR_WFL_NODE (TREE_PURPOSE (import));
6451         QUALIFIED_P (TYPE_NAME (class_type)) = 1;
6452       }
6453 }
6454
6455 static int
6456 note_possible_classname (name, len)
6457      const char *name;
6458      int len;
6459 {
6460   tree node;
6461   if (len > 5 && strncmp (&name [len-5], ".java", 5) == 0)
6462     len = len - 5;
6463   else if (len > 6 && strncmp (&name [len-6], ".class", 6) == 0)
6464     len = len - 6;
6465   else
6466     return 0;
6467   node = ident_subst (name, len, "", '/', '.', "");
6468   IS_A_CLASSFILE_NAME (node) = 1; /* Or soon to be */
6469   QUALIFIED_P (node) = strchr (name, '/') ? 1 : 0;
6470   return 1;
6471 }
6472
6473 /* Read a import directory, gathering potential match for further type
6474    references. Indifferently reads a filesystem or a ZIP archive
6475    directory.  */
6476
6477 static void
6478 read_import_dir (wfl)
6479      tree wfl;
6480 {
6481   tree package_id = EXPR_WFL_NODE (wfl);
6482   const char *package_name = IDENTIFIER_POINTER (package_id);
6483   int package_length = IDENTIFIER_LENGTH (package_id);
6484   DIR *dirp = NULL;
6485   JCF *saved_jcf = current_jcf;
6486
6487   int found = 0;
6488   int k;
6489   void *entry;
6490   struct buffer filename[1];
6491
6492
6493   if (IS_AN_IMPORT_ON_DEMAND_P (package_id))
6494     return;
6495   IS_AN_IMPORT_ON_DEMAND_P (package_id) = 1;
6496
6497   BUFFER_INIT (filename);
6498   buffer_grow (filename, package_length + 100);
6499
6500   for (entry = jcf_path_start (); entry != NULL; entry = jcf_path_next (entry))
6501     {
6502       const char *entry_name = jcf_path_name (entry);
6503       int entry_length = strlen (entry_name);
6504       if (jcf_path_is_zipfile (entry))
6505         {
6506           ZipFile *zipf;
6507           buffer_grow (filename, entry_length);
6508           memcpy (filename->data, entry_name, entry_length - 1);
6509           filename->data[entry_length-1] = '\0';
6510           zipf = opendir_in_zip (filename->data, jcf_path_is_system (entry));
6511           if (zipf == NULL)
6512             error ("malformed .zip archive in CLASSPATH: %s", entry_name);
6513           else
6514             {
6515               ZipDirectory *zipd = (ZipDirectory *) zipf->central_directory;
6516               BUFFER_RESET (filename);
6517               for (k = 0; k < package_length; k++)
6518                 {
6519                   char ch = package_name[k];
6520                   *filename->ptr++ = ch == '.' ? '/' : ch;
6521                 }
6522               *filename->ptr++ = '/';
6523
6524               for (k = 0; k < zipf->count;  k++, zipd = ZIPDIR_NEXT (zipd))
6525                 {
6526                   const char *current_entry = ZIPDIR_FILENAME (zipd);
6527                   int current_entry_len = zipd->filename_length;
6528
6529                   if (current_entry_len >= BUFFER_LENGTH (filename)
6530                       && strncmp (filename->data, current_entry, 
6531                                   BUFFER_LENGTH (filename)) != 0)
6532                     continue;
6533                   found |= note_possible_classname (current_entry,
6534                                                     current_entry_len);
6535                 }
6536             }
6537         }
6538       else
6539         {
6540           BUFFER_RESET (filename);
6541           buffer_grow (filename, entry_length + package_length + 4);
6542           strcpy (filename->data, entry_name);
6543           filename->ptr = filename->data + entry_length;
6544           for (k = 0; k < package_length; k++)
6545             {
6546               char ch = package_name[k];
6547               *filename->ptr++ = ch == '.' ? '/' : ch;
6548             }
6549           *filename->ptr = '\0';
6550
6551           dirp = opendir (filename->data);
6552           if (dirp == NULL)
6553             continue;
6554           *filename->ptr++ = '/';
6555           for (;;)
6556             {
6557               int len; 
6558               const char *d_name;
6559               struct dirent *direntp = readdir (dirp);
6560               if (!direntp)
6561                 break;
6562               d_name = direntp->d_name;
6563               len = strlen (direntp->d_name);
6564               buffer_grow (filename, len+1);
6565               strcpy (filename->ptr, d_name);
6566               found |= note_possible_classname (filename->data + entry_length,
6567                                                 package_length+len+1);
6568             }
6569           if (dirp)
6570             closedir (dirp);
6571         }
6572     }
6573
6574   free (filename->data);
6575
6576   /* Here we should have a unified way of retrieving an entry, to be
6577      indexed. */
6578   if (!found)
6579     {
6580       static int first = 1;
6581       if (first)
6582         {
6583           error ("Can't find default package `%s'. Check the CLASSPATH environment variable and the access to the archives.", package_name);
6584           java_error_count++;
6585           first = 0;
6586         }
6587       else
6588         parse_error_context (wfl, "Package `%s' not found in import",
6589                              package_name);
6590       current_jcf = saved_jcf;
6591       return;
6592     }
6593   current_jcf = saved_jcf;
6594 }
6595
6596 /* Possibly find a type in the import on demands specified
6597    types. Returns 1 if an error occured, 0 otherwise. Run throught the
6598    entire list, to detected potential double definitions.  */
6599                  
6600 static int
6601 find_in_imports_on_demand (class_type)
6602      tree class_type;
6603 {
6604   tree node, import, node_to_use = NULL_TREE;
6605   int seen_once = -1;
6606   tree cl = NULL_TREE;
6607
6608   for (import = ctxp->import_demand_list; import; import = TREE_CHAIN (import))
6609     {
6610       const char *id_name;
6611       obstack_grow (&temporary_obstack, 
6612                     IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))),
6613                     IDENTIFIER_LENGTH (EXPR_WFL_NODE (TREE_PURPOSE (import))));
6614       obstack_1grow (&temporary_obstack, '.');
6615       obstack_grow0 (&temporary_obstack, 
6616                      IDENTIFIER_POINTER (TYPE_NAME (class_type)),
6617                      IDENTIFIER_LENGTH (TYPE_NAME (class_type)));
6618       id_name = obstack_finish (&temporary_obstack);
6619               
6620       node = maybe_get_identifier (id_name);
6621       if (node && IS_A_CLASSFILE_NAME (node))
6622         {
6623           if (seen_once < 0)
6624             {
6625               cl = TREE_PURPOSE (import);
6626               seen_once = 1;
6627               node_to_use = node;
6628             }
6629           else
6630             {
6631               seen_once++;
6632               parse_error_context 
6633                 (import, "Type `%s' also potentially defined in package `%s'",
6634                  IDENTIFIER_POINTER (TYPE_NAME (class_type)),
6635                  IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))));
6636             }
6637         }
6638     }
6639
6640   if (seen_once == 1)
6641     {
6642       /* Setup lineno so that it refers to the line of the import (in
6643          case we parse a class file and encounter errors */
6644       tree decl;
6645       int saved_lineno = lineno;
6646       lineno = EXPR_WFL_LINENO (cl);
6647       TYPE_NAME (class_type) = node_to_use;
6648       QUALIFIED_P (TYPE_NAME (class_type)) = 1;
6649       decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
6650       /* If there is no DECL set for the class or if the class isn't
6651          loaded and not seen in source yet, the load */
6652       if (!decl || (!CLASS_LOADED_P (TREE_TYPE (decl))
6653                     && !CLASS_FROM_SOURCE_P (TREE_TYPE (decl))))
6654         load_class (node_to_use, 0);
6655       lineno = saved_lineno;
6656       return check_pkg_class_access (TYPE_NAME (class_type), cl);
6657     }
6658   else
6659     return (seen_once < 0 ? 0 : seen_once); /* It's ok not to have found */
6660 }
6661
6662 /* Add package NAME to the list of package encountered so far. To
6663    speed up class lookup in do_resolve_class, we make sure a
6664    particular package is added only once.  */
6665
6666 static void
6667 register_package (name)
6668      tree name;
6669 {
6670   static struct hash_table _pht, *pht = NULL;
6671
6672   if (!pht)
6673     {
6674       hash_table_init (&_pht, hash_newfunc, 
6675                        java_hash_hash_tree_node, java_hash_compare_tree_node);
6676       pht = &_pht;
6677     }
6678   
6679   if (!hash_lookup (pht, (const hash_table_key) name, FALSE, NULL))
6680     {
6681       package_list = chainon (package_list, build_tree_list (name, NULL));
6682       hash_lookup (pht, (const hash_table_key) name, TRUE, NULL);
6683     }
6684 }
6685
6686 static tree
6687 resolve_package (pkg, next)
6688      tree pkg, *next;
6689 {
6690   tree current, acc;
6691   tree type_name = NULL_TREE;
6692   const char *name = IDENTIFIER_POINTER (EXPR_WFL_NODE (pkg));
6693
6694   /* The trick is to determine when the package name stops and were
6695      the name of something contained in the package starts. Then we
6696      return a fully qualified name of what we want to get. */
6697
6698   /* Do a quick search on well known package names */
6699   if (!strncmp (name, "java.lang.reflect", 17))
6700     {
6701       *next = 
6702         TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg))));
6703       type_name = lookup_package_type (name, 17);
6704     }
6705   else if (!strncmp (name, "java.lang", 9))
6706     {
6707       *next = TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg)));
6708       type_name = lookup_package_type (name, 9);
6709     }
6710
6711   /* If we found something here, return */
6712   if (type_name)
6713     return type_name; 
6714
6715   *next = EXPR_WFL_QUALIFICATION (pkg);
6716
6717   /* Try the current package. */
6718   if (ctxp->package && !strncmp (name, IDENTIFIER_POINTER (ctxp->package),  
6719                                  IDENTIFIER_LENGTH (ctxp->package)))
6720     {
6721       type_name = 
6722         lookup_package_type_and_set_next (name, 
6723                                           IDENTIFIER_LENGTH (ctxp->package), 
6724                                           next );
6725       if (type_name)
6726         return type_name;
6727     }
6728
6729   /* Search in imported package */
6730   for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
6731     {
6732       tree current_pkg_name = EXPR_WFL_NODE (TREE_PURPOSE (current));
6733       int len = IDENTIFIER_LENGTH (current_pkg_name);
6734       if (!strncmp (name, IDENTIFIER_POINTER (current_pkg_name), len))
6735         {
6736           tree left, dummy;
6737           
6738           breakdown_qualified (&left, &dummy, current_pkg_name);
6739           len = IDENTIFIER_LENGTH (left);
6740           type_name = lookup_package_type_and_set_next (name, len, next);
6741           if (type_name)
6742             break;
6743         }
6744     }
6745
6746   /* Try to progressively construct a type name */
6747   if (TREE_CODE (pkg) == EXPR_WITH_FILE_LOCATION)
6748     for (acc = NULL_TREE, current = EXPR_WFL_QUALIFICATION (pkg); 
6749          current; current = TREE_CHAIN (current))
6750       {
6751         acc = merge_qualified_name (acc, EXPR_WFL_NODE (QUAL_WFL (current)));
6752         if ((type_name = resolve_no_layout (acc, NULL_TREE)))
6753           {
6754             type_name = acc;
6755             /* resolve_package should be used in a loop, hence we
6756                point at this one to naturally process the next one at
6757                the next iteration. */
6758             *next = current;
6759             break;
6760           }
6761       }
6762   return type_name;
6763 }
6764
6765 static tree
6766 lookup_package_type_and_set_next (name, len, next)
6767      const char *name;
6768      int len;
6769      tree *next;
6770 {
6771   const char *ptr;
6772   tree type_name = lookup_package_type (name, len);
6773
6774   if (!type_name)
6775     return NULL;
6776   
6777   ptr = IDENTIFIER_POINTER (type_name);
6778   while (ptr && (ptr = strchr (ptr, '.'))) 
6779     {
6780       *next = TREE_CHAIN (*next);
6781       ptr++;
6782     }
6783   return type_name;
6784 }
6785
6786 static tree
6787 lookup_package_type (name, from)
6788      const char *name;
6789      int from;
6790 {
6791   char subname [128];
6792   const char *sub = &name[from+1];
6793   while (*sub != '.' && *sub)
6794     sub++;
6795   strncpy (subname, name, sub-name);
6796   subname [sub-name] = '\0';
6797   return get_identifier (subname);
6798 }
6799
6800 static void
6801 check_inner_class_access (decl, enclosing_decl, cl)
6802      tree decl, enclosing_decl, cl;
6803 {
6804   int access = 0;
6805
6806   /* We don't issue an error message when CL is null. CL can be null
6807      as a result of processing a JDEP crafted by source_start_java_method
6808      for the purpose of patching its parm decl. But the error would
6809      have been already trapped when fixing the method's signature.
6810      DECL can also be NULL in case of earlier errors. */
6811   if (!decl || !cl)
6812     return;
6813
6814   /* We grant access to private and protected inner classes if the
6815      location from where we're trying to access DECL is an enclosing
6816      context for DECL or if both have a common enclosing context. */
6817   if (CLASS_PRIVATE (decl))
6818     access = 1;
6819   if (CLASS_PROTECTED (decl))
6820     access = 2;
6821   if (!access)
6822     return;
6823       
6824   if (common_enclosing_context_p (TREE_TYPE (enclosing_decl),
6825                                   TREE_TYPE (decl))
6826       || enclosing_context_p (TREE_TYPE (enclosing_decl),
6827                               TREE_TYPE (decl)))
6828     return;
6829
6830   parse_error_context (cl, "Can't access %s nested %s %s. Only public classes and interfaces in other packages can be accessed",
6831                        (access == 1 ? "private" : "protected"),
6832                        (CLASS_INTERFACE (decl) ? "interface" : "class"),
6833                        lang_printable_name (decl, 0));
6834 }
6835
6836 /* Check that CLASS_NAME refers to a PUBLIC class. Return 0 if no
6837    access violations were found, 1 otherwise.  */
6838
6839 static int
6840 check_pkg_class_access (class_name, cl)
6841      tree class_name;
6842      tree cl;
6843 {
6844   tree type;
6845
6846   if (!QUALIFIED_P (class_name) || !IDENTIFIER_CLASS_VALUE (class_name))
6847     return 0;
6848
6849   if (!(type = TREE_TYPE (IDENTIFIER_CLASS_VALUE (class_name))))
6850     return 0;
6851
6852   if (!CLASS_PUBLIC (TYPE_NAME (type)))
6853     {
6854       /* Access to a private class within the same package is
6855          allowed. */
6856       tree l, r;
6857       breakdown_qualified (&l, &r, class_name);
6858       if (l == ctxp->package)
6859         return 0;
6860
6861       parse_error_context 
6862         (cl, "Can't access %s `%s'. Only public classes and interfaces in other packages can be accessed",
6863          (CLASS_INTERFACE (TYPE_NAME (type)) ? "interface" : "class"),
6864          IDENTIFIER_POINTER (class_name));
6865       return 1;
6866     }
6867   return 0;
6868 }
6869
6870 /* Local variable declaration. */
6871
6872 static void
6873 declare_local_variables (modifier, type, vlist)
6874      int modifier;
6875      tree type;
6876      tree vlist;
6877 {
6878   tree decl, current, saved_type;
6879   tree type_wfl = NULL_TREE;
6880   int must_chain = 0;
6881   int final_p = 0;
6882
6883   /* Push a new block if statements were seen between the last time we
6884      pushed a block and now. Keep a cound of block to close */
6885   if (BLOCK_EXPR_BODY (GET_CURRENT_BLOCK (current_function_decl)))
6886     {
6887       tree body = GET_CURRENT_BLOCK (current_function_decl);
6888       tree b = enter_block ();
6889       BLOCK_EXPR_ORIGIN (b) = body;
6890     }
6891
6892   if (modifier)
6893     {
6894       int i;
6895       for (i = 0; i <= 10; i++) if (1 << i & modifier) break;
6896       if (modifier == ACC_FINAL)
6897         final_p = 1;
6898       else 
6899         {
6900           parse_error_context 
6901             (ctxp->modifier_ctx [i], 
6902              "Only `final' is allowed as a local variables modifier");
6903           return;
6904         }
6905     }
6906
6907   /* Obtain an incomplete type if TYPE is not complete. TYPE_WFL will
6908      hold the TYPE value if a new incomplete has to be created (as
6909      opposed to being found already existing and reused). */
6910   SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
6911
6912   /* If TYPE is fully resolved and we don't have a reference, make one */
6913   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
6914
6915   /* Go through all the declared variables */
6916   for (current = vlist, saved_type = type; current;
6917        current = TREE_CHAIN (current), type = saved_type)
6918     {
6919       tree other, real_type;
6920       tree wfl  = TREE_PURPOSE (current);
6921       tree name = EXPR_WFL_NODE (wfl);
6922       tree init = TREE_VALUE (current);
6923
6924       /* Process NAME, as it may specify extra dimension(s) for it */
6925       type = build_array_from_name (type, type_wfl, name, &name);
6926
6927       /* Variable redefinition check */
6928       if ((other = lookup_name_in_blocks (name)))
6929         {
6930           variable_redefinition_error (wfl, name, TREE_TYPE (other),
6931                                        DECL_SOURCE_LINE (other));
6932           continue;
6933         }
6934
6935       /* Type adjustment. We may have just readjusted TYPE because
6936          the variable specified more dimensions. Make sure we have
6937          a reference if we can and don't have one already. */
6938       PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
6939
6940       real_type = GET_REAL_TYPE (type);
6941       /* Never layout this decl. This will be done when its scope
6942          will be entered */
6943       decl = build_decl (VAR_DECL, name, real_type);
6944       LOCAL_FINAL (decl) = final_p;
6945       BLOCK_CHAIN_DECL (decl);
6946       
6947       /* If doing xreferencing, replace the line number with the WFL
6948          compound value */
6949       if (flag_emit_xref)
6950         DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (wfl);
6951       
6952       /* Don't try to use an INIT statement when an error was found */
6953       if (init && java_error_count)
6954         init = NULL_TREE;
6955       
6956       /* Add the initialization function to the current function's code */
6957       if (init)
6958         {
6959           /* Name might have been readjusted */
6960           EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = name;
6961           MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
6962           java_method_add_stmt (current_function_decl,
6963                                 build_debugable_stmt (EXPR_WFL_LINECOL (init),
6964                                                       init));
6965         }
6966     
6967       /* Setup dependency the type of the decl */
6968       if (must_chain)
6969         {
6970           jdep *dep;
6971           register_incomplete_type (JDEP_VARIABLE, type_wfl, decl, type);
6972           dep = CLASSD_LAST (ctxp->classd_list);
6973           JDEP_GET_PATCH (dep) = &TREE_TYPE (decl);
6974         }
6975     }
6976   SOURCE_FRONTEND_DEBUG (("Defined locals"));
6977 }
6978
6979 /* Called during parsing. Build decls from argument list.  */
6980
6981 static void
6982 source_start_java_method (fndecl)
6983      tree fndecl;
6984 {
6985   tree tem;
6986   tree parm_decl;
6987   int i;
6988
6989   if (!fndecl)
6990     return;
6991
6992   current_function_decl = fndecl;
6993
6994   /* New scope for the function */
6995   enter_block ();
6996   for (tem = TYPE_ARG_TYPES (TREE_TYPE (fndecl)), i = 0;
6997        tem != end_params_node; tem = TREE_CHAIN (tem), i++)
6998     {
6999       tree type = TREE_VALUE (tem);
7000       tree name = TREE_PURPOSE (tem);
7001       
7002       /* If type is incomplete. Create an incomplete decl and ask for
7003          the decl to be patched later */
7004       if (INCOMPLETE_TYPE_P (type))
7005         {
7006           jdep *jdep;
7007           tree real_type = GET_REAL_TYPE (type);
7008           parm_decl = build_decl (PARM_DECL, name, real_type);
7009           type = obtain_incomplete_type (type);
7010           register_incomplete_type (JDEP_PARM, NULL_TREE, NULL_TREE, type);
7011           jdep = CLASSD_LAST (ctxp->classd_list);
7012           JDEP_MISC (jdep) = name;
7013           JDEP_GET_PATCH (jdep) = &TREE_TYPE (parm_decl);
7014         }
7015       else
7016         parm_decl = build_decl (PARM_DECL, name, type);
7017
7018       /* Remember if a local variable was declared final (via its
7019          TREE_LIST of type/name.) Set LOCAL_FINAL accordingly. */
7020       if (ARG_FINAL_P (tem))
7021         LOCAL_FINAL (parm_decl) = 1;
7022
7023       BLOCK_CHAIN_DECL (parm_decl);
7024     }
7025   tem = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
7026   BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl)) =
7027     nreverse (tem);
7028   DECL_ARG_SLOT_COUNT (current_function_decl) = i;
7029   DECL_MAX_LOCALS (current_function_decl) = i;
7030 }
7031
7032 /* Called during parsing. Creates an artificial method declaration.  */
7033
7034 static tree
7035 create_artificial_method (class, flags, type, name, args)
7036      tree class;
7037      int flags;
7038      tree type, name, args;
7039 {
7040   tree mdecl;
7041
7042   java_parser_context_save_global ();
7043   lineno = 0;                                                               
7044   mdecl = make_node (FUNCTION_TYPE);                                
7045   TREE_TYPE (mdecl) = type;
7046   TYPE_ARG_TYPES (mdecl) = args;
7047   mdecl = add_method (class, flags, name, build_java_signature (mdecl)); 
7048   java_parser_context_restore_global ();
7049   DECL_ARTIFICIAL (mdecl) = 1;                                      
7050   return mdecl;
7051 }
7052
7053 /* Starts the body if an artifical method.  */
7054
7055 static void
7056 start_artificial_method_body (mdecl)
7057      tree mdecl;
7058 {
7059   DECL_SOURCE_LINE (mdecl) = 1;
7060   DECL_SOURCE_LINE_MERGE (mdecl, 1);
7061   source_start_java_method (mdecl);
7062   enter_block ();
7063 }
7064
7065 static void
7066 end_artificial_method_body (mdecl)
7067      tree mdecl;
7068 {
7069   BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)) = exit_block ();
7070   exit_block ();
7071 }
7072
7073 /* Called during expansion. Push decls formerly built from argument
7074    list so they're usable during expansion. */
7075
7076 static void
7077 expand_start_java_method (fndecl)
7078      tree fndecl;
7079 {
7080   tree tem, *ptr;
7081
7082   current_function_decl = fndecl;
7083
7084   if (! quiet_flag)
7085     fprintf (stderr, " [%s.", lang_printable_name (DECL_CONTEXT (fndecl), 0));
7086   announce_function (fndecl);
7087   if (! quiet_flag)
7088     fprintf (stderr, "]");
7089
7090   pushlevel (1);                /* Prepare for a parameter push */
7091   ptr = &DECL_ARGUMENTS (fndecl);
7092   tem  = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
7093   while (tem)
7094     {
7095       tree next = TREE_CHAIN (tem);
7096       tree type = TREE_TYPE (tem);
7097       if (PROMOTE_PROTOTYPES
7098           && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
7099           && INTEGRAL_TYPE_P (type))
7100         type = integer_type_node;
7101       DECL_ARG_TYPE (tem) = type;
7102       layout_decl (tem, 0);
7103       pushdecl (tem);
7104       *ptr = tem;
7105       ptr = &TREE_CHAIN (tem);
7106       tem = next;
7107     }
7108   *ptr = NULL_TREE;
7109   pushdecl_force_head (DECL_ARGUMENTS (fndecl));
7110   lineno = DECL_SOURCE_LINE_FIRST (fndecl);
7111 }
7112
7113 /* Terminate a function and expand its body.  */
7114
7115 static void
7116 source_end_java_method ()
7117 {
7118   tree fndecl = current_function_decl;
7119   int flag_asynchronous_exceptions = asynchronous_exceptions;
7120
7121   if (!fndecl)
7122     return;
7123
7124   java_parser_context_save_global ();
7125   lineno = ctxp->last_ccb_indent1;
7126
7127   /* Set EH language codes */
7128   java_set_exception_lang_code ();
7129
7130   /* Turn function bodies with only a NOP expr null, so they don't get
7131      generated at all and we won't get warnings when using the -W
7132      -Wall flags. */
7133   if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) == empty_stmt_node)
7134     BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) = NULL_TREE;
7135
7136   /* Generate function's code */
7137   if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl))
7138       && ! flag_emit_class_files
7139       && ! flag_emit_xref)
7140     expand_expr_stmt (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)));
7141
7142   /* pop out of its parameters */
7143   pushdecl_force_head (DECL_ARGUMENTS (fndecl));
7144   poplevel (1, 0, 1);
7145   BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
7146
7147   /* Generate rtl for function exit.  */
7148   if (! flag_emit_class_files && ! flag_emit_xref)
7149     {
7150       lineno = DECL_SOURCE_LINE_LAST (fndecl);
7151       /* Emit catch-finally clauses */
7152       emit_handlers ();
7153       expand_function_end (input_filename, lineno, 0);
7154
7155       /* FIXME: If the current method contains any exception handlers,
7156          force asynchronous_exceptions: this is necessary because signal
7157          handlers in libjava may throw exceptions.  This is far from being
7158          a perfect solution, but it's better than doing nothing at all.*/
7159       if (catch_clauses)
7160         asynchronous_exceptions = 1;
7161
7162       /* Run the optimizers and output assembler code for this function. */
7163       rest_of_compilation (fndecl);
7164     }
7165
7166   current_function_decl = NULL_TREE;
7167   permanent_allocation (1);
7168   java_parser_context_restore_global ();
7169   asynchronous_exceptions = flag_asynchronous_exceptions;
7170 }
7171
7172 /* Record EXPR in the current function block. Complements compound
7173    expression second operand if necessary.  */
7174
7175 tree
7176 java_method_add_stmt (fndecl, expr)
7177      tree fndecl, expr;
7178 {
7179   if (!GET_CURRENT_BLOCK (fndecl))
7180     return NULL_TREE;
7181   return add_stmt_to_block (GET_CURRENT_BLOCK (fndecl), NULL_TREE, expr);
7182 }
7183
7184 static tree
7185 add_stmt_to_block (b, type, stmt)
7186      tree b, type, stmt;
7187 {
7188   tree body = BLOCK_EXPR_BODY (b), c;
7189   
7190   if (java_error_count)
7191     return body;
7192     
7193   if ((c = add_stmt_to_compound (body, type, stmt)) == body)
7194     return body;
7195
7196   BLOCK_EXPR_BODY (b) = c;
7197   TREE_SIDE_EFFECTS (c) = 1;
7198   return c;
7199 }
7200
7201 /* Add STMT to EXISTING if possible, otherwise create a new
7202    COMPOUND_EXPR and add STMT to it. */
7203
7204 static tree
7205 add_stmt_to_compound (existing, type, stmt)
7206      tree existing, type, stmt;
7207 {
7208   if (existing)
7209     return build (COMPOUND_EXPR, type, existing, stmt);
7210   else
7211     return stmt;
7212 }
7213
7214 /* Hold THIS for the scope of the current public method decl.  */
7215 static tree current_this;
7216
7217 void java_layout_seen_class_methods ()
7218 {
7219   tree previous_list = all_class_list;
7220   tree end = NULL_TREE;
7221   tree current;
7222
7223   while (1)
7224     {
7225       for (current = previous_list; 
7226            current != end; current = TREE_CHAIN (current))
7227         layout_class_methods (TREE_TYPE (TREE_VALUE (current)));
7228       
7229       if (previous_list != all_class_list)
7230         {
7231           end = previous_list;
7232           previous_list = all_class_list;
7233         }
7234       else
7235         break;
7236     }
7237 }
7238
7239 void
7240 java_reorder_fields ()
7241 {
7242   static tree stop_reordering = NULL_TREE;
7243
7244   tree current;
7245   for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
7246     {
7247       current_class = TREE_TYPE (TREE_VALUE (current));
7248
7249       if (current_class == stop_reordering)
7250         break;
7251
7252       /* Reverse the fields, but leave the dummy field in front.
7253          Fields are already ordered for Object and Class */
7254       if (TYPE_FIELDS (current_class) && current_class != object_type_node
7255           && current_class != class_type_node)
7256       {
7257         /* If the dummy field is there, reverse the right fields and
7258            just layout the type for proper fields offset */
7259         if (!DECL_NAME (TYPE_FIELDS (current_class)))
7260           {
7261             tree fields = TYPE_FIELDS (current_class);
7262             TREE_CHAIN (fields) = nreverse (TREE_CHAIN (fields));
7263             TYPE_SIZE (current_class) = NULL_TREE;
7264           }
7265         /* We don't have a dummy field, we need to layout the class,
7266            after having reversed the fields */
7267         else
7268           {
7269             TYPE_FIELDS (current_class) = 
7270               nreverse (TYPE_FIELDS (current_class));
7271             TYPE_SIZE (current_class) = NULL_TREE;
7272           }
7273       }
7274     }
7275   stop_reordering = TREE_TYPE (TREE_VALUE (ctxp->gclass_list));
7276 }
7277
7278 /* Layout the methods of all classes loaded in one way on an
7279    other. Check methods of source parsed classes. Then reorder the
7280    fields and layout the classes or the type of all source parsed
7281    classes */
7282
7283 void
7284 java_layout_classes ()
7285 {
7286   tree current;
7287   int save_error_count = java_error_count;
7288
7289   /* Layout the methods of all classes seen so far */
7290   java_layout_seen_class_methods ();
7291   java_parse_abort_on_error ();
7292   all_class_list = NULL_TREE;
7293
7294   /* Then check the methods of all parsed classes */
7295   for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
7296     if (CLASS_FROM_SOURCE_P (TREE_TYPE (TREE_VALUE (current))))
7297       CHECK_METHODS (TREE_VALUE (current));
7298   java_parse_abort_on_error ();
7299
7300   for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
7301     {
7302       current_class = TREE_TYPE (TREE_VALUE (current));
7303       layout_class (current_class);
7304
7305       /* From now on, the class is considered completely loaded */
7306       CLASS_LOADED_P (current_class) = 1;
7307
7308       /* Error reported by the caller */
7309       if (java_error_count)
7310         return;
7311     }
7312
7313   /* We might have reloaded classes durign the process of laying out
7314      classes for code generation. We must layout the methods of those
7315      late additions, as constructor checks might use them */
7316   java_layout_seen_class_methods ();
7317   java_parse_abort_on_error ();
7318 }
7319
7320 /* Expand methods in the current set of classes rememebered for
7321    generation.  */
7322
7323 static void
7324 java_complete_expand_classes ()
7325 {
7326   tree current;
7327
7328   do_not_fold = flag_emit_xref;
7329
7330   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
7331     if (!INNER_CLASS_DECL_P (current))
7332       java_complete_expand_class (current);
7333 }
7334
7335 /* Expand the methods found in OUTER, starting first by OUTER's inner
7336    classes, if any.  */
7337
7338 static void
7339 java_complete_expand_class (outer)
7340      tree outer;
7341 {
7342   tree inner_list;
7343
7344   set_nested_class_simple_name_value (outer, 1); /* Set */
7345
7346   /* We need to go after all inner classes and start expanding them,
7347      starting with most nested ones. We have to do that because nested
7348      classes might add functions to outer classes */
7349
7350   for (inner_list = DECL_INNER_CLASS_LIST (outer);
7351        inner_list; inner_list = TREE_CHAIN (inner_list))
7352     java_complete_expand_class (TREE_PURPOSE (inner_list));
7353
7354   java_complete_expand_methods (outer);
7355   set_nested_class_simple_name_value (outer, 0); /* Reset */
7356 }
7357
7358 /* Expand methods registered in CLASS_DECL. The general idea is that
7359    we expand regular methods first. This allows us get an estimate on
7360    how outer context local alias fields are really used so we can add
7361    to the constructor just enough code to initialize them properly (it
7362    also lets us generate $finit$ correctly.) Then we expand the
7363    constructors and then <clinit>.  */
7364
7365 static void
7366 java_complete_expand_methods (class_decl)
7367      tree class_decl;
7368 {
7369   tree clinit, finit, decl, first_decl;
7370
7371   current_class = TREE_TYPE (class_decl);
7372
7373   /* Initialize a new constant pool */
7374   init_outgoing_cpool ();
7375
7376   /* Pre-expand <clinit> to figure whether we really need it or
7377      not. If we do need it, we pre-expand the static fields so they're
7378      ready to be used somewhere else. <clinit> will be fully expanded
7379      after we processed the constructors. */
7380   first_decl = TYPE_METHODS (current_class);
7381   clinit = maybe_generate_pre_expand_clinit (current_class);
7382
7383   /* Then generate $finit$ (if we need to) because constructor will
7384    try to use it.*/
7385   if (TYPE_FINIT_STMT_LIST (current_class))
7386     {
7387       finit = generate_finit (current_class);
7388       java_complete_expand_method (finit);
7389     }
7390
7391   /* Now do the constructors */
7392   for (decl = first_decl ; !java_error_count && decl; decl = TREE_CHAIN (decl))
7393     {
7394       int no_body;
7395
7396       if (!DECL_CONSTRUCTOR_P (decl))
7397         continue;
7398       
7399       no_body = !DECL_FUNCTION_BODY (decl);
7400       /* Don't generate debug info on line zero when expanding a
7401          generated constructor. */
7402       if (no_body)
7403         restore_line_number_status (1);
7404
7405       java_complete_expand_method (decl);
7406       
7407       if (no_body)
7408         restore_line_number_status (0);
7409     }
7410
7411   /* First, do the ordinary methods. */
7412   for (decl = first_decl; decl; decl = TREE_CHAIN (decl))
7413     {
7414       /* Skip abstract or native methods -- but do handle native
7415          methods when generating JNI stubs.  */
7416       if (METHOD_ABSTRACT (decl)
7417           || (! flag_jni && METHOD_NATIVE (decl))
7418           || DECL_CONSTRUCTOR_P (decl) || DECL_CLINIT_P (decl))
7419         continue;
7420
7421       if (METHOD_NATIVE (decl))
7422         {
7423           tree body = build_jni_stub (decl);
7424           BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (decl)) = body;
7425         }
7426
7427       java_complete_expand_method (decl);
7428     }
7429
7430   /* If there is indeed a <clinit>, fully expand it now */
7431   if (clinit)
7432     {
7433       /* Prevent the use of `this' inside <clinit> */
7434       ctxp->explicit_constructor_p = 1;
7435       java_complete_expand_method (clinit);
7436       ctxp->explicit_constructor_p = 0;
7437     }
7438   
7439   /* We might have generated a class$ that we now want to expand */
7440   if (TYPE_DOT_CLASS (current_class))
7441     java_complete_expand_method (TYPE_DOT_CLASS (current_class));
7442
7443   /* Now verify constructor circularity (stop after the first one we
7444      prove wrong.) */
7445   if (!CLASS_INTERFACE (class_decl))
7446     for (decl = TYPE_METHODS (current_class); decl; decl = TREE_CHAIN (decl))
7447       if (DECL_CONSTRUCTOR_P (decl) 
7448           && verify_constructor_circularity (decl, decl))
7449         break;
7450
7451   /* Save the constant pool. We'll need to restore it later. */
7452   TYPE_CPOOL (current_class) = outgoing_cpool;
7453 }
7454
7455 /* Hold a list of catch clauses list. The first element of this list is
7456    the list of the catch clauses of the currently analysed try block. */
7457 static tree currently_caught_type_list;
7458
7459 /* Attempt to create <clinit>. Pre-expand static fields so they can be
7460    safely used in some other methods/constructors.  */
7461
7462 static tree
7463 maybe_generate_pre_expand_clinit (class_type)
7464      tree class_type;
7465 {
7466   tree current, mdecl;
7467
7468   if (!TYPE_CLINIT_STMT_LIST (class_type))
7469     return NULL_TREE;
7470
7471   /* Go through all static fields and pre expand them */
7472   for (current = TYPE_FIELDS (class_type); current; 
7473        current = TREE_CHAIN (current))
7474     if (FIELD_STATIC (current))
7475       build_field_ref (NULL_TREE, class_type, DECL_NAME (current));
7476
7477   /* Then build the <clinit> method */
7478   mdecl = create_artificial_method (class_type, ACC_STATIC, void_type_node,
7479                                     clinit_identifier_node, end_params_node);
7480   layout_class_method (class_type, CLASSTYPE_SUPER (class_type),
7481                        mdecl, NULL_TREE);
7482   start_artificial_method_body (mdecl);
7483
7484   /* We process the list of assignment we produced as the result of
7485      the declaration of initialized static field and add them as
7486      statement to the <clinit> method. */
7487   for (current = TYPE_CLINIT_STMT_LIST (class_type); current;
7488        current = TREE_CHAIN (current))
7489     {
7490       tree stmt = current;
7491       /* We build the assignment expression that will initialize the
7492          field to its value. There are strict rules on static
7493          initializers (8.5). FIXME */
7494       if (TREE_CODE (stmt) != BLOCK && stmt != empty_stmt_node)
7495         stmt = build_debugable_stmt (EXPR_WFL_LINECOL (stmt), stmt);
7496       java_method_add_stmt (mdecl, stmt);
7497     }
7498
7499   end_artificial_method_body (mdecl);
7500
7501   /* Now we want to place <clinit> as the last method (because we need
7502      it at least for interface so that it doesn't interfere with the
7503      dispatch table based lookup. */
7504   if (TREE_CHAIN (TYPE_METHODS (class_type)))
7505     {
7506       current = TREE_CHAIN (TYPE_METHODS (class_type));
7507       TYPE_METHODS (class_type) = current;
7508
7509       while (TREE_CHAIN (current))
7510         current = TREE_CHAIN (current);
7511
7512       TREE_CHAIN (current) = mdecl;
7513       TREE_CHAIN (mdecl) = NULL_TREE;
7514     }
7515
7516   return mdecl;
7517 }
7518
7519 /* See whether we could get rid of <clinit>. Criteria are: all static
7520    final fields have constant initial values and the body of <clinit>
7521    is empty. Return 1 if <clinit> was discarded, 0 otherwise. */
7522
7523 static int
7524 maybe_yank_clinit (mdecl)
7525      tree mdecl;
7526 {
7527   tree type, current;
7528   tree fbody, bbody;
7529   
7530   if (!DECL_CLINIT_P (mdecl))
7531     return 0;
7532   
7533   /* If the body isn't empty, then we keep <clinit> */
7534   fbody = DECL_FUNCTION_BODY (mdecl);
7535   if ((bbody = BLOCK_EXPR_BODY (fbody)))
7536     bbody = BLOCK_EXPR_BODY (bbody);
7537   if (bbody && bbody != empty_stmt_node)
7538     return 0;
7539   
7540   type = DECL_CONTEXT (mdecl);
7541   current = TYPE_FIELDS (type);
7542
7543   for (current = (current ? TREE_CHAIN (current) : current); 
7544        current; current = TREE_CHAIN (current))
7545     if (!(FIELD_STATIC (current) && FIELD_FINAL (current)
7546           && DECL_INITIAL (current) && TREE_CONSTANT (DECL_INITIAL (current))))
7547       break;
7548
7549   if (current)
7550     return 0;
7551
7552   /* Get rid of <clinit> in the class' list of methods */
7553   if (TYPE_METHODS (type) == mdecl)
7554     TYPE_METHODS (type) = TREE_CHAIN (mdecl);
7555   else
7556     for (current = TYPE_METHODS (type); current; 
7557          current = TREE_CHAIN (current))
7558       if (TREE_CHAIN (current) == mdecl)
7559         {
7560           TREE_CHAIN (current) = TREE_CHAIN (mdecl);
7561           break;
7562         }
7563
7564   return 1;
7565 }
7566
7567
7568 /* Complete and expand a method.  */
7569
7570 static void
7571 java_complete_expand_method (mdecl)
7572      tree mdecl;
7573 {
7574   int yank_clinit = 0;
7575
7576   current_function_decl = mdecl;
7577   /* Fix constructors before expanding them */
7578   if (DECL_CONSTRUCTOR_P (mdecl))
7579     fix_constructors (mdecl);
7580   
7581   /* Expand functions that have a body */
7582   if (DECL_FUNCTION_BODY (mdecl))
7583     {
7584       tree fbody = DECL_FUNCTION_BODY (mdecl);
7585       tree block_body = BLOCK_EXPR_BODY (fbody);
7586       tree exception_copy = NULL_TREE;
7587       expand_start_java_method (mdecl);
7588       build_result_decl (mdecl);
7589
7590       current_this 
7591         = (!METHOD_STATIC (mdecl) ? 
7592            BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl)) : NULL_TREE);
7593
7594       /* Purge the `throws' list of unchecked exceptions. If we're
7595          doing xref, save a copy of the list and re-install it
7596          later. */
7597       if (flag_emit_xref)
7598         exception_copy = copy_list (DECL_FUNCTION_THROWS (mdecl));
7599
7600       purge_unchecked_exceptions (mdecl);
7601
7602       /* Install exceptions thrown with `throws' */
7603       PUSH_EXCEPTIONS (DECL_FUNCTION_THROWS (mdecl));
7604
7605       if (block_body != NULL_TREE)
7606         {
7607           block_body = java_complete_tree (block_body);
7608
7609           if (! flag_emit_xref && ! METHOD_NATIVE (mdecl))
7610             check_for_initialization (block_body);
7611           ctxp->explicit_constructor_p = 0;
7612         }
7613
7614       BLOCK_EXPR_BODY (fbody) = block_body;
7615
7616       /* If we saw a return but couldn't evaluate it properly, we'll
7617          have an error_mark_node here. */
7618       if (block_body != error_mark_node
7619           && (block_body == NULL_TREE || CAN_COMPLETE_NORMALLY (block_body))
7620           && TREE_CODE (TREE_TYPE (TREE_TYPE (mdecl))) != VOID_TYPE
7621           && !flag_emit_xref)
7622         missing_return_error (current_function_decl);
7623
7624       /* Check wether we could just get rid of clinit, now the picture
7625          is complete. */
7626       if (!(yank_clinit = maybe_yank_clinit (mdecl)))
7627         complete_start_java_method (mdecl); 
7628       
7629       /* Don't go any further if we've found error(s) during the
7630          expansion */
7631       if (!java_error_count && !yank_clinit)
7632         source_end_java_method ();
7633       else
7634         {
7635           if (java_error_count)
7636             pushdecl_force_head (DECL_ARGUMENTS (mdecl));
7637           poplevel (1, 0, 1);
7638         }
7639
7640       /* Pop the exceptions and sanity check */
7641       POP_EXCEPTIONS();
7642       if (currently_caught_type_list)
7643         fatal ("Exception list non empty - java_complete_expand_method");
7644
7645       if (flag_emit_xref)
7646         DECL_FUNCTION_THROWS (mdecl) = exception_copy;
7647     }
7648 }
7649
7650 \f
7651
7652 /* This section of the code deals with accessing enclosing context
7653    fields either directly by using the relevant access to this$<n> or
7654    by invoking an access method crafted for that purpose.  */
7655
7656 /* Build the necessary access from an inner class to an outer
7657    class. This routine could be optimized to cache previous result
7658    (decl, current_class and returned access).  When an access method
7659    needs to be generated, it always takes the form of a read. It might
7660    be later turned into a write by calling outer_field_access_fix.  */
7661
7662 static tree
7663 build_outer_field_access (id, decl)
7664      tree id, decl;
7665 {
7666   tree access = NULL_TREE;
7667   tree ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class)));
7668
7669   /* If decl's class is the direct outer class of the current_class,
7670      build the access as `this$<n>.<field>'. Not that we will break
7671      the `private' barrier if we're not emitting bytecodes. */
7672   if (ctx == DECL_CONTEXT (decl) 
7673       && (!FIELD_PRIVATE (decl) || !flag_emit_class_files ))
7674     {
7675       tree thisn = build_current_thisn (current_class);
7676       access = make_qualified_primary (build_wfl_node (thisn), 
7677                                        id, EXPR_WFL_LINECOL (id));
7678     }
7679   /* Otherwise, generate access methods to outer this and access the
7680      field (either using an access method or by direct access.) */
7681   else
7682     {
7683       int lc = EXPR_WFL_LINECOL (id);
7684
7685       /* Now we chain the required number of calls to the access$0 to
7686          get a hold to the enclosing instance we need, and the we
7687          build the field access. */
7688       access = build_access_to_thisn (ctx, DECL_CONTEXT (decl), lc);
7689
7690       /* If the field is private and we're generating bytecode, then
7691          we generate an access method */
7692       if (FIELD_PRIVATE (decl) && flag_emit_class_files )
7693         {
7694           tree name = build_outer_field_access_methods (decl);
7695           access = build_outer_field_access_expr (lc, DECL_CONTEXT (decl),
7696                                                   name, access, NULL_TREE);
7697         }
7698       /* Otherwise we use `access$(this$<j>). ... access$(this$<i>).<field>'.
7699          Once again we break the `private' access rule from a foreign
7700          class. */
7701       else
7702         access = make_qualified_primary (access, id, lc);
7703     }
7704   return resolve_expression_name (access, NULL);
7705 }
7706
7707 /* Return a non zero value if NODE describes an outer field inner
7708    access.  */
7709
7710 static int
7711 outer_field_access_p (type, decl)
7712     tree type, decl;
7713 {
7714   if (!INNER_CLASS_TYPE_P (type) 
7715       || TREE_CODE (decl) != FIELD_DECL
7716       || DECL_CONTEXT (decl) == type)
7717     return 0;
7718
7719   for (type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))); ;
7720        type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))))
7721     {
7722       if (type == DECL_CONTEXT (decl))
7723         return 1;
7724       if (!DECL_CONTEXT (TYPE_NAME (type)))
7725         break;
7726     }
7727
7728   return 0;
7729 }
7730
7731 /* Return a non zero value if NODE represents an outer field inner
7732    access that was been already expanded. As a side effect, it returns
7733    the name of the field being accessed and the argument passed to the
7734    access function, suitable for a regeneration of the access method
7735    call if necessary. */
7736
7737 static int
7738 outer_field_expanded_access_p (node, name, arg_type, arg)
7739     tree node, *name, *arg_type, *arg;
7740 {
7741   int identified = 0;
7742
7743   if (TREE_CODE (node) != CALL_EXPR)
7744     return 0;
7745
7746   /* Well, gcj generates slightly different tree nodes when compiling
7747      to native or bytecodes. It's the case for function calls. */
7748
7749   if (flag_emit_class_files 
7750       && TREE_CODE (node) == CALL_EXPR
7751       && OUTER_FIELD_ACCESS_IDENTIFIER_P (DECL_NAME (TREE_OPERAND (node, 0))))
7752     identified = 1;
7753   else if (!flag_emit_class_files)
7754     {
7755       node = TREE_OPERAND (node, 0);
7756       
7757       if (node && TREE_OPERAND (node, 0)
7758           && TREE_CODE (TREE_OPERAND (node, 0)) == ADDR_EXPR)
7759         {
7760           node = TREE_OPERAND (node, 0);
7761           if (TREE_OPERAND (node, 0)
7762               && TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL
7763               && (OUTER_FIELD_ACCESS_IDENTIFIER_P 
7764                   (DECL_NAME (TREE_OPERAND (node, 0)))))
7765             identified = 1;
7766         }
7767     }
7768
7769   if (identified && name && arg_type && arg)
7770     {
7771       tree argument = TREE_OPERAND (node, 1);
7772       *name = DECL_NAME (TREE_OPERAND (node, 0));
7773       *arg_type = TREE_TYPE (TREE_TYPE (TREE_VALUE (argument)));
7774       *arg = TREE_VALUE (argument);
7775     }
7776   return identified;
7777 }
7778
7779 /* Detect in NODE an outer field read access from an inner class and
7780    transform it into a write with RHS as an argument. This function is
7781    called from the java_complete_lhs when an assignment to a LHS can
7782    be identified. */
7783
7784 static tree
7785 outer_field_access_fix (wfl, node, rhs)
7786     tree wfl, node, rhs;
7787 {
7788   tree name, arg_type, arg;
7789   
7790   if (outer_field_expanded_access_p (node, &name, &arg_type, &arg))
7791     {
7792       /* At any rate, check whether we're trying to assign a value to
7793          a final. */
7794       tree accessed = (JDECL_P (node) ? node : 
7795                        (TREE_CODE (node) == COMPONENT_REF ? 
7796                         TREE_OPERAND (node, 1) : node));
7797       if (check_final_assignment (accessed, wfl))
7798         return error_mark_node;
7799   
7800       node = build_outer_field_access_expr (EXPR_WFL_LINECOL (wfl), 
7801                                             arg_type, name, arg, rhs);
7802       return java_complete_tree (node);
7803     }
7804   return NULL_TREE;
7805 }
7806
7807 /* Construct the expression that calls an access method:
7808      <type>.access$<n>(<arg1> [, <arg2>]); 
7809
7810    ARG2 can be NULL and will be omitted in that case. It will denote a
7811    read access.  */
7812
7813 static tree
7814 build_outer_field_access_expr (lc, type, access_method_name, arg1, arg2)
7815     int lc;
7816     tree type, access_method_name, arg1, arg2;
7817 {
7818   tree args, cn, access;
7819
7820   args = arg1 ? arg1 : 
7821     build_wfl_node (build_current_thisn (current_class));
7822   args = build_tree_list (NULL_TREE, args);
7823
7824   if (arg2)
7825     args = tree_cons (NULL_TREE, arg2, args);
7826
7827   access = build_method_invocation (build_wfl_node (access_method_name), args);
7828   cn = build_wfl_node (DECL_NAME (TYPE_NAME (type)));
7829   return make_qualified_primary (cn, access, lc);
7830 }
7831
7832 static tree
7833 build_new_access_id ()
7834 {
7835   static int access_n_counter = 1;
7836   char buffer [128];
7837
7838   sprintf (buffer, "access$%d", access_n_counter++);
7839   return get_identifier (buffer);
7840 }
7841
7842 /* Create the static access functions for the outer field DECL. We define a
7843    read:
7844      TREE_TYPE (<field>) access$<n> (DECL_CONTEXT (<field>) inst$) {
7845        return inst$.field;
7846      }
7847    and a write access:
7848      TREE_TYPE (<field>) access$<n> (DECL_CONTEXT (<field>) inst$,
7849                                      TREE_TYPE (<field>) value$) {
7850        return inst$.field = value$;
7851      }
7852    We should have a usage flags on the DECL so we can lazily turn the ones
7853    we're using for code generation. FIXME.
7854 */
7855
7856 static tree
7857 build_outer_field_access_methods (decl)
7858     tree decl;
7859 {
7860   tree id, args, stmt, mdecl;
7861   
7862   /* Check point, to be removed. FIXME */
7863   if (FIELD_INNER_ACCESS (decl) 
7864       && TREE_CODE (FIELD_INNER_ACCESS (decl)) != IDENTIFIER_NODE)
7865     abort ();
7866
7867   if (FIELD_INNER_ACCESS (decl))
7868     return FIELD_INNER_ACCESS (decl);
7869
7870   push_obstacks (&permanent_obstack, &permanent_obstack);
7871
7872   /* Create the identifier and a function named after it. */
7873   id = build_new_access_id ();
7874
7875   /* The identifier is marked as bearing the name of a generated write
7876      access function for outer field accessed from inner classes. */
7877   OUTER_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
7878
7879   /* Create the read access */
7880   args = build_tree_list (inst_id, build_pointer_type (DECL_CONTEXT (decl)));
7881   TREE_CHAIN (args) = end_params_node;
7882   stmt = make_qualified_primary (build_wfl_node (inst_id),
7883                                  build_wfl_node (DECL_NAME (decl)), 0);
7884   stmt = build_return (0, stmt);
7885   mdecl = build_outer_field_access_method (DECL_CONTEXT (decl), 
7886                                            TREE_TYPE (decl), id, args, stmt);
7887   DECL_FUNCTION_ACCESS_DECL (mdecl) = decl;
7888
7889   /* Create the write access method */
7890   args = build_tree_list (inst_id, build_pointer_type (DECL_CONTEXT (decl)));
7891   TREE_CHAIN (args) = build_tree_list (wpv_id, TREE_TYPE (decl));
7892   TREE_CHAIN (TREE_CHAIN (args)) = end_params_node;
7893   stmt = make_qualified_primary (build_wfl_node (inst_id),
7894                                  build_wfl_node (DECL_NAME (decl)), 0);
7895   stmt = build_return (0, build_assignment (ASSIGN_TK, 0, stmt,
7896                                             build_wfl_node (wpv_id)));
7897
7898   mdecl = build_outer_field_access_method (DECL_CONTEXT (decl), 
7899                                            TREE_TYPE (decl), id, args, stmt);
7900   DECL_FUNCTION_ACCESS_DECL (mdecl) = decl;
7901   pop_obstacks ();
7902
7903   /* Return the access name */
7904   return FIELD_INNER_ACCESS (decl) = id;
7905 }
7906
7907 /* Build an field access method NAME.  */
7908
7909 static tree 
7910 build_outer_field_access_method (class, type, name, args, body)
7911     tree class, type, name, args, body;
7912 {
7913   tree saved_current_function_decl, mdecl;
7914
7915   /* Create the method */
7916   mdecl = create_artificial_method (class, ACC_STATIC, type, name, args);
7917   fix_method_argument_names (args, mdecl);
7918   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
7919
7920   /* Attach the method body. */
7921   saved_current_function_decl = current_function_decl;
7922   start_artificial_method_body (mdecl);
7923   java_method_add_stmt (mdecl, body);
7924   end_artificial_method_body (mdecl);
7925   current_function_decl = saved_current_function_decl;
7926
7927   return mdecl;
7928 }
7929
7930 \f
7931 /* This section deals with building access function necessary for
7932    certain kinds of method invocation from inner classes.  */
7933
7934 static tree
7935 build_outer_method_access_method (decl)
7936     tree decl;
7937 {
7938   tree saved_current_function_decl, mdecl;
7939   tree args = NULL_TREE, call_args = NULL_TREE;
7940   tree carg, id, body, class;
7941   char buffer [80];
7942   int parm_id_count = 0;
7943
7944   /* Test this abort with an access to a private field */
7945   if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), "access$"))
7946     abort ();
7947
7948   /* Check the cache first */
7949   if (DECL_FUNCTION_INNER_ACCESS (decl))
7950     return DECL_FUNCTION_INNER_ACCESS (decl);
7951
7952   class = DECL_CONTEXT (decl);
7953
7954   /* Obtain an access identifier and mark it */
7955   id = build_new_access_id ();
7956   OUTER_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
7957
7958   push_obstacks (&permanent_obstack, &permanent_obstack);
7959
7960   carg = TYPE_ARG_TYPES (TREE_TYPE (decl));
7961   /* Create the arguments, as much as the original */
7962   for (; carg && carg != end_params_node; 
7963        carg = TREE_CHAIN (carg))
7964     {
7965       sprintf (buffer, "write_parm_value$%d", parm_id_count++);
7966       args = chainon (args, build_tree_list (get_identifier (buffer), 
7967                                              TREE_VALUE (carg)));
7968     }
7969   args = chainon (args, end_params_node);
7970
7971   /* Create the method */
7972   mdecl = create_artificial_method (class, ACC_STATIC, 
7973                                     TREE_TYPE (TREE_TYPE (decl)), id, args);
7974   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
7975   /* There is a potential bug here. We should be able to use
7976      fix_method_argument_names, but then arg names get mixed up and
7977      eventually a constructor will have its this$0 altered and the
7978      outer context won't be assignment properly. The test case is
7979      stub.java FIXME */
7980   TYPE_ARG_TYPES (TREE_TYPE (mdecl)) = args;
7981
7982   /* Attach the method body. */
7983   saved_current_function_decl = current_function_decl;
7984   start_artificial_method_body (mdecl);
7985
7986   /* The actual method invocation uses the same args. When invoking a
7987      static methods that way, we don't want to skip the first
7988      argument. */
7989   carg = args;
7990   if (!METHOD_STATIC (decl))
7991     carg = TREE_CHAIN (carg);
7992   for (; carg && carg != end_params_node; carg = TREE_CHAIN (carg))
7993     call_args = tree_cons (NULL_TREE, build_wfl_node (TREE_PURPOSE (carg)),
7994                            call_args);
7995
7996   body = build_method_invocation (build_wfl_node (DECL_NAME (decl)), 
7997                                   call_args);
7998   if (!METHOD_STATIC (decl))
7999     body = make_qualified_primary (build_wfl_node (TREE_PURPOSE (args)), 
8000                                    body, 0);
8001   if (TREE_TYPE (TREE_TYPE (decl)) != void_type_node)
8002     body = build_return (0, body);
8003   java_method_add_stmt (mdecl,body);
8004   end_artificial_method_body (mdecl);
8005   current_function_decl = saved_current_function_decl;
8006   pop_obstacks ();
8007
8008   /* Back tag the access function so it know what it accesses */
8009   DECL_FUNCTION_ACCESS_DECL (decl) = mdecl;
8010
8011   /* Tag the current method so it knows it has an access generated */
8012   return DECL_FUNCTION_INNER_ACCESS (decl) = mdecl;
8013 }
8014
8015 \f
8016 /* This section of the code deals with building expressions to access
8017    the enclosing instance of an inner class. The enclosing instance is
8018    kept in a generated field called this$<n>, with <n> being the
8019    inner class nesting level (starting from 0.)  */
8020     
8021 /* Build an access to a given this$<n>, possibly by chaining access
8022    call to others. Access methods to this$<n> are build on the fly if
8023    necessary */
8024
8025 static tree
8026 build_access_to_thisn (from, to, lc)
8027      tree from, to;
8028      int lc;
8029 {
8030   tree access = NULL_TREE;
8031
8032   while (from != to)
8033     {
8034       tree access0_wfl, cn;
8035
8036       maybe_build_thisn_access_method (from);
8037       access0_wfl = build_wfl_node (access0_identifier_node);
8038       cn = build_wfl_node (DECL_NAME (TYPE_NAME (from)));
8039       EXPR_WFL_LINECOL (access0_wfl) = lc;
8040       
8041       if (!access)
8042         {
8043           access = build_current_thisn (current_class);
8044           access = build_wfl_node (access);
8045         }
8046       access = build_tree_list (NULL_TREE, access);
8047       access = build_method_invocation (access0_wfl, access);
8048       access = make_qualified_primary (cn, access, lc);
8049       
8050       from = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (from)));
8051     }
8052   return access;
8053 }
8054
8055 /* Build an access function to the this$<n> local to TYPE. NULL_TREE
8056    is returned if nothing needs to be generated. Otherwise, the method
8057    generated and a method decl is returned.  
8058
8059    NOTE: These generated methods should be declared in a class file
8060    attribute so that they can't be referred to directly.  */
8061
8062 static tree
8063 maybe_build_thisn_access_method (type)
8064     tree type;
8065 {
8066   tree mdecl, args, stmt, rtype;
8067   tree saved_current_function_decl;
8068
8069   /* If TYPE is a top-level class, no access method is required.
8070      If there already is such an access method, bail out. */
8071   if (CLASS_ACCESS0_GENERATED_P (type) || !INNER_CLASS_TYPE_P (type))
8072     return NULL_TREE;
8073
8074   /* We generate the method. The method looks like:
8075      static <outer_of_type> access$0 (<type> inst$) { return inst$.this$<n>; }
8076   */
8077   push_obstacks (&permanent_obstack, &permanent_obstack);
8078   args = build_tree_list (inst_id, build_pointer_type (type));
8079   TREE_CHAIN (args) = end_params_node;
8080   rtype = build_pointer_type (TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))));
8081   mdecl = create_artificial_method (type, ACC_STATIC, rtype,
8082                                     access0_identifier_node, args);
8083   fix_method_argument_names (args, mdecl);
8084   layout_class_method (type, NULL_TREE, mdecl, NULL_TREE);
8085   stmt = build_current_thisn (type);
8086   stmt = make_qualified_primary (build_wfl_node (inst_id), 
8087                                  build_wfl_node (stmt), 0);
8088   stmt = build_return (0, stmt);
8089
8090   saved_current_function_decl = current_function_decl;
8091   start_artificial_method_body (mdecl);
8092   java_method_add_stmt (mdecl, stmt);
8093   end_artificial_method_body (mdecl);
8094   current_function_decl = saved_current_function_decl;
8095   pop_obstacks ();
8096
8097   CLASS_ACCESS0_GENERATED_P (type) = 1;
8098
8099   return mdecl;
8100 }
8101
8102 /* Craft an correctly numbered `this$<n>'string. this$0 is used for
8103    the first level of innerclassing. this$1 for the next one, etc...
8104    This function can be invoked with TYPE to NULL, available and then
8105    has to count the parser context.  */
8106
8107 static tree
8108 build_current_thisn (type)
8109     tree type;
8110 {
8111   static int saved_i = -1;
8112   static tree saved_thisn = NULL_TREE;
8113
8114   tree decl;
8115   char buffer [80];
8116   int i = 0;
8117
8118   if (type)
8119     {
8120       static tree saved_type = NULL_TREE;
8121       static int saved_type_i = 0;
8122
8123       if (type == saved_type)
8124         i = saved_type_i;
8125       else
8126         {
8127           for (i = -1, decl = DECL_CONTEXT (TYPE_NAME (type)); 
8128                decl; decl = DECL_CONTEXT (decl), i++)
8129             ;
8130       
8131           saved_type = type;
8132           saved_type_i = i;
8133         }
8134     }
8135   else
8136     i = list_length (GET_CPC_LIST ())-2;
8137
8138   if (i == saved_i)
8139     return saved_thisn;
8140     
8141   sprintf (buffer, "this$%d", i);
8142   saved_i = i;
8143   saved_thisn = get_identifier (buffer);
8144   return saved_thisn;
8145 }
8146
8147 /* Return the assignement to the hidden enclosing context `this$<n>'
8148    by the second incoming parameter to the innerclass constructor. The
8149    form used is `this.this$<n> = this$<n>;'.  */
8150
8151 static tree
8152 build_thisn_assign ()
8153 {
8154   if (current_class && PURE_INNER_CLASS_TYPE_P (current_class))
8155     {
8156       tree thisn = build_current_thisn (current_class);
8157       tree lhs = make_qualified_primary (build_wfl_node (this_identifier_node),
8158                                          build_wfl_node (thisn), 0);
8159       tree rhs = build_wfl_node (thisn);
8160       EXPR_WFL_SET_LINECOL (lhs, lineno, 0);
8161       return build_assignment (ASSIGN_TK, EXPR_WFL_LINECOL (lhs), lhs, rhs);
8162     }
8163   return NULL_TREE;
8164 }
8165
8166 \f
8167 /* Building the synthetic `class$' used to implement the `.class' 1.1
8168    extension for non primitive types. This method looks like:
8169
8170     static Class class$(String type) throws NoClassDefFoundError
8171     {
8172       try {return (java.lang.Class.forName (String));}
8173       catch (ClassNotFoundException e) {
8174         throw new NoClassDefFoundError(e.getMessage());}
8175     } */
8176
8177 static tree
8178 build_dot_class_method (class)
8179      tree class;
8180 {
8181 #define BWF(S) build_wfl_node (get_identifier ((S)))
8182 #define MQN(X,Y) make_qualified_name ((X), (Y), 0)
8183   tree args, tmp, saved_current_function_decl, mdecl;
8184   tree stmt, throw_stmt, catch, catch_block, try_block;
8185   tree catch_clause_param;
8186   tree class_not_found_exception, no_class_def_found_error;
8187
8188   static tree get_message_wfl, type_parm_wfl;
8189
8190   if (!get_message_wfl)
8191     {
8192       get_message_wfl = build_wfl_node (get_identifier ("getMessage"));
8193       type_parm_wfl = build_wfl_node (get_identifier ("type$"));
8194     }
8195
8196   /* Build the arguments */
8197   args = build_tree_list (get_identifier ("type$"),
8198                           build_pointer_type (string_type_node));
8199   TREE_CHAIN (args) = end_params_node;
8200
8201   /* Build the qualified name java.lang.Class.forName */
8202   tmp = MQN (MQN (MQN (BWF ("java"), 
8203                        BWF ("lang")), BWF ("Class")), BWF ("forName"));
8204
8205   /* For things we have to catch and throw */
8206   class_not_found_exception = 
8207     lookup_class (get_identifier ("java.lang.ClassNotFoundException"));
8208   no_class_def_found_error = 
8209     lookup_class (get_identifier ("java.lang.NoClassDefFoundError"));
8210   load_class (class_not_found_exception, 1);
8211   load_class (no_class_def_found_error, 1);
8212
8213   /* Create the "class$" function */
8214   mdecl = create_artificial_method (class, ACC_STATIC, 
8215                                     build_pointer_type (class_type_node),
8216                                     get_identifier ("class$"), args);
8217   DECL_FUNCTION_THROWS (mdecl) = build_tree_list (NULL_TREE,
8218                                                   no_class_def_found_error);
8219   
8220   /* We start by building the try block. We need to build:
8221        return (java.lang.Class.forName (type)); */
8222   stmt = build_method_invocation (tmp, 
8223                                   build_tree_list (NULL_TREE, type_parm_wfl));
8224   stmt = build_return (0, stmt);
8225   /* Put it in a block. That's the try block */
8226   try_block = build_expr_block (stmt, NULL_TREE);
8227
8228   /* Now onto the catch block. We start by building the expression
8229      throwing a new exception: 
8230        throw new NoClassDefFoundError (_.getMessage); */
8231   throw_stmt = make_qualified_name (build_wfl_node (wpv_id), 
8232                                     get_message_wfl, 0);
8233   throw_stmt = build_method_invocation (throw_stmt, NULL_TREE);
8234   
8235   /* Build new NoClassDefFoundError (_.getMessage) */
8236   throw_stmt = build_new_invocation 
8237     (build_wfl_node (get_identifier ("NoClassDefFoundError")),
8238      build_tree_list (build_pointer_type (string_type_node), throw_stmt));
8239
8240   /* Build the throw, (it's too early to use BUILD_THROW) */
8241   throw_stmt = build1 (THROW_EXPR, NULL_TREE, throw_stmt);
8242
8243   /* Build the catch block to encapsulate all this. We begin by
8244      building an decl for the catch clause parameter and link it to
8245      newly created block, the catch block. */
8246   catch_clause_param = 
8247     build_decl (VAR_DECL, wpv_id, 
8248                 build_pointer_type (class_not_found_exception));
8249   catch_block = build_expr_block (NULL_TREE, catch_clause_param);
8250   
8251   /* We initialize the variable with the exception handler. */
8252   catch = build (MODIFY_EXPR, NULL_TREE, catch_clause_param,
8253                  soft_exceptioninfo_call_node);
8254   add_stmt_to_block (catch_block, NULL_TREE, catch);
8255
8256   /* We add the statement throwing the new exception */
8257   add_stmt_to_block (catch_block, NULL_TREE, throw_stmt);
8258
8259   /* Build a catch expression for all this */
8260   catch_block = build1 (CATCH_EXPR, NULL_TREE, catch_block);
8261
8262   /* Build the try/catch sequence */
8263   stmt = build_try_statement (0, try_block, catch_block);
8264
8265   fix_method_argument_names (args, mdecl);
8266   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
8267   saved_current_function_decl = current_function_decl;
8268   start_artificial_method_body (mdecl);
8269   java_method_add_stmt (mdecl, stmt);
8270   end_artificial_method_body (mdecl);
8271   current_function_decl = saved_current_function_decl;
8272   TYPE_DOT_CLASS (class) = mdecl;
8273
8274   return mdecl;
8275 }
8276
8277 static tree
8278 build_dot_class_method_invocation (name)
8279      tree name;
8280 {
8281   tree s = make_node (STRING_CST);
8282   TREE_STRING_LENGTH (s) = IDENTIFIER_LENGTH (name);
8283   TREE_STRING_POINTER (s) = obstack_alloc (expression_obstack,
8284                                            TREE_STRING_LENGTH (s)+1);
8285   strcpy (TREE_STRING_POINTER (s), IDENTIFIER_POINTER (name));
8286   return build_method_invocation (build_wfl_node (get_identifier ("class$")),
8287                                   build_tree_list (NULL_TREE, s));
8288 }
8289
8290 /* This section of the code deals with constructor.  */
8291
8292 /* Craft a body for default constructor. Patch existing constructor
8293    bodies with call to super() and field initialization statements if
8294    necessary.  */
8295
8296 static void
8297 fix_constructors (mdecl)
8298      tree mdecl;
8299 {
8300   tree body = DECL_FUNCTION_BODY (mdecl);
8301   tree thisn_assign, compound = NULL_TREE;
8302   tree class_type = DECL_CONTEXT (mdecl);
8303
8304   if (!body)
8305     {
8306       /* It is an error for the compiler to generate a default
8307          constructor if the superclass doesn't have a constructor that
8308          takes no argument, or the same args for an anonymous class */
8309       if (verify_constructor_super (mdecl))
8310         {
8311           tree sclass_decl = TYPE_NAME (CLASSTYPE_SUPER (class_type));
8312           tree save = DECL_NAME (mdecl);
8313           const char *n = IDENTIFIER_POINTER (DECL_NAME (sclass_decl));
8314           DECL_NAME (mdecl) = DECL_NAME (sclass_decl);
8315           parse_error_context
8316             (lookup_cl (TYPE_NAME (class_type)), 
8317              "No constructor matching `%s' found in class `%s'",
8318              lang_printable_name (mdecl, 0), n);
8319           DECL_NAME (mdecl) = save;
8320         }
8321       
8322       /* The constructor body must be crafted by hand. It's the
8323          constructor we defined when we realize we didn't have the
8324          CLASSNAME() constructor */
8325       start_artificial_method_body (mdecl);
8326       
8327       /* We don't generate a super constructor invocation if we're
8328          compiling java.lang.Object. build_super_invocation takes care
8329          of that. */
8330       compound = java_method_add_stmt (mdecl, build_super_invocation (mdecl));
8331
8332       /* Insert the instance initializer block right here, after the
8333          super invocation. */
8334       add_instance_initializer (mdecl);
8335
8336       /* Insert an assignment to the this$<n> hidden field, if
8337          necessary */
8338       if ((thisn_assign = build_thisn_assign ()))
8339         java_method_add_stmt (mdecl, thisn_assign);
8340
8341       end_artificial_method_body (mdecl);
8342     }
8343   /* Search for an explicit constructor invocation */
8344   else 
8345     {
8346       int found = 0;
8347       tree main_block = BLOCK_EXPR_BODY (body);
8348       
8349       while (body)
8350         switch (TREE_CODE (body))
8351           {
8352           case CALL_EXPR:
8353             found = CALL_EXPLICIT_CONSTRUCTOR_P (body);
8354             body = NULL_TREE;
8355             break;
8356           case COMPOUND_EXPR:
8357           case EXPR_WITH_FILE_LOCATION:
8358             body = TREE_OPERAND (body, 0);
8359             break;
8360           case BLOCK:
8361             body = BLOCK_EXPR_BODY (body);
8362             break;
8363           default:
8364             found = 0;
8365             body = NULL_TREE;
8366           }
8367       /* The constructor is missing an invocation of super() */
8368       if (!found)
8369         compound = add_stmt_to_compound (compound, NULL_TREE,
8370                                          build_super_invocation (mdecl));
8371       
8372       /* Insert the instance initializer block right here, after the
8373          super invocation. */
8374       add_instance_initializer (mdecl);
8375
8376       /* Generate the assignment to this$<n>, if necessary */
8377       if ((thisn_assign = build_thisn_assign ()))
8378         compound = add_stmt_to_compound (compound, NULL_TREE, thisn_assign);
8379
8380       /* Fix the constructor main block if we're adding extra stmts */
8381       if (compound)
8382         {
8383           compound = add_stmt_to_compound (compound, NULL_TREE,
8384                                            BLOCK_EXPR_BODY (main_block));
8385           BLOCK_EXPR_BODY (main_block) = compound;
8386         }
8387     }
8388 }
8389
8390 /* Browse constructors in the super class, searching for a constructor
8391    that doesn't take any argument. Return 0 if one is found, 1
8392    otherwise.  If the current class is an anonymous inner class, look
8393    for something that has the same signature. */
8394
8395 static int
8396 verify_constructor_super (mdecl)
8397      tree mdecl;
8398 {
8399   tree class = CLASSTYPE_SUPER (current_class);
8400   int super_inner = PURE_INNER_CLASS_TYPE_P (class);
8401   tree sdecl;
8402
8403   if (!class)
8404     return 0;
8405
8406   if (ANONYMOUS_CLASS_P (current_class))
8407     {
8408       tree mdecl_arg_type;
8409       SKIP_THIS_AND_ARTIFICIAL_PARMS (mdecl_arg_type, mdecl);
8410       for (sdecl = TYPE_METHODS (class); sdecl; sdecl = TREE_CHAIN (sdecl))
8411         if (DECL_CONSTRUCTOR_P (sdecl))
8412           {
8413             tree m_arg_type;
8414             tree arg_type = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (sdecl)));
8415             if (super_inner)
8416               arg_type = TREE_CHAIN (arg_type);
8417             for (m_arg_type = mdecl_arg_type; 
8418                  (arg_type != end_params_node 
8419                   && m_arg_type != end_params_node);
8420                  arg_type = TREE_CHAIN (arg_type), 
8421                    m_arg_type = TREE_CHAIN (m_arg_type))
8422               if (TREE_VALUE (arg_type) != TREE_VALUE (m_arg_type))
8423                 break;
8424
8425             if (arg_type == end_params_node && m_arg_type == end_params_node)
8426               return 0;
8427           }
8428     }
8429   else
8430     {
8431       for (sdecl = TYPE_METHODS (class); sdecl; sdecl = TREE_CHAIN (sdecl))
8432         {
8433           tree arg = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (sdecl)));
8434           if (super_inner)
8435             arg = TREE_CHAIN (arg);
8436           if (DECL_CONSTRUCTOR_P (sdecl) && arg == end_params_node)
8437             return 0;
8438         }
8439     }
8440   return 1;
8441 }
8442
8443 /* Generate code for all context remembered for code generation.  */
8444
8445 void
8446 java_expand_classes ()
8447 {
8448   int save_error_count = 0;
8449   static struct parser_ctxt *saved_ctxp = NULL;
8450
8451   java_parse_abort_on_error ();
8452   if (!(ctxp = ctxp_for_generation))
8453     return;
8454   java_layout_classes ();
8455   java_parse_abort_on_error ();
8456
8457   saved_ctxp = ctxp_for_generation;
8458   for (; ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
8459     {
8460       ctxp = ctxp_for_generation;
8461       lang_init_source (2);            /* Error msgs have method prototypes */
8462       java_complete_expand_classes (); /* Complete and expand classes */
8463       java_parse_abort_on_error ();
8464     }
8465
8466   /* Find anonymous classes and expand their constructor, now they
8467      have been fixed. */
8468   for (ctxp_for_generation = saved_ctxp;
8469        ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
8470     {
8471       tree current;
8472       ctxp = ctxp_for_generation;
8473       for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
8474         {
8475           current_class = TREE_TYPE (current);
8476           if (ANONYMOUS_CLASS_P (current_class))
8477             {
8478               tree d;
8479               for (d = TYPE_METHODS (current_class); d; d = TREE_CHAIN (d))
8480                 {
8481                   if (DECL_CONSTRUCTOR_P (d))
8482                     {
8483                       restore_line_number_status (1);
8484                       reset_method_name (d);
8485                       java_complete_expand_method (d);
8486                       restore_line_number_status (0);
8487                       break;    /* We now there are no other ones */
8488                     }
8489                 }
8490             }
8491         }
8492     }
8493
8494   /* If we've found error at that stage, don't try to generate
8495      anything, unless we're emitting xrefs or checking the syntax only
8496      (but not using -fsyntax-only for the purpose of generating
8497      bytecode. */
8498   if (java_error_count && !flag_emit_xref 
8499       && (!flag_syntax_only && !flag_emit_class_files))
8500     return;
8501
8502   /* Now things are stable, go for generation of the class data. */
8503   for (ctxp_for_generation = saved_ctxp;
8504        ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
8505     {
8506       tree current;
8507       ctxp = ctxp_for_generation;
8508       for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
8509         {
8510           current_class = TREE_TYPE (current);
8511           outgoing_cpool = TYPE_CPOOL (current_class);
8512           if (flag_emit_class_files)
8513             write_classfile (current_class);
8514           if (flag_emit_xref)
8515             expand_xref (current_class);
8516           else if (! flag_syntax_only)
8517             finish_class ();
8518         }
8519     }
8520 }
8521
8522 /* Wrap non WFL PRIMARY around a WFL and set EXPR_WFL_QUALIFICATION to
8523    a tree list node containing RIGHT. Fore coming RIGHTs will be
8524    chained to this hook. LOCATION contains the location of the
8525    separating `.' operator.  */
8526
8527 static tree
8528 make_qualified_primary (primary, right, location)
8529      tree primary, right;
8530      int location;
8531 {
8532   tree wfl;
8533
8534   if (TREE_CODE (primary) != EXPR_WITH_FILE_LOCATION)
8535     wfl = build_wfl_wrap (primary, location);
8536   else
8537     {
8538       wfl = primary;
8539       /* If wfl wasn't qualified, we build a first anchor */
8540       if (!EXPR_WFL_QUALIFICATION (wfl))
8541         EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (wfl, NULL_TREE);
8542     }
8543
8544   /* And chain them */
8545   EXPR_WFL_LINECOL (right) = location;
8546   chainon (EXPR_WFL_QUALIFICATION (wfl), build_tree_list (right, NULL_TREE));
8547   PRIMARY_P (wfl) =  1;
8548   return wfl;
8549 }
8550
8551 /* Simple merge of two name separated by a `.' */
8552
8553 static tree
8554 merge_qualified_name (left, right)
8555      tree left, right;
8556 {
8557   tree node;
8558   if (!left && !right)
8559     return NULL_TREE;
8560
8561   if (!left)
8562     return right;
8563
8564   if (!right)
8565     return left;
8566
8567   obstack_grow (&temporary_obstack, IDENTIFIER_POINTER (left),
8568                 IDENTIFIER_LENGTH (left));
8569   obstack_1grow (&temporary_obstack, '.');
8570   obstack_grow0 (&temporary_obstack, IDENTIFIER_POINTER (right),
8571                  IDENTIFIER_LENGTH (right));
8572   node =  get_identifier (obstack_base (&temporary_obstack));
8573   obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
8574   QUALIFIED_P (node) = 1;
8575   return node;
8576 }
8577
8578 /* Merge the two parts of a qualified name into LEFT.  Set the
8579    location information of the resulting node to LOCATION, usually
8580    inherited from the location information of the `.' operator. */
8581
8582 static tree
8583 make_qualified_name (left, right, location)
8584      tree left, right;
8585      int location;
8586 {
8587 #ifdef USE_COMPONENT_REF
8588   tree node = build (COMPONENT_REF, NULL_TREE, left, right);
8589   EXPR_WFL_LINECOL (node) = location;
8590   return node;
8591 #else
8592   tree left_id = EXPR_WFL_NODE (left);
8593   tree right_id = EXPR_WFL_NODE (right);
8594   tree wfl, merge;
8595
8596   merge = merge_qualified_name (left_id, right_id);
8597
8598   /* Left wasn't qualified and is now qualified */
8599   if (!QUALIFIED_P (left_id))
8600     {
8601       tree wfl = build_expr_wfl (left_id, ctxp->filename, 0, 0);
8602       EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (left);
8603       EXPR_WFL_QUALIFICATION (left) = build_tree_list (wfl, NULL_TREE);
8604     }
8605   
8606   wfl = build_expr_wfl (right_id, ctxp->filename, 0, 0);
8607   EXPR_WFL_LINECOL (wfl) = location;
8608   chainon (EXPR_WFL_QUALIFICATION (left), build_tree_list (wfl, NULL_TREE));
8609
8610   EXPR_WFL_NODE (left) = merge;
8611   return left;
8612 #endif
8613 }
8614
8615 /* Extract the last identifier component of the qualified in WFL. The
8616    last identifier is removed from the linked list */
8617
8618 static tree
8619 cut_identifier_in_qualified (wfl)
8620      tree wfl;
8621 {
8622   tree q;
8623   tree previous = NULL_TREE;
8624   for (q = EXPR_WFL_QUALIFICATION (wfl); ; previous = q, q = TREE_CHAIN (q))
8625     if (!TREE_CHAIN (q))
8626       {
8627         if (!previous)
8628           fatal ("Operating on a non qualified qualified WFL - cut_identifier_in_qualified");
8629         TREE_CHAIN (previous) = NULL_TREE;
8630         return TREE_PURPOSE (q);
8631       }
8632 }
8633
8634 /* Resolve the expression name NAME. Return its decl.  */
8635
8636 static tree
8637 resolve_expression_name (id, orig)
8638      tree id;
8639      tree *orig;
8640 {
8641   tree name = EXPR_WFL_NODE (id);
8642   tree decl;
8643
8644   /* 6.5.5.1: Simple expression names */
8645   if (!PRIMARY_P (id) && !QUALIFIED_P (name))
8646     {
8647       /* 15.13.1: NAME can appear within the scope of a local variable
8648          declaration */
8649       if ((decl = IDENTIFIER_LOCAL_VALUE (name)))
8650         return decl;
8651
8652       /* 15.13.1: NAME can appear within a class declaration */
8653       else 
8654         {
8655           decl = lookup_field_wrapper (current_class, name);
8656           if (decl)
8657             {
8658               tree access = NULL_TREE;
8659               int fs = FIELD_STATIC (decl);
8660
8661               /* If we're accessing an outer scope local alias, make
8662                  sure we change the name of the field we're going to
8663                  build access to. */
8664               if (FIELD_LOCAL_ALIAS_USED (decl))
8665                 name = DECL_NAME (decl);
8666
8667               /* Instance variable (8.3.1.1) can't appear within
8668                  static method, static initializer or initializer for
8669                  a static variable. */
8670               if (!fs && METHOD_STATIC (current_function_decl))
8671                 {
8672                   static_ref_err (id, name, current_class);
8673                   return error_mark_node;
8674                 }
8675               /* Instance variables can't appear as an argument of
8676                  an explicit constructor invocation */
8677               if (!fs && ctxp->explicit_constructor_p)
8678                 {
8679                   parse_error_context
8680                     (id, "Can't reference `%s' before the superclass constructor has been called", IDENTIFIER_POINTER (name));
8681                   return error_mark_node;
8682                 }
8683
8684               /* If we're processing an inner class and we're trying
8685                  to access a field belonging to an outer class, build
8686                  the access to the field */
8687               if (!fs && outer_field_access_p (current_class, decl))
8688                 return build_outer_field_access (id, decl);
8689
8690               /* Otherwise build what it takes to access the field */
8691               access = build_field_ref ((fs ? NULL_TREE : current_this),
8692                                         DECL_CONTEXT (decl), name);
8693               if (fs && !flag_emit_class_files && !flag_emit_xref)
8694                 access = build_class_init (DECL_CONTEXT (access), access);
8695               /* We may be asked to save the real field access node */
8696               if (orig)
8697                 *orig = access;
8698               /* And we return what we got */
8699               return access;
8700             }
8701           /* Fall down to error report on undefined variable */
8702         }
8703     }
8704   /* 6.5.5.2 Qualified Expression Names */
8705   else
8706     {
8707       if (orig)
8708         *orig = NULL_TREE;
8709       qualify_ambiguous_name (id);
8710       /* 15.10.1 Field Access Using a Primary and/or Expression Name */
8711       /* 15.10.2: Accessing Superclass Members using super */
8712       return resolve_field_access (id, orig, NULL);
8713     }
8714
8715   /* We've got an error here */
8716   parse_error_context (id, "Undefined variable `%s'", 
8717                        IDENTIFIER_POINTER (name));
8718
8719   return error_mark_node;
8720 }
8721
8722 static void
8723 static_ref_err (wfl, field_id, class_type)
8724     tree wfl, field_id, class_type;
8725 {
8726   parse_error_context 
8727     (wfl, 
8728      "Can't make a static reference to nonstatic variable `%s' in class `%s'",
8729      IDENTIFIER_POINTER (field_id), 
8730      IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class_type))));
8731 }
8732
8733 /* 15.10.1 Field Acess Using a Primary and/or Expression Name.
8734    We return something suitable to generate the field access. We also
8735    return the field decl in FIELD_DECL and its type in FIELD_TYPE.  If
8736    recipient's address can be null. */
8737
8738 static tree
8739 resolve_field_access (qual_wfl, field_decl, field_type)
8740      tree qual_wfl;
8741      tree *field_decl, *field_type;
8742 {
8743   int is_static = 0;
8744   tree field_ref;
8745   tree decl, where_found, type_found;
8746
8747   if (resolve_qualified_expression_name (qual_wfl, &decl,
8748                                          &where_found, &type_found))
8749     return error_mark_node;
8750
8751   /* Resolve the LENGTH field of an array here */
8752   if (DECL_P (decl) && DECL_NAME (decl) == length_identifier_node 
8753       && type_found && TYPE_ARRAY_P (type_found) 
8754       && ! flag_emit_class_files && ! flag_emit_xref)
8755     {
8756       tree length = build_java_array_length_access (where_found);
8757       field_ref =
8758         build_java_arraynull_check (type_found, length, int_type_node);
8759
8760       /* In case we're dealing with a static array, we need to
8761          initialize its class before the array length can be fetched.
8762          It's also a good time to create a DECL_RTL for the field if
8763          none already exists, otherwise if the field was declared in a
8764          class found in an external file and hasn't been (and won't
8765          be) accessed for its value, none will be created. */
8766       if (TREE_CODE (where_found) == VAR_DECL && FIELD_STATIC (where_found))
8767         {
8768           build_static_field_ref (where_found);
8769           field_ref = build_class_init (DECL_CONTEXT (where_found), field_ref);
8770         }
8771     }
8772   /* We might have been trying to resolve field.method(). In which
8773      case, the resolution is over and decl is the answer */
8774   else if (JDECL_P (decl) && IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)) == decl)
8775     field_ref = decl;
8776   else if (JDECL_P (decl))
8777     {
8778       int static_final_found = 0;
8779       if (!type_found)
8780         type_found = DECL_CONTEXT (decl);
8781       is_static = JDECL_P (decl) && FIELD_STATIC (decl);
8782       if (FIELD_FINAL (decl) && FIELD_STATIC (decl)
8783           && JPRIMITIVE_TYPE_P (TREE_TYPE (decl))
8784           && DECL_INITIAL (decl))
8785         {
8786           /* When called on a FIELD_DECL of the right (primitive)
8787              type, java_complete_tree will try to substitue the decl
8788              for it's initial value. */
8789           field_ref = java_complete_tree (decl);
8790           static_final_found = 1;
8791         }
8792       else
8793         field_ref = build_field_ref ((is_static && !flag_emit_xref? 
8794                                       NULL_TREE : where_found), 
8795                                      type_found, DECL_NAME (decl));
8796       if (field_ref == error_mark_node)
8797         return error_mark_node;
8798       if (is_static && !static_final_found 
8799           && !flag_emit_class_files && !flag_emit_xref)
8800         field_ref = build_class_init (DECL_CONTEXT (decl), field_ref);
8801     }
8802   else
8803     field_ref = decl;
8804
8805   if (field_decl)
8806     *field_decl = decl;
8807   if (field_type)
8808     *field_type = (QUAL_DECL_TYPE (decl) ? 
8809                    QUAL_DECL_TYPE (decl) : TREE_TYPE (decl));
8810   return field_ref;
8811 }
8812
8813 /* If NODE is an access to f static field, strip out the class
8814    initialization part and return the field decl, otherwise, return
8815    NODE. */
8816
8817 static tree
8818 strip_out_static_field_access_decl (node)
8819     tree node;
8820 {
8821   if (TREE_CODE (node) == COMPOUND_EXPR)
8822     {
8823       tree op1 = TREE_OPERAND (node, 1);
8824       if (TREE_CODE (op1) == COMPOUND_EXPR)
8825          {
8826            tree call = TREE_OPERAND (op1, 0);
8827            if (TREE_CODE (call) == CALL_EXPR
8828                && TREE_CODE (TREE_OPERAND (call, 0)) == ADDR_EXPR
8829                && TREE_OPERAND (TREE_OPERAND (call, 0), 0)
8830                == soft_initclass_node)
8831              return TREE_OPERAND (op1, 1);
8832          }
8833       else if (JDECL_P (op1))
8834         return op1;
8835     }
8836   return node;
8837 }
8838
8839 /* 6.5.5.2: Qualified Expression Names */
8840
8841 static int
8842 resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
8843      tree wfl;
8844      tree *found_decl, *type_found, *where_found;
8845 {
8846   int from_type = 0;            /* Field search initiated from a type */
8847   int from_super = 0, from_cast = 0, from_qualified_this = 0;
8848   int previous_call_static = 0;
8849   int is_static;
8850   tree decl = NULL_TREE, type = NULL_TREE, q;
8851   /* For certain for of inner class instantiation */
8852   tree saved_current, saved_this;               
8853 #define RESTORE_THIS_AND_CURRENT_CLASS                          \
8854   { current_class = saved_current; current_this = saved_this;}
8855
8856   *type_found = *where_found = NULL_TREE;
8857
8858   for (q = EXPR_WFL_QUALIFICATION (wfl); q; q = TREE_CHAIN (q))
8859     {
8860       tree qual_wfl = QUAL_WFL (q);
8861       tree ret_decl;            /* for EH checking */
8862       int location;             /* for EH checking */
8863
8864       /* 15.10.1 Field Access Using a Primary */
8865       switch (TREE_CODE (qual_wfl))
8866         {
8867         case CALL_EXPR:
8868         case NEW_CLASS_EXPR:
8869           /* If the access to the function call is a non static field,
8870              build the code to access it. */
8871           if (JDECL_P (decl) && !FIELD_STATIC (decl))
8872             {
8873               decl = maybe_access_field (decl, *where_found, 
8874                                          DECL_CONTEXT (decl));
8875               if (decl == error_mark_node)
8876                 return 1;
8877             }
8878
8879           /* And code for the function call */
8880           if (complete_function_arguments (qual_wfl))
8881             return 1;
8882
8883           /* We might have to setup a new current class and a new this
8884              for the search of an inner class, relative to the type of
8885              a expression resolved as `decl'. The current values are
8886              saved and restored shortly after */
8887           saved_current = current_class;
8888           saved_this = current_this;
8889           if (decl && TREE_CODE (qual_wfl) == NEW_CLASS_EXPR)
8890             {
8891               current_class = type;
8892               current_this = decl;
8893             }
8894
8895           if (from_super && TREE_CODE (qual_wfl) == CALL_EXPR)
8896             CALL_USING_SUPER (qual_wfl) = 1;
8897           location = (TREE_CODE (qual_wfl) == CALL_EXPR ?
8898                       EXPR_WFL_LINECOL (TREE_OPERAND (qual_wfl, 0)) : 0);
8899           *where_found = patch_method_invocation (qual_wfl, decl, type, 
8900                                                   &is_static, &ret_decl);
8901           if (*where_found == error_mark_node)
8902             {
8903               RESTORE_THIS_AND_CURRENT_CLASS;
8904               return 1;
8905             }
8906           *type_found = type = QUAL_DECL_TYPE (*where_found);
8907
8908           /* If we're creating an inner class instance, check for that
8909              an enclosing instance is in scope */
8910           if (TREE_CODE (qual_wfl) == NEW_CLASS_EXPR
8911               && INNER_ENCLOSING_SCOPE_CHECK (type))
8912             {
8913               parse_error_context 
8914                 (qual_wfl, "No enclosing instance for inner class `%s' is in scope%s",
8915                  lang_printable_name (type, 0),
8916                  (!current_this ? "" :
8917                   "; an explicit one must be provided when creating this inner class"));
8918               RESTORE_THIS_AND_CURRENT_CLASS;
8919               return 1;
8920             }
8921
8922           /* In case we had to change then to resolve a inner class
8923              instantiation using a primary qualified by a `new' */
8924           RESTORE_THIS_AND_CURRENT_CLASS;
8925
8926           /* EH check */
8927           if (location)
8928             check_thrown_exceptions (location, ret_decl);
8929
8930           /* If the previous call was static and this one is too,
8931              build a compound expression to hold the two (because in
8932              that case, previous function calls aren't transported as
8933              forcoming function's argument. */
8934           if (previous_call_static && is_static)
8935             {
8936               decl = build (COMPOUND_EXPR, type, decl, *where_found);
8937               TREE_SIDE_EFFECTS (decl) = 1;
8938             }
8939           else
8940             {
8941               previous_call_static = is_static;
8942               decl = *where_found;
8943             }
8944           from_type = 0;
8945           continue;
8946
8947         case NEW_ARRAY_EXPR:
8948         case NEW_ANONYMOUS_ARRAY_EXPR:
8949           *where_found = decl = java_complete_tree (qual_wfl);
8950           if (decl == error_mark_node)
8951             return 1;
8952           *type_found = type = QUAL_DECL_TYPE (decl);
8953           CLASS_LOADED_P (type) = 1;
8954           continue;
8955
8956         case CONVERT_EXPR:
8957           *where_found = decl = java_complete_tree (qual_wfl);
8958           if (decl == error_mark_node)
8959             return 1;
8960           *type_found = type = QUAL_DECL_TYPE (decl);
8961           from_cast = 1;
8962           continue;
8963
8964         case CONDITIONAL_EXPR:
8965         case STRING_CST:
8966         case MODIFY_EXPR:
8967           *where_found = decl = java_complete_tree (qual_wfl);
8968           if (decl == error_mark_node)
8969             return 1;
8970           *type_found = type = QUAL_DECL_TYPE (decl);
8971           continue;
8972
8973         case ARRAY_REF:
8974           /* If the access to the function call is a non static field,
8975              build the code to access it. */
8976           if (JDECL_P (decl) && !FIELD_STATIC (decl))
8977             {
8978               decl = maybe_access_field (decl, *where_found, type);
8979               if (decl == error_mark_node)
8980                 return 1;
8981             }
8982           /* And code for the array reference expression */
8983           decl = java_complete_tree (qual_wfl);
8984           if (decl == error_mark_node)
8985             return 1;
8986           type = QUAL_DECL_TYPE (decl);
8987           continue;
8988
8989         case PLUS_EXPR:
8990           if ((decl = java_complete_tree (qual_wfl)) == error_mark_node)
8991             return 1;
8992           if ((type = patch_string (decl)))
8993             decl = type;
8994           *where_found = QUAL_RESOLUTION (q) = decl;
8995           *type_found = type = TREE_TYPE (decl);
8996           break;
8997
8998         case CLASS_LITERAL:
8999           if ((decl = java_complete_tree (qual_wfl)) == error_mark_node)
9000             return 1;
9001           *where_found = QUAL_RESOLUTION (q) = decl;
9002           *type_found = type = TREE_TYPE (decl);
9003           break;
9004
9005         default:
9006           /* Fix for -Wall Just go to the next statement. Don't
9007              continue */
9008           break;
9009         }
9010
9011       /* If we fall here, we weren't processing a (static) function call. */
9012       previous_call_static = 0;
9013
9014       /* It can be the keyword THIS */
9015       if (EXPR_WFL_NODE (qual_wfl) == this_identifier_node)
9016         {
9017           if (!current_this)
9018             {
9019               parse_error_context 
9020                 (wfl, "Keyword `this' used outside allowed context");
9021               return 1;
9022             }
9023           if (ctxp->explicit_constructor_p)
9024             {
9025               parse_error_context (wfl, "Can't reference `this' before the superclass constructor has been called");
9026               return 1;
9027             }
9028           /* We have to generate code for intermediate acess */
9029           if (!from_type || TREE_TYPE (TREE_TYPE (current_this)) == type)
9030             {
9031               *where_found = decl = current_this;
9032               *type_found = type = QUAL_DECL_TYPE (decl);
9033             }
9034           /* We're trying to access the this from somewhere else. Make sure
9035              it's allowed before doing so. */
9036           else
9037             {
9038               if (!enclosing_context_p (type, current_class))
9039                 {
9040                   char *p  = xstrdup (lang_printable_name (type, 0));
9041                   parse_error_context (qual_wfl, "Can't use variable `%s.this': type `%s' isn't an outer type of type `%s'", 
9042                                        p, p, 
9043                                        lang_printable_name (current_class, 0));
9044                   free (p);
9045                   return 1;
9046                 }
9047               *where_found = decl = build_current_thisn (type);
9048               from_qualified_this = 1;
9049             }
9050
9051           from_type = 0;
9052           continue;
9053         }
9054
9055       /* 15.10.2 Accessing Superclass Members using SUPER */
9056       if (EXPR_WFL_NODE (qual_wfl) == super_identifier_node)
9057         {
9058           tree node;
9059           /* Check on the restricted use of SUPER */
9060           if (METHOD_STATIC (current_function_decl)
9061               || current_class == object_type_node)
9062             {
9063               parse_error_context 
9064                 (wfl, "Keyword `super' used outside allowed context");
9065               return 1;
9066             }
9067           /* Otherwise, treat SUPER as (SUPER_CLASS)THIS */
9068           node = build_cast (EXPR_WFL_LINECOL (qual_wfl), 
9069                              CLASSTYPE_SUPER (current_class),
9070                              build_this (EXPR_WFL_LINECOL (qual_wfl)));
9071           *where_found = decl = java_complete_tree (node);
9072           if (decl == error_mark_node)
9073             return 1;
9074           *type_found = type = QUAL_DECL_TYPE (decl);
9075           from_super = from_type = 1;
9076           continue;
9077         }
9078
9079       /* 15.13.1: Can't search for field name in packages, so we
9080          assume a variable/class name was meant. */
9081       if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
9082         {
9083           tree name = resolve_package (wfl, &q);
9084           if (name)
9085             {
9086               tree list;
9087               *where_found = decl = resolve_no_layout (name, qual_wfl);
9088               /* We want to be absolutely sure that the class is laid
9089                  out. We're going to search something inside it. */
9090               *type_found = type = TREE_TYPE (decl);
9091               layout_class (type);
9092               from_type = 1;
9093
9094               /* Fix them all the way down, if any are left. */
9095               if (q)
9096                 {
9097                   list = TREE_CHAIN (q);
9098                   while (list)
9099                     {
9100                       RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (list)) = 1;
9101                       RESOLVE_PACKAGE_NAME_P (QUAL_WFL (list)) = 0;
9102                       list = TREE_CHAIN (list);
9103                     }
9104                 }
9105             }
9106           else
9107             {
9108               if (from_super || from_cast)
9109                 parse_error_context 
9110                   ((from_cast ? qual_wfl : wfl),
9111                    "No variable `%s' defined in class `%s'",
9112                    IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
9113                    lang_printable_name (type, 0));
9114               else
9115                 parse_error_context
9116                   (qual_wfl, "Undefined variable or class name: `%s'",
9117                    IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)));
9118               return 1;
9119             }
9120         }
9121
9122       /* We have a type name. It's been already resolved when the
9123          expression was qualified. */
9124       else if (RESOLVE_TYPE_NAME_P (qual_wfl))
9125         {
9126           if (!(decl = QUAL_RESOLUTION (q)))
9127             return 1;           /* Error reported already */
9128
9129           /* Sneak preview. If next we see a `new', we're facing a
9130              qualification with resulted in a type being selected
9131              instead of a field.  Report the error */
9132           if(TREE_CHAIN (q) 
9133              && TREE_CODE (TREE_PURPOSE (TREE_CHAIN (q))) == NEW_CLASS_EXPR)
9134             {
9135               parse_error_context (qual_wfl, "Undefined variable `%s'",
9136                                    IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
9137               return 1;
9138             }
9139
9140           if (not_accessible_p (TREE_TYPE (decl), decl, 0))
9141             {
9142               parse_error_context 
9143                 (qual_wfl, "Can't access %s field `%s.%s' from `%s'",
9144                  java_accstring_lookup (get_access_flags_from_decl (decl)),
9145                  GET_TYPE_NAME (type),
9146                  IDENTIFIER_POINTER (DECL_NAME (decl)),
9147                  IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
9148               return 1;
9149             }
9150           check_deprecation (qual_wfl, decl);
9151
9152           type = TREE_TYPE (decl);
9153           from_type = 1;
9154         }
9155       /* We resolve and expression name */
9156       else 
9157         {
9158           tree field_decl = NULL_TREE;
9159
9160           /* If there exists an early resolution, use it. That occurs
9161              only once and we know that there are more things to
9162              come. Don't do that when processing something after SUPER
9163              (we need more thing to be put in place below */
9164           if (!from_super && QUAL_RESOLUTION (q))
9165             {
9166               decl = QUAL_RESOLUTION (q);
9167               if (!type)
9168                 {
9169                   if (TREE_CODE (decl) == FIELD_DECL && !FIELD_STATIC (decl))
9170                     {
9171                       if (current_this)
9172                         *where_found = current_this;
9173                       else
9174                         {
9175                           static_ref_err (qual_wfl, DECL_NAME (decl),
9176                                           current_class);
9177                           return 1;
9178                         }
9179                     }
9180                   else
9181                     {
9182                       *where_found = TREE_TYPE (decl);
9183                       if (TREE_CODE (*where_found) == POINTER_TYPE)
9184                         *where_found = TREE_TYPE (*where_found);
9185                     }
9186                 }
9187             }
9188
9189           /* We have to search for a field, knowing the type of its
9190              container. The flag FROM_TYPE indicates that we resolved
9191              the last member of the expression as a type name, which
9192              means that for the resolution of this field, we'll look
9193              for other errors than if it was resolved as a member of
9194              an other field. */
9195           else
9196             {
9197               int is_static;
9198               tree field_decl_type; /* For layout */
9199
9200               if (!from_type && !JREFERENCE_TYPE_P (type))
9201                 {
9202                   parse_error_context 
9203                     (qual_wfl, "Attempt to reference field `%s' in `%s %s'",
9204                      IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
9205                      lang_printable_name (type, 0),
9206                      IDENTIFIER_POINTER (DECL_NAME (field_decl)));
9207                   return 1;
9208                 }
9209               
9210               field_decl = lookup_field_wrapper (type,
9211                                                  EXPR_WFL_NODE (qual_wfl));
9212
9213               /* Maybe what we're trying to access an inner class. */
9214               if (!field_decl)
9215                 {
9216                   tree ptr, inner_decl;
9217
9218                   BUILD_PTR_FROM_NAME (ptr, EXPR_WFL_NODE (qual_wfl));
9219                   inner_decl = resolve_class (decl, ptr, NULL_TREE, qual_wfl);
9220                   if (inner_decl)
9221                     {
9222                       check_inner_class_access (inner_decl, decl, qual_wfl); 
9223                       type = TREE_TYPE (inner_decl);
9224                       decl = inner_decl;
9225                       from_type = 1;
9226                       continue;
9227                     }
9228                 }
9229
9230               if (field_decl == NULL_TREE)
9231                 {
9232                   parse_error_context 
9233                     (qual_wfl, "No variable `%s' defined in type `%s'",
9234                      IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)), 
9235                      GET_TYPE_NAME (type));
9236                   return 1;
9237                 }
9238               if (field_decl == error_mark_node)
9239                 return 1;
9240
9241               /* Layout the type of field_decl, since we may need
9242                  it. Don't do primitive types or loaded classes. The
9243                  situation of non primitive arrays may not handled
9244                  properly here. FIXME */
9245               if (TREE_CODE (TREE_TYPE (field_decl)) == POINTER_TYPE)
9246                 field_decl_type = TREE_TYPE (TREE_TYPE (field_decl));
9247               else
9248                 field_decl_type = TREE_TYPE (field_decl);
9249               if (!JPRIMITIVE_TYPE_P (field_decl_type) 
9250                   && !CLASS_LOADED_P (field_decl_type)
9251                   && !TYPE_ARRAY_P (field_decl_type))
9252                 resolve_and_layout (field_decl_type, NULL_TREE);
9253               if (TYPE_ARRAY_P (field_decl_type))
9254                 CLASS_LOADED_P (field_decl_type) = 1;
9255               
9256               /* Check on accessibility here */
9257               if (not_accessible_p (type, field_decl, from_super))
9258                 {
9259                   parse_error_context 
9260                     (qual_wfl,
9261                      "Can't access %s field `%s.%s' from `%s'",
9262                      java_accstring_lookup 
9263                        (get_access_flags_from_decl (field_decl)),
9264                      GET_TYPE_NAME (type),
9265                      IDENTIFIER_POINTER (DECL_NAME (field_decl)),
9266                      IDENTIFIER_POINTER 
9267                        (DECL_NAME (TYPE_NAME (current_class))));
9268                   return 1;
9269                 }
9270               check_deprecation (qual_wfl, field_decl);
9271               
9272               /* There are things to check when fields are accessed
9273                  from type. There are no restrictions on a static
9274                  declaration of the field when it is accessed from an
9275                  interface */
9276               is_static = FIELD_STATIC (field_decl);
9277               if (!from_super && from_type 
9278                   && !TYPE_INTERFACE_P (type) 
9279                   && !is_static 
9280                   && (current_function_decl 
9281                       && METHOD_STATIC (current_function_decl)))
9282                 {
9283                   static_ref_err (qual_wfl, EXPR_WFL_NODE (qual_wfl), type);
9284                   return 1;
9285                 }
9286               from_cast = from_super = 0;
9287
9288               /* It's an access from a type but it isn't static, we
9289                  make it relative to `this'. */
9290               if (!is_static && from_type)
9291                 decl = current_this;
9292
9293               /* If we need to generate something to get a proper
9294                  handle on what this field is accessed from, do it
9295                  now. */
9296               if (!is_static)
9297                 {
9298                   decl = maybe_access_field (decl, *where_found, *type_found);
9299                   if (decl == error_mark_node)
9300                     return 1;
9301                 }
9302
9303               /* We want to keep the location were found it, and the type
9304                  we found. */
9305               *where_found = decl;
9306               *type_found = type;
9307
9308               /* Generate the correct expression for field access from
9309                  qualified this */
9310               if (from_qualified_this)
9311                 {
9312                   field_decl = build_outer_field_access (qual_wfl, field_decl);
9313                   from_qualified_this = 0;
9314                 }
9315
9316               /* This is the decl found and eventually the next one to
9317                  search from */
9318               decl = field_decl;
9319             }
9320           from_type = 0;
9321           type = QUAL_DECL_TYPE (decl);
9322
9323           /* Sneak preview. If decl is qualified by a `new', report
9324              the error here to be accurate on the peculiar construct */
9325           if (TREE_CHAIN (q) 
9326               && TREE_CODE (TREE_PURPOSE (TREE_CHAIN (q))) == NEW_CLASS_EXPR
9327               && !JREFERENCE_TYPE_P (type))
9328             {
9329               parse_error_context (qual_wfl, "Attempt to reference field `new' in a `%s'", 
9330                                    lang_printable_name (type, 0));
9331               return 1;
9332             }
9333         }
9334       /* `q' might have changed due to a after package resolution
9335          re-qualification */
9336       if (!q)
9337         break;
9338     }
9339   *found_decl = decl;
9340   return 0;
9341 }
9342
9343 /* 6.6 Qualified name and access control. Returns 1 if MEMBER (a decl)
9344    can't be accessed from REFERENCE (a record type). This should be
9345    used when decl is a field or a method.*/
9346
9347 static int
9348 not_accessible_p (reference, member, from_super)
9349      tree reference, member;
9350      int from_super;
9351 {
9352   int access_flag = get_access_flags_from_decl (member);
9353
9354   /* Inner classes are processed by check_inner_class_access */
9355   if (INNER_CLASS_TYPE_P (reference))
9356     return 0;
9357
9358   /* Access always granted for members declared public */
9359   if (access_flag & ACC_PUBLIC)
9360     return 0;
9361   
9362   /* Check access on protected members */
9363   if (access_flag & ACC_PROTECTED)
9364     {
9365       /* Access granted if it occurs from within the package
9366          containing the class in which the protected member is
9367          declared */
9368       if (class_in_current_package (DECL_CONTEXT (member)))
9369         return 0;
9370
9371       /* If accessed with the form `super.member', then access is granted */
9372       if (from_super)
9373         return 0;
9374
9375       /* Otherwise, access is granted if occuring from the class where
9376          member is declared or a subclass of it. Find the right
9377          context to perform the check */
9378       if (PURE_INNER_CLASS_TYPE_P (reference))
9379         {
9380           while (INNER_CLASS_TYPE_P (reference))
9381             {
9382               if (inherits_from_p (reference, DECL_CONTEXT (member)))
9383                 return 0;
9384               reference = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (reference)));
9385             }
9386         }
9387       if (inherits_from_p (reference, DECL_CONTEXT (member)))
9388         return 0;
9389       return 1;
9390     }
9391
9392   /* Check access on private members. Access is granted only if it
9393      occurs from within the class in which it is declared. Exceptions
9394      are accesses from inner-classes. */
9395   if (access_flag & ACC_PRIVATE)
9396     return (current_class == DECL_CONTEXT (member) ? 0 : 
9397             (INNER_CLASS_TYPE_P (current_class) ? 0 : 1));
9398
9399   /* Default access are permitted only when occuring within the
9400      package in which the type (REFERENCE) is declared. In other words,
9401      REFERENCE is defined in the current package */
9402   if (ctxp->package)
9403     return !class_in_current_package (reference);
9404
9405   /* Otherwise, access is granted */
9406   return 0;
9407 }
9408
9409 /* Test deprecated decl access.  */
9410 static void
9411 check_deprecation (wfl, decl)
9412      tree wfl, decl;
9413 {
9414   const char *file = DECL_SOURCE_FILE (decl);
9415   /* Complain if the field is deprecated and the file it was defined
9416      in isn't compiled at the same time the file which contains its
9417      use is */
9418   if (DECL_DEPRECATED (decl) 
9419       && !IS_A_COMMAND_LINE_FILENAME_P (get_identifier (file)))
9420     {
9421       char the [20];
9422       switch (TREE_CODE (decl))
9423         {
9424         case FUNCTION_DECL:
9425           strcpy (the, "method");
9426           break;
9427         case FIELD_DECL:
9428           strcpy (the, "field");
9429           break;
9430         case TYPE_DECL:
9431           strcpy (the, "class");
9432           break;
9433         default:
9434           fatal ("unexpected DECL code - check_deprecation");
9435         }
9436       parse_warning_context 
9437         (wfl, "The %s `%s' in class `%s' has been deprecated", 
9438          the, lang_printable_name (decl, 0),
9439          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)))));
9440     }
9441 }
9442
9443 /* Returns 1 if class was declared in the current package, 0 otherwise */
9444
9445 static int
9446 class_in_current_package (class)
9447      tree class;
9448 {
9449   static tree cache = NULL_TREE;
9450   int qualified_flag;
9451   tree left;
9452
9453   if (cache == class)
9454     return 1;
9455
9456   qualified_flag = QUALIFIED_P (DECL_NAME (TYPE_NAME (class)));
9457
9458   /* If the current package is empty and the name of CLASS is
9459      qualified, class isn't in the current package.  If there is a
9460      current package and the name of the CLASS is not qualified, class
9461      isn't in the current package */
9462   if ((!ctxp->package && qualified_flag) || (ctxp->package && !qualified_flag))
9463     return 0;
9464
9465   /* If there is not package and the name of CLASS isn't qualified,
9466      they belong to the same unnamed package */
9467   if (!ctxp->package && !qualified_flag)
9468     return 1;
9469
9470   /* Compare the left part of the name of CLASS with the package name */
9471   breakdown_qualified (&left, NULL, DECL_NAME (TYPE_NAME (class)));
9472   if (ctxp->package == left)
9473     {
9474       cache = class;
9475       return 1;
9476     }
9477   return 0;
9478 }
9479
9480 /* This function may generate code to access DECL from WHERE. This is
9481    done only if certain conditions meet.  */
9482
9483 static tree
9484 maybe_access_field (decl, where, type)
9485   tree decl, where, type;
9486 {
9487   if (TREE_CODE (decl) == FIELD_DECL && decl != current_this
9488       && !FIELD_STATIC (decl))
9489     decl = build_field_ref (where ? where : current_this, 
9490                             (type ? type : DECL_CONTEXT (decl)),
9491                             DECL_NAME (decl));
9492   return decl;
9493 }
9494
9495 /* Build a method invocation, by patching PATCH. If non NULL
9496    and according to the situation, PRIMARY and WHERE may be
9497    used. IS_STATIC is set to 1 if the invoked function is static. */
9498
9499 static tree
9500 patch_method_invocation (patch, primary, where, is_static, ret_decl)
9501      tree patch, primary, where;
9502      int *is_static;
9503      tree *ret_decl;
9504 {
9505   tree wfl = TREE_OPERAND (patch, 0);
9506   tree args = TREE_OPERAND (patch, 1);
9507   tree name = EXPR_WFL_NODE (wfl);
9508   tree list;
9509   int is_static_flag = 0;
9510   int is_super_init = 0;
9511   tree this_arg = NULL_TREE;
9512   
9513   /* Should be overriden if everything goes well. Otherwise, if
9514      something fails, it should keep this value. It stop the
9515      evaluation of a bogus assignment. See java_complete_tree,
9516      MODIFY_EXPR: for the reasons why we sometimes want to keep on
9517      evaluating an assignment */
9518   TREE_TYPE (patch) = error_mark_node;
9519
9520   /* Since lookup functions are messing with line numbers, save the
9521      context now.  */
9522   java_parser_context_save_global ();
9523
9524   /* 15.11.1: Compile-Time Step 1: Determine Class or Interface to Search */
9525
9526   /* Resolution of qualified name, excluding constructors */
9527   if (QUALIFIED_P (name) && !CALL_CONSTRUCTOR_P (patch))
9528     {
9529       tree identifier, identifier_wfl, type, resolved;
9530       /* Extract the last IDENTIFIER of the qualified
9531          expression. This is a wfl and we will use it's location
9532          data during error report. */
9533       identifier_wfl = cut_identifier_in_qualified (wfl);
9534       identifier = EXPR_WFL_NODE (identifier_wfl);
9535       
9536       /* Given the context, IDENTIFIER is syntactically qualified
9537          as a MethodName. We need to qualify what's before */
9538       qualify_ambiguous_name (wfl);
9539       resolved = resolve_field_access (wfl, NULL, NULL);
9540
9541       if (resolved == error_mark_node)
9542         PATCH_METHOD_RETURN_ERROR ();
9543
9544       type = GET_SKIP_TYPE (resolved);
9545       resolve_and_layout (type, NULL_TREE);
9546       
9547       if (JPRIMITIVE_TYPE_P (type))
9548         {
9549         parse_error_context
9550           (identifier_wfl,
9551           "Can't invoke a method on primitive type `%s'",
9552           IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
9553         PATCH_METHOD_RETURN_ERROR ();         
9554       }      
9555       
9556       list = lookup_method_invoke (0, identifier_wfl, type, identifier, args);
9557       args = nreverse (args);
9558
9559       /* We're resolving a call from a type */
9560       if (TREE_CODE (resolved) == TYPE_DECL)
9561         {
9562           if (CLASS_INTERFACE (resolved))
9563             {
9564               parse_error_context
9565                 (identifier_wfl,
9566                 "Can't make static reference to method `%s' in interface `%s'",
9567                  IDENTIFIER_POINTER (identifier), 
9568                  IDENTIFIER_POINTER (name));
9569               PATCH_METHOD_RETURN_ERROR ();
9570             }
9571           if (list && !METHOD_STATIC (list))
9572             {
9573               char *fct_name = xstrdup (lang_printable_name (list, 0));
9574               parse_error_context 
9575                 (identifier_wfl,
9576                  "Can't make static reference to method `%s %s' in class `%s'",
9577                  lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0), 
9578                  fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
9579               free (fct_name);
9580               PATCH_METHOD_RETURN_ERROR ();
9581             }
9582         }
9583       else
9584         this_arg = primary = resolved;
9585       
9586       /* IDENTIFIER_WFL will be used to report any problem further */
9587       wfl = identifier_wfl;
9588     }
9589   /* Resolution of simple names, names generated after a primary: or
9590      constructors */
9591   else
9592     {
9593       tree class_to_search = NULL_TREE;
9594       int lc;                   /* Looking for Constructor */
9595       
9596       /* We search constructor in their target class */
9597       if (CALL_CONSTRUCTOR_P (patch))
9598         {
9599           if (TREE_CODE (patch) == NEW_CLASS_EXPR)
9600             class_to_search = EXPR_WFL_NODE (wfl);
9601           else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) == 
9602                    this_identifier_node)
9603             class_to_search = NULL_TREE;
9604           else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) ==
9605                    super_identifier_node)
9606             {
9607               is_super_init = 1;
9608               if (CLASSTYPE_SUPER (current_class))
9609                 class_to_search = 
9610                   DECL_NAME (TYPE_NAME (CLASSTYPE_SUPER (current_class)));
9611               else
9612                 {
9613                   parse_error_context (wfl, "Can't invoke super constructor on java.lang.Object");
9614                   PATCH_METHOD_RETURN_ERROR ();
9615                 }
9616             }
9617
9618           /* Class to search is NULL if we're searching the current one */
9619           if (class_to_search)
9620             {
9621               class_to_search = resolve_and_layout (class_to_search, wfl);
9622
9623               if (!class_to_search)
9624                 {
9625                   parse_error_context 
9626                     (wfl, "Class `%s' not found in type declaration",
9627                      IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
9628                   PATCH_METHOD_RETURN_ERROR ();
9629                 }
9630               
9631               /* Can't instantiate an abstract class, but we can
9632                  invoke it's constructor. It's use within the `new'
9633                  context is denied here. */
9634               if (CLASS_ABSTRACT (class_to_search) 
9635                   && TREE_CODE (patch) == NEW_CLASS_EXPR)
9636                 {
9637                   parse_error_context 
9638                     (wfl, "Class `%s' is an abstract class. It can't be instantiated",
9639                      IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
9640                   PATCH_METHOD_RETURN_ERROR ();
9641                 }
9642
9643               class_to_search = TREE_TYPE (class_to_search);
9644             }
9645           else
9646             class_to_search = current_class;
9647           lc = 1;
9648         }
9649       /* This is a regular search in the local class, unless an
9650          alternate class is specified. */
9651       else
9652         {
9653           class_to_search = (where ? where : current_class);
9654           lc = 0;
9655         }
9656
9657       /* NAME is a simple identifier or comes from a primary. Search
9658          in the class whose declaration contain the method being
9659          invoked. */
9660       resolve_and_layout (class_to_search, NULL_TREE);
9661
9662       list = lookup_method_invoke (lc, wfl, class_to_search, name, args);
9663       /* Don't continue if no method were found, as the next statement
9664          can't be executed then. */
9665       if (!list)
9666         PATCH_METHOD_RETURN_ERROR ();
9667
9668       /* Check for static reference if non static methods */
9669       if (check_for_static_method_reference (wfl, patch, list, 
9670                                              class_to_search, primary))
9671         PATCH_METHOD_RETURN_ERROR ();
9672
9673       /* Check for inner classes creation from illegal contexts */
9674       if (lc && (INNER_CLASS_TYPE_P (class_to_search)
9675                  && !CLASS_STATIC (TYPE_NAME (class_to_search)))
9676           && INNER_ENCLOSING_SCOPE_CHECK (class_to_search))
9677         {
9678           parse_error_context 
9679             (wfl, "No enclosing instance for inner class `%s' is in scope%s",
9680              lang_printable_name (class_to_search, 0),
9681              (!current_this ? "" :
9682               "; an explicit one must be provided when creating this inner class"));
9683           PATCH_METHOD_RETURN_ERROR ();
9684         }
9685
9686       /* Non static methods are called with the current object extra
9687          argument. If patch a `new TYPE()', the argument is the value
9688          returned by the object allocator. If method is resolved as a
9689          primary, use the primary otherwise use the current THIS. */
9690       args = nreverse (args);
9691       if (TREE_CODE (patch) != NEW_CLASS_EXPR)
9692         {
9693           this_arg = primary ? primary : current_this;
9694
9695           /* If we're using an access method, things are different.
9696              There are two familly of cases:
9697
9698              1) We're not generating bytecodes:
9699
9700              - LIST is non static. It's invocation is transformed from
9701                x(a1,...,an) into this$<n>.x(a1,....an).
9702              - LIST is static. It's invocation is transformed from
9703                x(a1,...,an) into TYPE_OF(this$<n>).x(a1,....an)
9704
9705              2) We're generating bytecodes:
9706              
9707              - LIST is non static. It's invocation is transformed from
9708                x(a1,....,an) into access$<n>(this$<n>,a1,...,an).
9709              - LIST is static. It's invocation is transformed from
9710                x(a1,....,an) into TYPEOF(this$<n>).x(a1,....an).
9711
9712              Of course, this$<n> can be abitrary complex, ranging from
9713              this$0 (the immediate outer context) to 
9714              access$0(access$0(...(this$0))). 
9715              
9716              maybe_use_access_method returns a non zero value if the
9717              this_arg has to be moved into the (then generated) stub
9718              argument list. In the meantime, the selected function
9719              might have be replaced by a generated stub. */
9720           if (maybe_use_access_method (is_super_init, &list, &this_arg))
9721             args = tree_cons (NULL_TREE, this_arg, args);
9722         }
9723     }
9724
9725   /* Merge point of all resolution schemes. If we have nothing, this
9726      is an error, already signaled */
9727   if (!list) 
9728     PATCH_METHOD_RETURN_ERROR ();
9729
9730   /* Check accessibility, position the is_static flag, build and
9731      return the call */
9732   if (not_accessible_p (DECL_CONTEXT (current_function_decl), list, 0))
9733     {
9734       char *fct_name = xstrdup (lang_printable_name (list, 0));
9735       parse_error_context 
9736         (wfl, "Can't access %s method `%s %s.%s' from `%s'",
9737          java_accstring_lookup (get_access_flags_from_decl (list)),
9738          lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0), 
9739          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (list)))), 
9740          fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
9741       free (fct_name);
9742       PATCH_METHOD_RETURN_ERROR ();
9743     }
9744   check_deprecation (wfl, list);
9745
9746   /* If invoking a innerclass constructor, there are hidden parameters
9747      to pass */
9748   if (TREE_CODE (patch) == NEW_CLASS_EXPR 
9749       && PURE_INNER_CLASS_TYPE_P (DECL_CONTEXT (list)))
9750     {
9751       /* And make sure we add the accessed local variables to be saved
9752          in field aliases. */
9753       args = build_alias_initializer_parameter_list
9754         (AIPL_FUNCTION_CTOR_INVOCATION, DECL_CONTEXT (list), args, NULL);
9755
9756       /* We have to reverse things. Find out why. FIXME */
9757       if (ANONYMOUS_CLASS_P (DECL_CONTEXT (list)))
9758         args = nreverse (args);
9759       
9760       /* Secretely pass the current_this/primary as a second argument */
9761       if (primary || current_this)
9762         args = tree_cons (NULL_TREE, (primary ? primary : current_this), args);
9763       else
9764         args = tree_cons (NULL_TREE, integer_zero_node, args);
9765     }
9766
9767   /* This handles the situation where a constructor invocation needs
9768      to have an enclosing context passed as a second parameter (the
9769      constructor is one of an inner class. We extract it from the
9770      current function.  */
9771   if (is_super_init && PURE_INNER_CLASS_TYPE_P (DECL_CONTEXT (list)))
9772     {
9773       tree enclosing_decl = DECL_CONTEXT (TYPE_NAME (current_class));
9774       tree extra_arg;
9775
9776       if (ANONYMOUS_CLASS_P (current_class) || !DECL_CONTEXT (enclosing_decl))
9777         {
9778           extra_arg = DECL_FUNCTION_BODY (current_function_decl);
9779           extra_arg = TREE_CHAIN (BLOCK_EXPR_DECLS (extra_arg));
9780         }
9781       else
9782         {
9783           tree dest = TREE_TYPE (DECL_CONTEXT (enclosing_decl));
9784           extra_arg = 
9785             build_access_to_thisn (TREE_TYPE (enclosing_decl), dest, 0);
9786           extra_arg = java_complete_tree (extra_arg);
9787         }
9788       args = tree_cons (NULL_TREE, extra_arg, args);
9789     }
9790
9791   is_static_flag = METHOD_STATIC (list);
9792   if (! METHOD_STATIC (list) && this_arg != NULL_TREE)
9793     args = tree_cons (NULL_TREE, this_arg, args);
9794
9795   /* In the context of an explicit constructor invocation, we can't
9796      invoke any method relying on `this'. Exceptions are: we're
9797      invoking a static function, primary exists and is not the current
9798      this, we're creating a new object. */
9799   if (ctxp->explicit_constructor_p 
9800       && !is_static_flag 
9801       && (!primary || primary == current_this)
9802       && (TREE_CODE (patch) != NEW_CLASS_EXPR))
9803     {
9804       parse_error_context (wfl, "Can't reference `this' before the superclass constructor has been called");
9805       PATCH_METHOD_RETURN_ERROR ();
9806     }
9807   java_parser_context_restore_global ();
9808   if (is_static) 
9809     *is_static = is_static_flag;
9810   /* Sometimes, we want the decl of the selected method. Such as for
9811      EH checking */
9812   if (ret_decl)
9813     *ret_decl = list;
9814   patch = patch_invoke (patch, list, args);
9815   if (is_super_init && CLASS_HAS_FINIT_P (current_class))
9816     {
9817       tree finit_parms, finit_call;
9818       
9819       /* Prepare to pass hidden parameters to $finit$, if any. */
9820       finit_parms = build_alias_initializer_parameter_list 
9821         (AIPL_FUNCTION_FINIT_INVOCATION, current_class, NULL_TREE, NULL);
9822
9823       finit_call = 
9824         build_method_invocation (build_wfl_node (finit_identifier_node),
9825                                  finit_parms);
9826
9827       /* Generate the code used to initialize fields declared with an
9828          initialization statement and build a compound statement along
9829          with the super constructor invocation. */
9830       patch = build (COMPOUND_EXPR, void_type_node, patch,
9831                      java_complete_tree (finit_call));
9832       CAN_COMPLETE_NORMALLY (patch) = 1;
9833     }
9834   return patch;
9835 }
9836
9837 /* Check that we're not trying to do a static reference to a method in
9838    non static method. Return 1 if it's the case, 0 otherwise. */
9839
9840 static int
9841 check_for_static_method_reference (wfl, node, method, where, primary)
9842      tree wfl, node, method, where, primary;
9843 {
9844   if (METHOD_STATIC (current_function_decl) 
9845       && !METHOD_STATIC (method) && !primary && !CALL_CONSTRUCTOR_P (node))
9846     {
9847       char *fct_name = xstrdup (lang_printable_name (method, 0));
9848       parse_error_context 
9849         (wfl, "Can't make static reference to method `%s %s' in class `%s'", 
9850          lang_printable_name (TREE_TYPE (TREE_TYPE (method)), 0), fct_name,
9851          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (where))));
9852       free (fct_name);
9853       return 1;
9854     }
9855   return 0;
9856 }
9857
9858 /* Fix the invocation of *MDECL if necessary in the case of a
9859    invocation from an inner class. *THIS_ARG might be modified
9860    appropriately and an alternative access to *MDECL might be
9861    returned.  */
9862
9863 static int
9864 maybe_use_access_method (is_super_init, mdecl, this_arg)
9865      int is_super_init;
9866      tree *mdecl, *this_arg;
9867 {
9868   tree ctx;
9869   tree md = *mdecl, ta = *this_arg;
9870   int to_return = 0;
9871   int non_static_context = !METHOD_STATIC (md);
9872
9873   if (is_super_init 
9874       || DECL_CONTEXT (md) == current_class
9875       || !PURE_INNER_CLASS_TYPE_P (current_class) 
9876       || DECL_FINIT_P (md))
9877     return 0;
9878   
9879   /* If we're calling a method found in an enclosing class, generate
9880      what it takes to retrieve the right this. Don't do that if we're
9881      invoking a static method. */
9882
9883   if (non_static_context)
9884     {
9885       ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class)));
9886       if (inherits_from_p (ctx, DECL_CONTEXT (md)))
9887         {
9888           ta = build_current_thisn (current_class);
9889           ta = build_wfl_node (ta);
9890         }
9891       else
9892         {
9893           tree type = ctx;
9894           while (type)
9895             {
9896               maybe_build_thisn_access_method (type);
9897               if (inherits_from_p (type, DECL_CONTEXT (md)))
9898                 {
9899                   ta = build_access_to_thisn (ctx, type, 0);
9900                   break;
9901                 }
9902               type = (DECL_CONTEXT (TYPE_NAME (type)) ? 
9903                       TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))) : NULL_TREE);
9904             }
9905         }
9906       ta = java_complete_tree (ta);
9907     }
9908
9909   /* We might have to use an access method to get to MD. We can
9910      break the method access rule as far as we're not generating
9911      bytecode */
9912   if (METHOD_PRIVATE (md) && flag_emit_class_files)
9913     {
9914       md = build_outer_method_access_method (md);
9915       to_return = 1;
9916     }
9917
9918   *mdecl = md;
9919   *this_arg = ta;
9920
9921   /* Returnin a non zero value indicates we were doing a non static
9922      method invokation that is now a static invocation. It will have
9923      callee displace `this' to insert it in the regular argument
9924      list. */
9925   return (non_static_context && to_return);
9926 }
9927
9928 /* Patch an invoke expression METHOD and ARGS, based on its invocation
9929    mode.  */
9930
9931 static tree
9932 patch_invoke (patch, method, args)
9933      tree patch, method, args;
9934 {
9935   tree dtable, func;
9936   tree original_call, t, ta;
9937   tree cond = NULL_TREE;
9938
9939   /* Last step for args: convert build-in types. If we're dealing with
9940      a new TYPE() type call, the first argument to the constructor
9941      isn't found in the incoming argument list, but delivered by
9942      `new' */
9943   t = TYPE_ARG_TYPES (TREE_TYPE (method));
9944   if (TREE_CODE (patch) == NEW_CLASS_EXPR)
9945     t = TREE_CHAIN (t);
9946   for (ta = args; t != end_params_node && ta; 
9947        t = TREE_CHAIN (t), ta = TREE_CHAIN (ta))
9948     if (JPRIMITIVE_TYPE_P (TREE_TYPE (TREE_VALUE (ta))) &&
9949         TREE_TYPE (TREE_VALUE (ta)) != TREE_VALUE (t))
9950       TREE_VALUE (ta) = convert (TREE_VALUE (t), TREE_VALUE (ta));
9951
9952   /* Resolve unresolved returned type isses */
9953   t = TREE_TYPE (TREE_TYPE (method));
9954   if (TREE_CODE (t) == POINTER_TYPE && !CLASS_LOADED_P (TREE_TYPE (t)))
9955     resolve_and_layout (TREE_TYPE (t), NULL);
9956
9957   if (flag_emit_class_files || flag_emit_xref)
9958     func = method;
9959   else
9960     {
9961       tree signature = build_java_signature (TREE_TYPE (method));
9962       switch (invocation_mode (method, CALL_USING_SUPER (patch)))
9963         {
9964         case INVOKE_VIRTUAL:
9965           dtable = invoke_build_dtable (0, args);
9966           func = build_invokevirtual (dtable, method);
9967           break;
9968
9969         case INVOKE_NONVIRTUAL:
9970           /* If the object for the method call is null, we throw an
9971              exception.  We don't do this if the object is the current
9972              method's `this'.  In other cases we just rely on an
9973              optimization pass to eliminate redundant checks.  */
9974           if (TREE_VALUE (args) != current_this)
9975             {
9976               /* We use a SAVE_EXPR here to make sure we only evaluate
9977                  the new `self' expression once.  */
9978               tree save_arg = save_expr (TREE_VALUE (args));
9979               TREE_VALUE (args) = save_arg;
9980               cond = build (EQ_EXPR, boolean_type_node, save_arg,
9981                             null_pointer_node);
9982             }
9983           /* Fall through.  */
9984
9985         case INVOKE_SUPER:
9986         case INVOKE_STATIC:
9987           func = build_known_method_ref (method, TREE_TYPE (method),
9988                                          DECL_CONTEXT (method),
9989                                          signature, args);
9990           break;
9991
9992         case INVOKE_INTERFACE:
9993           dtable = invoke_build_dtable (1, args);
9994           func = build_invokeinterface (dtable, method);
9995           break;
9996
9997         default:
9998           fatal ("internal error - unknown invocation_mode result");
9999         }
10000
10001       /* Ensure self_type is initialized, (invokestatic). FIXME */
10002       func = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (method)), func);
10003     }
10004
10005   TREE_TYPE (patch) = TREE_TYPE (TREE_TYPE (method));
10006   TREE_OPERAND (patch, 0) = func;
10007   TREE_OPERAND (patch, 1) = args;
10008   original_call = patch;
10009
10010   /* We're processing a `new TYPE ()' form. New is called and its
10011      returned value is the first argument to the constructor. We build
10012      a COMPOUND_EXPR and use saved expression so that the overall NEW
10013      expression value is a pointer to a newly created and initialized
10014      class. */
10015   if (TREE_CODE (original_call) == NEW_CLASS_EXPR)
10016     {
10017       tree class = DECL_CONTEXT (method);
10018       tree c1, saved_new, size, new;
10019       if (flag_emit_class_files || flag_emit_xref)
10020         {
10021           TREE_TYPE (patch) = build_pointer_type (class);
10022           return patch;
10023         }
10024       if (!TYPE_SIZE (class))
10025         safe_layout_class (class);
10026       size = size_in_bytes (class);
10027       new = build (CALL_EXPR, promote_type (class),
10028                    build_address_of (alloc_object_node),
10029                    tree_cons (NULL_TREE, build_class_ref (class),
10030                               build_tree_list (NULL_TREE, 
10031                                                size_in_bytes (class))),
10032                    NULL_TREE);
10033       saved_new = save_expr (new);
10034       c1 = build_tree_list (NULL_TREE, saved_new);
10035       TREE_CHAIN (c1) = TREE_OPERAND (original_call, 1);
10036       TREE_OPERAND (original_call, 1) = c1;
10037       TREE_SET_CODE (original_call, CALL_EXPR);
10038       patch = build (COMPOUND_EXPR, TREE_TYPE (new), patch, saved_new);
10039     }
10040
10041   /* If COND is set, then we are building a check to see if the object
10042      is NULL.  */
10043   if (cond != NULL_TREE)
10044     {
10045       /* We have to make the `then' branch a compound expression to
10046          make the types turn out right.  This seems bizarre.  */
10047       patch = build (COND_EXPR, TREE_TYPE (patch), cond,
10048                      build (COMPOUND_EXPR, TREE_TYPE (patch),
10049                             build (CALL_EXPR, void_type_node,
10050                                    build_address_of (soft_nullpointer_node),
10051                                    NULL_TREE, NULL_TREE),
10052                             (FLOAT_TYPE_P (TREE_TYPE (patch))
10053                              ? build_real (TREE_TYPE (patch), dconst0)
10054                              : build1 (CONVERT_EXPR, TREE_TYPE (patch),
10055                                        integer_zero_node))),
10056                      patch);
10057       TREE_SIDE_EFFECTS (patch) = 1;
10058     }
10059
10060   return patch;
10061 }
10062
10063 static int
10064 invocation_mode (method, super)
10065      tree method;
10066      int super;
10067 {
10068   int access = get_access_flags_from_decl (method);
10069
10070   if (super)
10071     return INVOKE_SUPER;
10072
10073   if (access & ACC_STATIC)
10074     return INVOKE_STATIC;
10075
10076   /* We have to look for a constructor before we handle nonvirtual
10077      calls; otherwise the constructor will look nonvirtual.  */
10078   if (DECL_CONSTRUCTOR_P (method))
10079     return INVOKE_STATIC;
10080
10081   if (access & ACC_FINAL || access & ACC_PRIVATE)
10082     return INVOKE_NONVIRTUAL;
10083
10084   if (CLASS_FINAL (TYPE_NAME (DECL_CONTEXT (method))))
10085     return INVOKE_NONVIRTUAL;
10086
10087   if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))))
10088     return INVOKE_INTERFACE;
10089
10090   return INVOKE_VIRTUAL;
10091 }
10092
10093 /* Retrieve a refined list of matching methods. It covers the step
10094    15.11.2 (Compile-Time Step 2) */
10095
10096 static tree
10097 lookup_method_invoke (lc, cl, class, name, arg_list)
10098      int lc;
10099      tree cl;
10100      tree class, name, arg_list;
10101 {
10102   tree atl = end_params_node;           /* Arg Type List */
10103   tree method, signature, list, node;
10104   const char *candidates;               /* Used for error report */
10105   char *dup;
10106
10107   /* Fix the arguments */
10108   for (node = arg_list; node; node = TREE_CHAIN (node))
10109     {
10110       tree current_arg = TREE_TYPE (TREE_VALUE (node));
10111       /* Non primitive type may have to be resolved */
10112       if (!JPRIMITIVE_TYPE_P (current_arg))
10113         resolve_and_layout (current_arg, NULL_TREE);
10114       /* And promoted */
10115       if (TREE_CODE (current_arg) == RECORD_TYPE)
10116         current_arg = promote_type (current_arg);
10117       atl = tree_cons (NULL_TREE, current_arg, atl);
10118     }
10119
10120   /* Presto. If we're dealing with an anonymous class and a
10121      constructor call, generate the right constructor now, since we
10122      know the arguments' types. */
10123
10124   if (lc && ANONYMOUS_CLASS_P (class))
10125     craft_constructor (TYPE_NAME (class), atl);
10126
10127   /* Find all candidates and then refine the list, searching for the
10128      most specific method. */
10129   list = find_applicable_accessible_methods_list (lc, class, name, atl);
10130   list = find_most_specific_methods_list (list);
10131   if (list && !TREE_CHAIN (list))
10132     return TREE_VALUE (list);
10133
10134   /* Issue an error. List candidates if any. Candidates are listed
10135      only if accessible (non accessible methods may end-up here for
10136      the sake of a better error report). */
10137   candidates = NULL;
10138   if (list)
10139     {
10140       tree current;
10141       obstack_grow (&temporary_obstack, ". Candidates are:\n", 18);
10142       for (current = list; current; current = TREE_CHAIN (current))
10143         {
10144           tree cm = TREE_VALUE (current);
10145           char string [4096];
10146           if (!cm || not_accessible_p (class, cm, 0))
10147             continue;
10148           sprintf 
10149             (string, "  `%s' in `%s'%s",
10150              get_printable_method_name (cm),
10151              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (cm)))),
10152              (TREE_CHAIN (current) ? "\n" : ""));
10153           obstack_grow (&temporary_obstack, string, strlen (string));
10154         }
10155       obstack_1grow (&temporary_obstack, '\0');
10156       candidates = obstack_finish (&temporary_obstack);
10157     }
10158   /* Issue the error message */
10159   method = make_node (FUNCTION_TYPE);
10160   TYPE_ARG_TYPES (method) = atl;
10161   signature = build_java_argument_signature (method);
10162   dup = xstrdup (lang_printable_name (class, 0));
10163   parse_error_context (cl, "Can't find %s `%s(%s)' in type `%s'%s",
10164                        (lc ? "constructor" : "method"),
10165                        (lc ? dup : IDENTIFIER_POINTER (name)),
10166                        IDENTIFIER_POINTER (signature), dup,
10167                        (candidates ? candidates : ""));
10168   free (dup);
10169   return NULL_TREE;
10170 }
10171
10172 /* 15.11.2.1: Find Methods that are Applicable and Accessible. LC is 1
10173    when we're looking for a constructor. */
10174
10175 static tree
10176 find_applicable_accessible_methods_list (lc, class, name, arglist)
10177      int lc;
10178      tree class, name, arglist;
10179 {
10180   static struct hash_table t, *searched_classes = NULL;
10181   static int search_not_done = 0;
10182   tree list = NULL_TREE, all_list = NULL_TREE;
10183
10184   /* Check the hash table to determine if this class has been searched 
10185      already. */
10186   if (searched_classes)
10187     {
10188       if (hash_lookup (searched_classes, 
10189                       (const hash_table_key) class, FALSE, NULL))
10190        return NULL;
10191     }
10192   else
10193     {
10194       hash_table_init (&t, hash_newfunc, java_hash_hash_tree_node,
10195                       java_hash_compare_tree_node);
10196       searched_classes = &t;
10197     }
10198     
10199   search_not_done++;
10200   hash_lookup (searched_classes, 
10201                (const hash_table_key) class, TRUE, NULL);
10202
10203   if (!CLASS_LOADED_P (class) && !CLASS_FROM_SOURCE_P (class))
10204     {
10205       load_class (class, 1);
10206       safe_layout_class (class);
10207     }
10208
10209   /* Search interfaces */
10210   if (TREE_CODE (TYPE_NAME (class)) == TYPE_DECL 
10211       && CLASS_INTERFACE (TYPE_NAME (class)))
10212     {
10213       int i, n;
10214       tree basetype_vec = TYPE_BINFO_BASETYPES (class);
10215       search_applicable_methods_list (lc, TYPE_METHODS (class), 
10216                                       name, arglist, &list, &all_list);
10217       n = TREE_VEC_LENGTH (basetype_vec);
10218       for (i = 1; i < n; i++)
10219         {
10220           tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
10221           tree rlist;
10222
10223           rlist = find_applicable_accessible_methods_list (lc,  t, name, 
10224                                                            arglist);
10225           list = chainon (rlist, list);
10226         }
10227     }
10228   /* Search classes */
10229   else
10230     {
10231       tree sc = class;
10232       int seen_inner_class = 0;
10233       search_applicable_methods_list (lc, TYPE_METHODS (class), 
10234                                       name, arglist, &list, &all_list);
10235
10236       /* We must search all interfaces of this class */
10237       if (!lc)
10238       {
10239         tree basetype_vec = TYPE_BINFO_BASETYPES (sc);
10240         int n = TREE_VEC_LENGTH (basetype_vec), i;
10241         for (i = 1; i < n; i++)
10242           {
10243             tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
10244             if (t != object_type_node)
10245               {
10246                 tree rlist
10247                   = find_applicable_accessible_methods_list (lc, t,
10248                                                              name, arglist);
10249                 list = chainon (rlist, list);
10250               }
10251           }
10252       }
10253
10254       /* Search enclosing context of inner classes before looking
10255          ancestors up. */
10256       while (!lc && INNER_CLASS_TYPE_P (class))
10257         {
10258           tree rlist;
10259           seen_inner_class = 1;
10260           class = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class)));
10261           rlist = find_applicable_accessible_methods_list (lc, class, 
10262                                                            name, arglist);
10263           list = chainon (rlist, list);
10264         }
10265
10266       if (!lc && seen_inner_class 
10267           && TREE_TYPE (DECL_CONTEXT (TYPE_NAME (sc))) == CLASSTYPE_SUPER (sc))
10268         class = CLASSTYPE_SUPER (sc);
10269       else
10270         class = sc;
10271
10272       /* Search superclass */
10273       if (!lc && CLASSTYPE_SUPER (class) != NULL_TREE)
10274         {
10275           tree rlist;
10276           class = CLASSTYPE_SUPER (class);
10277           rlist = find_applicable_accessible_methods_list (lc, class, 
10278                                                            name, arglist);
10279           list = chainon (rlist, list);
10280         }
10281     }
10282
10283   search_not_done--;
10284
10285   /* We're done. Reset the searched classes list and finally search
10286      java.lang.Object if it wasn't searched already. */
10287   if (!search_not_done)
10288     {
10289       if (!lc
10290           && TYPE_METHODS (object_type_node)
10291           && !hash_lookup (searched_classes, 
10292                            (const hash_table_key) object_type_node, 
10293                            FALSE, NULL))
10294         {
10295           search_applicable_methods_list (lc, 
10296                                           TYPE_METHODS (object_type_node),
10297                                           name, arglist, &list, &all_list);
10298         }
10299       hash_table_free (searched_classes);
10300       searched_classes = NULL;
10301     }
10302
10303   /* Either return the list obtained or all selected (but
10304      inaccessible) methods for better error report. */
10305   return (!list ? all_list : list);
10306 }
10307
10308 /* Effectively search for the appropriate method in method */
10309
10310 static void 
10311 search_applicable_methods_list (lc, method, name, arglist, list, all_list)
10312      int lc;
10313      tree method, name, arglist;
10314      tree *list, *all_list;
10315 {
10316   for (; method; method = TREE_CHAIN (method))
10317     {
10318       /* When dealing with constructor, stop here, otherwise search
10319          other classes */
10320       if (lc && !DECL_CONSTRUCTOR_P (method))
10321         continue;
10322       else if (!lc && (DECL_CONSTRUCTOR_P (method) 
10323                        || (GET_METHOD_NAME (method) != name)))
10324         continue;
10325           
10326       if (argument_types_convertible (method, arglist))
10327         {
10328           /* Retain accessible methods only */
10329           if (!not_accessible_p (DECL_CONTEXT (current_function_decl), 
10330                                  method, 0))
10331             *list = tree_cons (NULL_TREE, method, *list);
10332           else
10333             /* Also retain all selected method here */
10334             *all_list = tree_cons (NULL_TREE, method, *list);
10335         }
10336     }
10337 }
10338
10339 /* 15.11.2.2 Choose the Most Specific Method */
10340
10341 static tree
10342 find_most_specific_methods_list (list)
10343      tree list;
10344 {
10345   int max = 0;
10346   int abstract, candidates;
10347   tree current, new_list = NULL_TREE;
10348   for (current = list; current; current = TREE_CHAIN (current))
10349     {
10350       tree method;
10351       DECL_SPECIFIC_COUNT (TREE_VALUE (current)) = 0;
10352
10353       for (method = list; method; method = TREE_CHAIN (method))
10354         {
10355           tree method_v, current_v;
10356           /* Don't test a method against itself */
10357           if (method == current)
10358             continue;
10359
10360           method_v = TREE_VALUE (method);
10361           current_v = TREE_VALUE (current);
10362
10363           /* Compare arguments and location where methods where declared */
10364           if (argument_types_convertible (method_v, current_v))
10365             {
10366               if (valid_method_invocation_conversion_p 
10367                   (DECL_CONTEXT (method_v), DECL_CONTEXT (current_v))
10368                   || (INNER_CLASS_TYPE_P (DECL_CONTEXT (current_v))
10369                       && enclosing_context_p (DECL_CONTEXT (method_v),
10370                                               DECL_CONTEXT (current_v))))
10371                 {
10372                   int v = (DECL_SPECIFIC_COUNT (current_v) += 
10373                     (INNER_CLASS_TYPE_P (DECL_CONTEXT (current_v)) ? 2 : 1));
10374                   max = (v > max ? v : max);
10375                 }
10376             }
10377         }
10378     }
10379
10380   /* Review the list and select the maximally specific methods */
10381   for (current = list, abstract = -1, candidates = -1;
10382        current; current = TREE_CHAIN (current))
10383     if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
10384       {
10385         new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
10386         abstract += (METHOD_ABSTRACT (TREE_VALUE (current)) ? 1 : 0);
10387         candidates++;
10388       }
10389
10390   /* If we have several and they're all abstract, just pick the
10391      closest one. */
10392   if (candidates > 0 && (candidates == abstract))
10393     {
10394       new_list = nreverse (new_list);
10395       TREE_CHAIN (new_list) = NULL_TREE;
10396     }
10397
10398   /* We have several, we couldn't find a most specific, all but one are
10399      abstract, we pick the only non abstract one. */
10400   if (candidates > 0 && !max && (candidates == abstract+1))
10401     {
10402       for (current = new_list; current; current = TREE_CHAIN (current))
10403         if (!METHOD_ABSTRACT (TREE_VALUE (current)))
10404           {
10405             TREE_CHAIN (current) = NULL_TREE;
10406             new_list = current;
10407           }
10408     }
10409
10410   /* If we can't find one, lower expectations and try to gather multiple
10411      maximally specific methods */
10412   while (!new_list && max)
10413     {
10414       while (--max > 0)
10415         {
10416           if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
10417             new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
10418         }
10419     }
10420
10421   return new_list;
10422 }
10423
10424 /* Make sure that the type of each M2_OR_ARGLIST arguments can be
10425    converted by method invocation conversion (5.3) to the type of the
10426    corresponding parameter of M1. Implementation expects M2_OR_ARGLIST
10427    to change less often than M1. */
10428
10429 static int
10430 argument_types_convertible (m1, m2_or_arglist)
10431     tree m1, m2_or_arglist;
10432 {
10433   static tree m2_arg_value = NULL_TREE;
10434   static tree m2_arg_cache = NULL_TREE;
10435
10436   register tree m1_arg, m2_arg;
10437
10438   SKIP_THIS_AND_ARTIFICIAL_PARMS (m1_arg, m1)
10439
10440   if (m2_arg_value == m2_or_arglist)
10441     m2_arg = m2_arg_cache;
10442   else
10443     {
10444       /* M2_OR_ARGLIST can be a function DECL or a raw list of
10445          argument types */
10446       if (m2_or_arglist && TREE_CODE (m2_or_arglist) == FUNCTION_DECL)
10447         {
10448           m2_arg = TYPE_ARG_TYPES (TREE_TYPE (m2_or_arglist));
10449           if (!METHOD_STATIC (m2_or_arglist))
10450             m2_arg = TREE_CHAIN (m2_arg);
10451         }
10452       else
10453         m2_arg = m2_or_arglist;
10454
10455       m2_arg_value = m2_or_arglist;
10456       m2_arg_cache = m2_arg;
10457     }
10458
10459   while (m1_arg != end_params_node && m2_arg != end_params_node)
10460     {
10461       resolve_and_layout (TREE_VALUE (m1_arg), NULL_TREE);
10462       if (!valid_method_invocation_conversion_p (TREE_VALUE (m1_arg),
10463                                                  TREE_VALUE (m2_arg)))
10464         break;
10465       m1_arg = TREE_CHAIN (m1_arg);
10466       m2_arg = TREE_CHAIN (m2_arg);
10467     }
10468   return m1_arg == end_params_node && m2_arg == end_params_node;
10469 }
10470
10471 /* Qualification routines */
10472
10473 static void
10474 qualify_ambiguous_name (id)
10475      tree id;
10476 {
10477   tree qual, qual_wfl, name = NULL_TREE, decl, ptr_type = NULL_TREE,
10478     saved_current_class;
10479   int again, super_found = 0, this_found = 0, new_array_found = 0;
10480   int code;
10481
10482   /* We first qualify the first element, then derive qualification of
10483      others based on the first one. If the first element is qualified
10484      by a resolution (field or type), this resolution is stored in the
10485      QUAL_RESOLUTION of the qual element being examined. We need to
10486      save the current_class since the use of SUPER might change the
10487      its value. */
10488   saved_current_class = current_class;
10489   qual = EXPR_WFL_QUALIFICATION (id);
10490   do {
10491
10492     /* Simple qualified expression feature a qual_wfl that is a
10493        WFL. Expression derived from a primary feature more complicated
10494        things like a CALL_EXPR. Expression from primary need to be
10495        worked out to extract the part on which the qualification will
10496        take place. */
10497     qual_wfl = QUAL_WFL (qual);
10498     switch (TREE_CODE (qual_wfl))
10499       {
10500       case CALL_EXPR:
10501         qual_wfl = TREE_OPERAND (qual_wfl, 0);
10502         if (TREE_CODE (qual_wfl) != EXPR_WITH_FILE_LOCATION)
10503           {
10504             qual = EXPR_WFL_QUALIFICATION (qual_wfl);
10505             qual_wfl = QUAL_WFL (qual);
10506           }
10507         break;
10508       case NEW_ARRAY_EXPR:
10509       case NEW_ANONYMOUS_ARRAY_EXPR:
10510         qual = TREE_CHAIN (qual);
10511         again = new_array_found = 1;
10512         continue;
10513       case CONVERT_EXPR:
10514         break;
10515       case NEW_CLASS_EXPR:
10516         qual_wfl = TREE_OPERAND (qual_wfl, 0);
10517         break;
10518       case ARRAY_REF:
10519         while (TREE_CODE (qual_wfl) == ARRAY_REF)
10520           qual_wfl = TREE_OPERAND (qual_wfl, 0);
10521         break;
10522       case STRING_CST:
10523         qual = TREE_CHAIN (qual);
10524         qual_wfl = QUAL_WFL (qual);
10525         break;
10526       case CLASS_LITERAL:
10527         qual = TREE_CHAIN (qual);
10528         qual_wfl = QUAL_WFL (qual);
10529       break;
10530       default:
10531         /* Fix for -Wall. Just break doing nothing */
10532         break;
10533       }
10534
10535     ptr_type = current_class;
10536     again = 0;
10537     code = TREE_CODE (qual_wfl);
10538
10539     /* Pos evaluation: non WFL leading expression nodes */
10540     if (code == CONVERT_EXPR
10541         && TREE_CODE (TREE_TYPE (qual_wfl)) == EXPR_WITH_FILE_LOCATION)
10542       name = EXPR_WFL_NODE (TREE_TYPE (qual_wfl));
10543
10544     else if (code == INTEGER_CST)
10545       name = qual_wfl;
10546     
10547     else if ((code == ARRAY_REF || code == CALL_EXPR || code == MODIFY_EXPR) &&
10548              TREE_CODE (TREE_OPERAND (qual_wfl, 0)) == EXPR_WITH_FILE_LOCATION)
10549       name = EXPR_WFL_NODE (TREE_OPERAND (qual_wfl, 0));
10550
10551     else if (code == TREE_LIST)
10552       name = EXPR_WFL_NODE (TREE_PURPOSE (qual_wfl));
10553
10554     else if (code == STRING_CST || code == CONDITIONAL_EXPR 
10555              || code == PLUS_EXPR)
10556       {
10557         qual = TREE_CHAIN (qual);
10558         qual_wfl = QUAL_WFL (qual);
10559         again = 1;
10560       }
10561     else 
10562       {
10563         name = EXPR_WFL_NODE (qual_wfl);
10564         if (!name)
10565           {
10566             qual = EXPR_WFL_QUALIFICATION (qual_wfl);
10567             again = 1;
10568           }
10569       }
10570
10571     /* If we have a THIS (from a primary), we set the context accordingly */
10572     if (name == this_identifier_node)
10573       {
10574         qual = TREE_CHAIN (qual);
10575         qual_wfl = QUAL_WFL (qual);
10576         if (TREE_CODE (qual_wfl) == CALL_EXPR)
10577           again = 1;
10578         else
10579           name = EXPR_WFL_NODE (qual_wfl);
10580         this_found = 1;
10581       }
10582     /* If we have a SUPER, we set the context accordingly */
10583     if (name == super_identifier_node)
10584       {
10585         current_class = CLASSTYPE_SUPER (ptr_type);
10586         /* Check that there is such a thing as a super class. If not,
10587            return.  The error will be caught later on, during the
10588            resolution */
10589         if (!current_class)
10590           {
10591             current_class = saved_current_class;
10592             return;
10593           }
10594         qual = TREE_CHAIN (qual);
10595         /* Do one more interation to set things up */
10596         super_found = again = 1;
10597       }
10598   } while (again);
10599   
10600   /* If name appears within the scope of a local variable declaration
10601      or parameter declaration, then it is an expression name. We don't
10602      carry this test out if we're in the context of the use of SUPER
10603      or THIS */
10604   if (!this_found && !super_found 
10605       && TREE_CODE (name) != STRING_CST && TREE_CODE (name) != INTEGER_CST
10606       && (decl = IDENTIFIER_LOCAL_VALUE (name)))
10607     {
10608       RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
10609       QUAL_RESOLUTION (qual) = decl;
10610     }
10611
10612   /* If within the class/interface NAME was found to be used there
10613      exists a (possibly inherited) field named NAME, then this is an
10614      expression name. If we saw a NEW_ARRAY_EXPR before and want to
10615      address length, it is OK. */
10616   else if ((decl = lookup_field_wrapper (ptr_type, name))
10617            || (new_array_found && name == length_identifier_node))
10618     {
10619       RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
10620       QUAL_RESOLUTION (qual) = (new_array_found ? NULL_TREE : decl);
10621     }
10622
10623   /* We reclassify NAME as yielding to a type name resolution if:
10624      - NAME is a class/interface declared within the compilation
10625        unit containing NAME,
10626      - NAME is imported via a single-type-import declaration,
10627      - NAME is declared in an another compilation unit of the package
10628        of the compilation unit containing NAME,
10629      - NAME is declared by exactly on type-import-on-demand declaration
10630      of the compilation unit containing NAME. 
10631      - NAME is actually a STRING_CST. */
10632   else if (TREE_CODE (name) == STRING_CST || TREE_CODE (name) == INTEGER_CST
10633            || (decl = resolve_and_layout (name, NULL_TREE)))
10634     {
10635       RESOLVE_TYPE_NAME_P (qual_wfl) = 1;
10636       QUAL_RESOLUTION (qual) = decl;
10637     }
10638
10639   /* Method call, array references and cast are expression name */
10640   else if (TREE_CODE (QUAL_WFL (qual)) == CALL_EXPR
10641            || TREE_CODE (QUAL_WFL (qual)) == ARRAY_REF
10642            || TREE_CODE (QUAL_WFL (qual)) == CONVERT_EXPR)
10643     RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
10644
10645   /* Check here that NAME isn't declared by more than one
10646      type-import-on-demand declaration of the compilation unit
10647      containing NAME. FIXME */
10648
10649   /* Otherwise, NAME is reclassified as a package name */
10650   else 
10651     RESOLVE_PACKAGE_NAME_P (qual_wfl) = 1;
10652
10653   /* Propagate the qualification accross other components of the
10654      qualified name */
10655   for (qual = TREE_CHAIN (qual); qual;
10656        qual_wfl = QUAL_WFL (qual), qual = TREE_CHAIN (qual))
10657     {
10658       if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
10659         RESOLVE_PACKAGE_NAME_P (QUAL_WFL (qual)) = 1;
10660       else 
10661         RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (qual)) = 1;
10662     }
10663
10664   /* Store the global qualification for the ambiguous part of ID back
10665      into ID fields */
10666   if (RESOLVE_EXPRESSION_NAME_P (qual_wfl))
10667     RESOLVE_EXPRESSION_NAME_P (id) = 1;
10668   else if (RESOLVE_TYPE_NAME_P (qual_wfl))
10669     RESOLVE_TYPE_NAME_P (id) = 1;
10670   else if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
10671     RESOLVE_PACKAGE_NAME_P (id) = 1;
10672
10673   /* Restore the current class */
10674   current_class = saved_current_class;
10675 }
10676
10677 static int
10678 breakdown_qualified (left, right, source)
10679     tree *left, *right, source;
10680 {
10681   char *p = IDENTIFIER_POINTER (source), *base;
10682   int   l = IDENTIFIER_LENGTH (source);
10683
10684   /* Breakdown NAME into REMAINDER . IDENTIFIER */
10685   base = p;
10686   p += (l-1);
10687   while (*p != '.' && p != base)
10688     p--;
10689
10690   /* We didn't find a '.'. Return an error */
10691   if (p == base)
10692     return 1;
10693
10694   *p = '\0';
10695   if (right)
10696     *right = get_identifier (p+1);
10697   *left = get_identifier (IDENTIFIER_POINTER (source));
10698   *p = '.';
10699   
10700   return 0;
10701 }
10702
10703 /* Patch tree nodes in a function body. When a BLOCK is found, push
10704    local variable decls if present.
10705    Same as java_complete_lhs, but does resolve static finals to values. */
10706
10707 static tree
10708 java_complete_tree (node)
10709      tree node;
10710 {
10711   node = java_complete_lhs (node);
10712   if (JDECL_P (node) && FIELD_STATIC (node) && FIELD_FINAL (node) 
10713       && DECL_INITIAL (node) != NULL_TREE
10714       && !flag_emit_xref)
10715     {
10716       tree value = DECL_INITIAL (node);
10717       DECL_INITIAL (node) = NULL_TREE;
10718       push_obstacks (&permanent_obstack, &permanent_obstack);
10719       value = fold_constant_for_init (value, node);
10720       pop_obstacks ();
10721       DECL_INITIAL (node) = value;
10722       if (value != NULL_TREE)
10723         {
10724           /* fold_constant_for_init sometimes widen the original type
10725              of the constant (i.e. byte to int.) It's not desirable,
10726              especially if NODE is a function argument. */
10727           if (TREE_CODE (value) == INTEGER_CST
10728               && TREE_TYPE (node) != TREE_TYPE (value))
10729             return convert (TREE_TYPE (node), value);
10730           else
10731             return value;
10732         }
10733     }
10734   return node;
10735 }
10736
10737 static tree
10738 java_stabilize_reference (node)
10739      tree node;
10740 {
10741   if (TREE_CODE (node) == COMPOUND_EXPR)
10742     {
10743       tree op0 = TREE_OPERAND (node, 0);
10744       tree op1 = TREE_OPERAND (node, 1);
10745       TREE_OPERAND (node, 0) = save_expr (op0);
10746       TREE_OPERAND (node, 1) = java_stabilize_reference (op1);
10747       return node;
10748     }
10749   return stabilize_reference (node);
10750 }
10751
10752 /* Patch tree nodes in a function body. When a BLOCK is found, push
10753    local variable decls if present.
10754    Same as java_complete_tree, but does not resolve static finals to values. */
10755
10756 static tree
10757 java_complete_lhs (node)
10758      tree node;
10759 {
10760   tree nn, cn, wfl_op1, wfl_op2, wfl_op3;
10761   int flag;
10762
10763   /* CONVERT_EXPR always has its type set, even though it needs to be
10764      worked out. */
10765   if (TREE_TYPE (node) && TREE_CODE (node) != CONVERT_EXPR)
10766     return node;
10767
10768   /* The switch block implements cases processing container nodes
10769      first.  Contained nodes are always written back. Leaves come
10770      next and return a value. */
10771   switch (TREE_CODE (node))
10772     {
10773     case BLOCK:
10774
10775       /* 1- Block section.
10776          Set the local values on decl names so we can identify them
10777          faster when they're referenced. At that stage, identifiers
10778          are legal so we don't check for declaration errors. */
10779       for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
10780         {
10781           DECL_CONTEXT (cn) = current_function_decl;
10782           IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = cn;
10783         }
10784       if (BLOCK_EXPR_BODY (node) == NULL_TREE)
10785           CAN_COMPLETE_NORMALLY (node) = 1;
10786       else
10787         {
10788           tree stmt = BLOCK_EXPR_BODY (node);
10789           tree *ptr;
10790           int error_seen = 0;
10791           if (TREE_CODE (stmt) == COMPOUND_EXPR)
10792             {
10793               /* Re-order from (((A; B); C); ...; Z) to 
10794                  (A; (B; (C ; (...; Z)))).
10795                  This makes it easier to scan the statements left-to-right
10796                  without using recursion (which might overflow the stack
10797                  if the block has many statements. */
10798               for (;;)
10799                 {
10800                   tree left = TREE_OPERAND (stmt, 0);
10801                   if (TREE_CODE (left) != COMPOUND_EXPR)
10802                     break;
10803                   TREE_OPERAND (stmt, 0) = TREE_OPERAND (left, 1);
10804                   TREE_OPERAND (left, 1) = stmt;
10805                   stmt = left;
10806                 }
10807               BLOCK_EXPR_BODY (node) = stmt;
10808             }
10809
10810           /* Now do the actual complete, without deep recursion for
10811              long blocks. */
10812           ptr = &BLOCK_EXPR_BODY (node);
10813           while (TREE_CODE (*ptr) == COMPOUND_EXPR
10814                  && TREE_OPERAND (*ptr, 1) != empty_stmt_node)
10815             {
10816               tree cur = java_complete_tree (TREE_OPERAND (*ptr, 0));
10817               tree *next = &TREE_OPERAND (*ptr, 1);
10818               TREE_OPERAND (*ptr, 0) = cur;
10819               if (cur == empty_stmt_node)
10820                 {
10821                   /* Optimization;  makes it easier to detect empty bodies.
10822                      Most useful for <clinit> with all-constant initializer. */
10823                   *ptr = *next;
10824                   continue;
10825                 }
10826               if (TREE_CODE (cur) == ERROR_MARK)
10827                 error_seen++;
10828               else if (! CAN_COMPLETE_NORMALLY (cur))
10829                 {
10830                   wfl_op2 = *next;
10831                   for (;;)
10832                     {
10833                       if (TREE_CODE (wfl_op2) == BLOCK)
10834                         wfl_op2 = BLOCK_EXPR_BODY (wfl_op2);
10835                       else if (TREE_CODE (wfl_op2) == COMPOUND_EXPR)
10836                         wfl_op2 = TREE_OPERAND (wfl_op2, 0);
10837                       else
10838                         break;
10839                     }
10840                   if (TREE_CODE (wfl_op2) != CASE_EXPR
10841                       && TREE_CODE (wfl_op2) != DEFAULT_EXPR)
10842                     unreachable_stmt_error (*ptr);
10843                 }
10844               ptr = next;
10845             }
10846           *ptr = java_complete_tree (*ptr);
10847
10848           if (TREE_CODE (*ptr) == ERROR_MARK || error_seen > 0)
10849             return error_mark_node;
10850           CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (*ptr);
10851         }
10852       /* Turn local bindings to null */
10853       for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
10854         IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = NULL_TREE;
10855
10856       TREE_TYPE (node) = void_type_node;
10857       break;
10858
10859       /* 2- They are expressions but ultimately deal with statements */
10860
10861     case THROW_EXPR:
10862       wfl_op1 = TREE_OPERAND (node, 0);
10863       COMPLETE_CHECK_OP_0 (node);
10864       /* 14.19 A throw statement cannot complete normally. */
10865       CAN_COMPLETE_NORMALLY (node) = 0;
10866       return patch_throw_statement (node, wfl_op1);
10867
10868     case SYNCHRONIZED_EXPR:
10869       wfl_op1 = TREE_OPERAND (node, 0);
10870       return patch_synchronized_statement (node, wfl_op1);
10871
10872     case TRY_EXPR:
10873       return patch_try_statement (node);
10874
10875     case TRY_FINALLY_EXPR:
10876       COMPLETE_CHECK_OP_0 (node);
10877       COMPLETE_CHECK_OP_1 (node);
10878       CAN_COMPLETE_NORMALLY (node)
10879         = (CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0))
10880            && CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)));
10881       TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 0));
10882       return node;
10883
10884     case CLEANUP_POINT_EXPR:
10885       COMPLETE_CHECK_OP_0 (node);
10886       TREE_TYPE (node) = void_type_node;
10887       CAN_COMPLETE_NORMALLY (node) = 
10888         CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
10889       return node;
10890
10891     case WITH_CLEANUP_EXPR:
10892       COMPLETE_CHECK_OP_0 (node);
10893       COMPLETE_CHECK_OP_2 (node);
10894       CAN_COMPLETE_NORMALLY (node) = 
10895         CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
10896       TREE_TYPE (node) = void_type_node;
10897       return node;
10898
10899     case LABELED_BLOCK_EXPR:
10900       PUSH_LABELED_BLOCK (node);
10901       if (LABELED_BLOCK_BODY (node))
10902         COMPLETE_CHECK_OP_1 (node);
10903       TREE_TYPE (node) = void_type_node;
10904       POP_LABELED_BLOCK ();
10905
10906       if (LABELED_BLOCK_BODY (node) == empty_stmt_node)
10907         {
10908           LABELED_BLOCK_BODY (node) = NULL_TREE;
10909           CAN_COMPLETE_NORMALLY (node) = 1;
10910         }
10911       else if (CAN_COMPLETE_NORMALLY (LABELED_BLOCK_BODY (node)))
10912         CAN_COMPLETE_NORMALLY (node) = 1;
10913       return node;
10914
10915     case EXIT_BLOCK_EXPR:
10916       /* We don't complete operand 1, because it's the return value of
10917          the EXIT_BLOCK_EXPR which doesn't exist it Java */
10918       return patch_bc_statement (node);
10919
10920     case CASE_EXPR:
10921       cn = java_complete_tree (TREE_OPERAND (node, 0));
10922       if (cn == error_mark_node)
10923         return cn;
10924
10925       /* First, the case expression must be constant. Values of final
10926          fields are accepted. */
10927       cn = fold (cn);
10928       if ((TREE_CODE (cn) == COMPOUND_EXPR || TREE_CODE (cn) == COMPONENT_REF)
10929           && JDECL_P (TREE_OPERAND (cn, 1))
10930           && FIELD_FINAL (TREE_OPERAND (cn, 1))
10931           && DECL_INITIAL (TREE_OPERAND (cn, 1)))
10932         {
10933           push_obstacks (&permanent_obstack, &permanent_obstack);
10934           cn = fold_constant_for_init (DECL_INITIAL (TREE_OPERAND (cn, 1)),
10935                                        TREE_OPERAND (cn, 1));
10936           pop_obstacks ();
10937         }
10938
10939       if (!TREE_CONSTANT (cn) && !flag_emit_xref)
10940         {
10941           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10942           parse_error_context (node, "Constant expression required");
10943           return error_mark_node;
10944         }
10945
10946       nn = ctxp->current_loop;
10947
10948       /* It must be assignable to the type of the switch expression. */
10949       if (!try_builtin_assignconv (NULL_TREE, 
10950                                    TREE_TYPE (TREE_OPERAND (nn, 0)), cn))
10951         {
10952           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10953           parse_error_context 
10954             (wfl_operator,
10955              "Incompatible type for case. Can't convert `%s' to `int'",
10956              lang_printable_name (TREE_TYPE (cn), 0));
10957           return error_mark_node;
10958         }
10959
10960       cn = fold (convert (int_type_node, cn));
10961
10962       /* Multiple instance of a case label bearing the same
10963          value is checked during code generation. The case
10964          expression is allright so far. */
10965       TREE_OPERAND (node, 0) = cn;
10966       TREE_TYPE (node) = void_type_node;
10967       CAN_COMPLETE_NORMALLY (node) = 1;
10968       TREE_SIDE_EFFECTS (node) = 1;
10969       break;
10970
10971     case DEFAULT_EXPR:
10972       nn = ctxp->current_loop;
10973       /* Only one default label is allowed per switch statement */
10974       if (SWITCH_HAS_DEFAULT (nn))
10975         {
10976           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10977           parse_error_context (wfl_operator, 
10978                                "Duplicate case label: `default'");
10979           return error_mark_node;
10980         }
10981       else
10982         SWITCH_HAS_DEFAULT (nn) = 1;
10983       TREE_TYPE (node) = void_type_node;
10984       TREE_SIDE_EFFECTS (node) = 1;
10985       CAN_COMPLETE_NORMALLY (node) = 1;
10986       break;
10987
10988     case SWITCH_EXPR:
10989     case LOOP_EXPR:
10990       PUSH_LOOP (node);
10991       /* Check whether the loop was enclosed in a labeled
10992          statement. If not, create one, insert the loop in it and
10993          return the node */
10994       nn = patch_loop_statement (node);
10995
10996       /* Anyways, walk the body of the loop */
10997       if (TREE_CODE (node) == LOOP_EXPR)
10998         TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
10999       /* Switch statement: walk the switch expression and the cases */
11000       else
11001         node = patch_switch_statement (node);
11002
11003       if (node == error_mark_node || TREE_OPERAND (node, 0) == error_mark_node)
11004         nn = error_mark_node;
11005       else
11006         {
11007           TREE_TYPE (nn) = TREE_TYPE (node) = void_type_node;
11008           /* If we returned something different, that's because we
11009              inserted a label. Pop the label too. */
11010           if (nn != node)
11011             {
11012               if (CAN_COMPLETE_NORMALLY (node))
11013                 CAN_COMPLETE_NORMALLY (nn) = 1;
11014               POP_LABELED_BLOCK ();
11015             }
11016         }
11017       POP_LOOP ();
11018       return nn;
11019
11020     case EXIT_EXPR:
11021       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
11022       return patch_exit_expr (node);
11023
11024     case COND_EXPR:
11025       /* Condition */
11026       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
11027       if (TREE_OPERAND (node, 0) == error_mark_node)
11028         return error_mark_node;
11029       /* then-else branches */
11030       TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
11031       if (TREE_OPERAND (node, 1) == error_mark_node)
11032         return error_mark_node;
11033       TREE_OPERAND (node, 2) = java_complete_tree (TREE_OPERAND (node, 2));
11034       if (TREE_OPERAND (node, 2) == error_mark_node)
11035         return error_mark_node;
11036       return patch_if_else_statement (node);
11037       break;
11038
11039     case CONDITIONAL_EXPR:
11040       /* Condition */
11041       wfl_op1 = TREE_OPERAND (node, 0);
11042       COMPLETE_CHECK_OP_0 (node);
11043       wfl_op2 = TREE_OPERAND (node, 1);
11044       COMPLETE_CHECK_OP_1 (node);
11045       wfl_op3 = TREE_OPERAND (node, 2);
11046       COMPLETE_CHECK_OP_2 (node);
11047       return patch_conditional_expr (node, wfl_op1, wfl_op2);
11048
11049       /* 3- Expression section */
11050     case COMPOUND_EXPR:
11051       wfl_op2 = TREE_OPERAND (node, 1);
11052       TREE_OPERAND (node, 0) = nn = 
11053         java_complete_tree (TREE_OPERAND (node, 0));
11054       if (wfl_op2 == empty_stmt_node)
11055         CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (nn);
11056       else
11057         {
11058           if (! CAN_COMPLETE_NORMALLY (nn) && TREE_CODE (nn) != ERROR_MARK)
11059             {
11060               /* An unreachable condition in a do-while statement
11061                  is *not* (technically) an unreachable statement. */
11062               nn = wfl_op2;
11063               if (TREE_CODE (nn) == EXPR_WITH_FILE_LOCATION)
11064                 nn = EXPR_WFL_NODE (nn);
11065               if (TREE_CODE (nn) != EXIT_EXPR)
11066                 {
11067                   SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
11068                   parse_error_context (wfl_operator, "Unreachable statement");
11069                 }
11070             }
11071           TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
11072           if (TREE_OPERAND (node, 1) == error_mark_node)
11073             return error_mark_node;
11074           CAN_COMPLETE_NORMALLY (node)
11075             = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1));
11076         }
11077       TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 1));
11078       break;
11079
11080     case RETURN_EXPR:
11081       /* CAN_COMPLETE_NORMALLY (node) = 0; */
11082       return patch_return (node);
11083
11084     case EXPR_WITH_FILE_LOCATION:
11085       if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
11086           || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
11087         {
11088           tree wfl = node;
11089           node = resolve_expression_name (node, NULL);
11090           if (node == error_mark_node)
11091             return node;
11092           /* Keep line number information somewhere were it doesn't
11093              disrupt the completion process. */
11094           if (flag_emit_xref && TREE_CODE (node) != CALL_EXPR)
11095             {
11096               EXPR_WFL_NODE (wfl) = TREE_OPERAND (node, 1);
11097               TREE_OPERAND (node, 1) = wfl;
11098             }
11099           CAN_COMPLETE_NORMALLY (node) = 1;
11100         }
11101       else
11102         {
11103           tree body;
11104           int save_lineno = lineno;
11105           lineno = EXPR_WFL_LINENO (node);
11106           body = java_complete_tree (EXPR_WFL_NODE (node));
11107           lineno = save_lineno;
11108           EXPR_WFL_NODE (node) = body;
11109           TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (body);
11110           CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (body);
11111           if (body == empty_stmt_node)
11112             {
11113               /* Optimization;  makes it easier to detect empty bodies. */
11114               return body;
11115             }
11116           if (body == error_mark_node)
11117             {
11118               /* Its important for the evaluation of assignment that
11119                  this mark on the TREE_TYPE is propagated. */
11120               TREE_TYPE (node) = error_mark_node;
11121               return error_mark_node;
11122             }
11123           else
11124             TREE_TYPE (node) = TREE_TYPE (EXPR_WFL_NODE (node));
11125           
11126         }
11127       break;
11128
11129     case NEW_ARRAY_EXPR:
11130       /* Patch all the dimensions */
11131       flag = 0;
11132       for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
11133         {
11134           int location = EXPR_WFL_LINECOL (TREE_VALUE (cn));
11135           tree dim = convert (int_type_node, 
11136                               java_complete_tree (TREE_VALUE (cn)));
11137           if (dim == error_mark_node)
11138             {
11139               flag = 1;
11140               continue;
11141             }
11142           else
11143             {
11144               TREE_VALUE (cn) = dim;
11145               /* Setup the location of the current dimension, for
11146                  later error report. */
11147               TREE_PURPOSE (cn) = 
11148                 build_expr_wfl (NULL_TREE, input_filename, 0, 0);
11149               EXPR_WFL_LINECOL (TREE_PURPOSE (cn)) = location;
11150             }
11151         }
11152       /* They complete the array creation expression, if no errors
11153          were found. */
11154       CAN_COMPLETE_NORMALLY (node) = 1;
11155       return (flag ? error_mark_node
11156               : force_evaluation_order (patch_newarray (node)));
11157
11158     case NEW_ANONYMOUS_ARRAY_EXPR:
11159       /* Create the array type if necessary. */
11160       if (ANONYMOUS_ARRAY_DIMS_SIG (node))
11161         {
11162           tree type = ANONYMOUS_ARRAY_BASE_TYPE (node);
11163           if (!(type = resolve_type_during_patch (type)))
11164             return error_mark_node;
11165           type = build_array_from_name (type, NULL_TREE,
11166                                         ANONYMOUS_ARRAY_DIMS_SIG (node), NULL);
11167           ANONYMOUS_ARRAY_BASE_TYPE (node) = build_pointer_type (type);
11168         }
11169       node = patch_new_array_init (ANONYMOUS_ARRAY_BASE_TYPE (node),
11170                                    ANONYMOUS_ARRAY_INITIALIZER (node));
11171       if (node == error_mark_node)
11172         return error_mark_node;
11173       CAN_COMPLETE_NORMALLY (node) = 1;
11174       return node;
11175
11176     case NEW_CLASS_EXPR:
11177     case CALL_EXPR:
11178       /* Complete function's argument(s) first */
11179       if (complete_function_arguments (node))
11180         return error_mark_node;
11181       else
11182         {
11183           tree decl, wfl = TREE_OPERAND (node, 0);
11184           int in_this = CALL_THIS_CONSTRUCTOR_P (node);
11185
11186           node = patch_method_invocation (node, NULL_TREE, 
11187                                           NULL_TREE, 0, &decl);
11188           if (node == error_mark_node)
11189             return error_mark_node;
11190
11191           check_thrown_exceptions (EXPR_WFL_LINECOL (node), decl);
11192           /* If we call this(...), register signature and positions */
11193           if (in_this)
11194             DECL_CONSTRUCTOR_CALLS (current_function_decl) = 
11195               tree_cons (wfl, decl, 
11196                          DECL_CONSTRUCTOR_CALLS (current_function_decl));
11197           CAN_COMPLETE_NORMALLY (node) = 1;
11198           return force_evaluation_order (node);
11199         }
11200
11201     case MODIFY_EXPR:
11202       /* Save potential wfls */
11203       wfl_op1 = TREE_OPERAND (node, 0);
11204       TREE_OPERAND (node, 0) = nn = java_complete_lhs (wfl_op1);
11205       
11206       if (MODIFY_EXPR_FROM_INITIALIZATION_P (node)
11207           && TREE_CODE (nn) == VAR_DECL && TREE_STATIC (nn)
11208           && DECL_INITIAL (nn) != NULL_TREE)
11209         {
11210           tree value;
11211           
11212           push_obstacks (&permanent_obstack, &permanent_obstack);
11213           value = fold_constant_for_init (nn, nn);
11214           pop_obstacks ();
11215
11216           if (value != NULL_TREE)
11217             {
11218               tree type = TREE_TYPE (value);
11219               if (JPRIMITIVE_TYPE_P (type) || 
11220                   (type == string_ptr_type_node && ! flag_emit_class_files))
11221                 return empty_stmt_node;
11222             }
11223           if (! flag_emit_class_files)
11224             DECL_INITIAL (nn) = NULL_TREE;
11225         }
11226       wfl_op2 = TREE_OPERAND (node, 1);
11227
11228       if (TREE_OPERAND (node, 0) == error_mark_node)
11229         return error_mark_node;
11230
11231       flag = COMPOUND_ASSIGN_P (wfl_op2);
11232       if (flag)
11233         {
11234           /* This might break when accessing outer field from inner
11235              class. TESTME, FIXME */
11236           tree lvalue = java_stabilize_reference (TREE_OPERAND (node, 0)); 
11237
11238           /* Hand stablize the lhs on both places */
11239           TREE_OPERAND (node, 0) = lvalue;
11240           TREE_OPERAND (TREE_OPERAND (node, 1), 0) = 
11241             (flag_emit_class_files ? lvalue : save_expr (lvalue));
11242
11243           /* 15.25.2.a: Left hand is not an array access. FIXME */
11244           /* Now complete the RHS. We write it back later on. */
11245           nn = java_complete_tree (TREE_OPERAND (node, 1));
11246
11247           if ((cn = patch_string (nn)))
11248             nn = cn;
11249
11250           /* The last part of the rewrite for E1 op= E2 is to have 
11251              E1 = (T)(E1 op E2), with T being the type of E1. */
11252           nn = java_complete_tree (build_cast (EXPR_WFL_LINECOL (wfl_op2), 
11253                                                TREE_TYPE (lvalue), nn));
11254
11255           /* 15.25.2.b: Left hand is an array access. FIXME */
11256         }
11257
11258       /* If we're about to patch a NEW_ARRAY_INIT, we call a special
11259          function to complete this RHS. Note that a NEW_ARRAY_INIT
11260          might have been already fully expanded if created as a result
11261          of processing an anonymous array initializer. We avoid doing
11262          the operation twice by testing whether the node already bears
11263          a type. */
11264       else if (TREE_CODE (wfl_op2) == NEW_ARRAY_INIT && !TREE_TYPE (wfl_op2))
11265         nn = patch_new_array_init (TREE_TYPE (TREE_OPERAND (node, 0)),
11266                                    TREE_OPERAND (node, 1));
11267       /* Otherwise we simply complete the RHS */
11268       else
11269         nn = java_complete_tree (TREE_OPERAND (node, 1));
11270
11271       if (nn == error_mark_node)
11272         return error_mark_node;
11273
11274       /* Write back the RHS as we evaluated it. */
11275       TREE_OPERAND (node, 1) = nn;
11276
11277       /* In case we're handling = with a String as a RHS, we need to
11278          produce a String out of the RHS (it might still be a
11279          STRING_CST or a StringBuffer at this stage */
11280       if ((nn = patch_string (TREE_OPERAND (node, 1))))
11281         TREE_OPERAND (node, 1) = nn;
11282
11283       if ((nn = outer_field_access_fix (wfl_op1, TREE_OPERAND (node, 0),
11284                                         TREE_OPERAND (node, 1))))
11285         {
11286           /* We return error_mark_node if outer_field_access_fix
11287              detects we write into a final. */
11288           if (nn == error_mark_node)
11289             return error_mark_node;
11290           node = nn;
11291         }
11292       else
11293         {
11294           node = patch_assignment (node, wfl_op1, wfl_op2);
11295           /* Reorganize the tree if necessary. */
11296           if (flag && (!JREFERENCE_TYPE_P (TREE_TYPE (node)) 
11297                        || JSTRING_P (TREE_TYPE (node))))
11298             node = java_refold (node);
11299         }
11300       
11301       CAN_COMPLETE_NORMALLY (node) = 1;
11302       return node;
11303
11304     case MULT_EXPR:
11305     case PLUS_EXPR:
11306     case MINUS_EXPR:
11307     case LSHIFT_EXPR:
11308     case RSHIFT_EXPR:
11309     case URSHIFT_EXPR:
11310     case BIT_AND_EXPR:
11311     case BIT_XOR_EXPR:
11312     case BIT_IOR_EXPR:
11313     case TRUNC_MOD_EXPR:
11314     case TRUNC_DIV_EXPR:
11315     case RDIV_EXPR:
11316     case TRUTH_ANDIF_EXPR:
11317     case TRUTH_ORIF_EXPR:
11318     case EQ_EXPR: 
11319     case NE_EXPR:
11320     case GT_EXPR:
11321     case GE_EXPR:
11322     case LT_EXPR:
11323     case LE_EXPR:
11324       /* Operands 0 and 1 are WFL in certain cases only. patch_binop
11325          knows how to handle those cases. */
11326       wfl_op1 = TREE_OPERAND (node, 0);
11327       wfl_op2 = TREE_OPERAND (node, 1);
11328
11329       CAN_COMPLETE_NORMALLY (node) = 1;
11330       /* Don't complete string nodes if dealing with the PLUS operand. */
11331       if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op1))
11332         {
11333           nn = java_complete_tree (wfl_op1);
11334           if (nn == error_mark_node)
11335             return error_mark_node;
11336
11337           TREE_OPERAND (node, 0) = nn;
11338         }
11339       if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op2))
11340         {
11341           nn = java_complete_tree (wfl_op2);
11342           if (nn == error_mark_node)
11343             return error_mark_node;
11344
11345           TREE_OPERAND (node, 1) = nn;
11346         }
11347       return force_evaluation_order (patch_binop (node, wfl_op1, wfl_op2));
11348
11349     case INSTANCEOF_EXPR:
11350       wfl_op1 = TREE_OPERAND (node, 0);
11351       COMPLETE_CHECK_OP_0 (node);
11352       if (flag_emit_xref)
11353         {
11354           TREE_TYPE (node) = boolean_type_node;
11355           return node;
11356         }
11357       return patch_binop (node, wfl_op1, TREE_OPERAND (node, 1));
11358
11359     case UNARY_PLUS_EXPR:
11360     case NEGATE_EXPR:
11361     case TRUTH_NOT_EXPR:
11362     case BIT_NOT_EXPR:
11363     case PREDECREMENT_EXPR:
11364     case PREINCREMENT_EXPR:
11365     case POSTDECREMENT_EXPR:
11366     case POSTINCREMENT_EXPR:
11367     case CONVERT_EXPR:
11368       /* There are cases were wfl_op1 is a WFL. patch_unaryop knows
11369          how to handle those cases. */
11370       wfl_op1 = TREE_OPERAND (node, 0);
11371       CAN_COMPLETE_NORMALLY (node) = 1;
11372       TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
11373       if (TREE_OPERAND (node, 0) == error_mark_node)
11374         return error_mark_node;
11375       node = patch_unaryop (node, wfl_op1);
11376       CAN_COMPLETE_NORMALLY (node) = 1;
11377       break;
11378
11379     case ARRAY_REF:
11380       /* There are cases were wfl_op1 is a WFL. patch_array_ref knows
11381          how to handle those cases. */
11382       wfl_op1 = TREE_OPERAND (node, 0);
11383       TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
11384       if (TREE_OPERAND (node, 0) == error_mark_node)
11385         return error_mark_node;
11386       if (!flag_emit_class_files && !flag_emit_xref)
11387         TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
11388       /* The same applies to wfl_op2 */
11389       wfl_op2 = TREE_OPERAND (node, 1);
11390       TREE_OPERAND (node, 1) = java_complete_tree (wfl_op2);
11391       if (TREE_OPERAND (node, 1) == error_mark_node)
11392         return error_mark_node;
11393       if (!flag_emit_class_files && !flag_emit_xref)
11394         TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1));
11395       return patch_array_ref (node);
11396
11397     case RECORD_TYPE:
11398       return node;;
11399
11400     case COMPONENT_REF:
11401       /* The first step in the re-write of qualified name handling.  FIXME.
11402          So far, this is only to support PRIMTYPE.class -> PRIMCLASS.TYPE. */
11403       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
11404       if (TREE_CODE (TREE_OPERAND (node, 0)) == RECORD_TYPE)
11405         {
11406           tree name = TREE_OPERAND (node, 1);
11407           tree field = lookup_field_wrapper (TREE_OPERAND (node, 0), name);
11408           if (field == NULL_TREE)
11409             {
11410               error ("missing static field `%s'", IDENTIFIER_POINTER (name));
11411               return error_mark_node;
11412             }
11413           if (! FIELD_STATIC (field))
11414             {
11415               error ("not a static field `%s'", IDENTIFIER_POINTER (name));
11416               return error_mark_node;
11417             }
11418           return field;
11419         }
11420       else
11421         fatal ("unimplemented java_complete_tree for COMPONENT_REF");
11422       break;
11423
11424     case THIS_EXPR:
11425       /* Can't use THIS in a static environment */
11426       if (!current_this)
11427         {
11428           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11429           parse_error_context (wfl_operator,
11430                                "Keyword `this' used outside allowed context");
11431           TREE_TYPE (node) = error_mark_node;
11432           return error_mark_node;
11433         }
11434       if (ctxp->explicit_constructor_p)
11435         {
11436           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11437           parse_error_context 
11438             (wfl_operator, "Can't reference `this' or `super' before the superclass constructor has been called");
11439           TREE_TYPE (node) = error_mark_node;
11440           return error_mark_node;
11441         }
11442       return current_this;
11443       
11444     case CLASS_LITERAL:
11445       CAN_COMPLETE_NORMALLY (node) = 1;
11446       node = patch_incomplete_class_ref (node);
11447       if (node == error_mark_node)
11448         return error_mark_node;
11449       break;
11450
11451     case INSTANCE_INITIALIZERS_EXPR:
11452       in_instance_initializer++;
11453       node = java_complete_tree (TREE_OPERAND (node, 0));
11454       in_instance_initializer--;
11455       if (node != error_mark_node)
11456         TREE_TYPE (node) = void_type_node;
11457       else
11458         return error_mark_node;
11459       break;
11460
11461     default:
11462       CAN_COMPLETE_NORMALLY (node) = 1;
11463       /* Ok: may be we have a STRING_CST or a crafted `StringBuffer'
11464          and it's time to turn it into the appropriate String object */
11465       if ((nn = patch_string (node)))
11466         node = nn;
11467       else
11468         fatal ("No case for tree code `%s' - java_complete_tree\n",
11469                tree_code_name [TREE_CODE (node)]);
11470     }
11471   return node;
11472 }
11473
11474 /* Complete function call's argument. Return a non zero value is an
11475    error was found.  */
11476
11477 static int
11478 complete_function_arguments (node)
11479      tree node;
11480 {
11481   int flag = 0;
11482   tree cn;
11483
11484   ctxp->explicit_constructor_p += (CALL_EXPLICIT_CONSTRUCTOR_P (node) ? 1 : 0);
11485   for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
11486     {
11487       tree wfl = TREE_VALUE (cn), parm, temp;
11488       parm = java_complete_tree (wfl);
11489
11490       if (parm == error_mark_node)
11491         {
11492           flag = 1;
11493           continue;
11494         }
11495       /* If have a string literal that we haven't transformed yet or a
11496          crafted string buffer, as a result of use of the the String
11497          `+' operator. Build `parm.toString()' and expand it. */
11498       if ((temp = patch_string (parm)))
11499         parm = temp;
11500       /* Inline PRIMTYPE.TYPE read access */
11501       parm = maybe_build_primttype_type_ref (parm, wfl);
11502
11503       TREE_VALUE (cn) = parm;
11504     }
11505   ctxp->explicit_constructor_p -= (CALL_EXPLICIT_CONSTRUCTOR_P (node) ? 1 : 0);
11506   return flag;
11507 }
11508
11509 /* Sometimes (for loops and variable initialized during their
11510    declaration), we want to wrap a statement around a WFL and turn it
11511    debugable.  */
11512
11513 static tree
11514 build_debugable_stmt (location, stmt)
11515     int location;
11516     tree stmt;
11517 {
11518   if (TREE_CODE (stmt) != EXPR_WITH_FILE_LOCATION)
11519     {
11520       stmt = build_expr_wfl (stmt, input_filename, 0, 0);
11521       EXPR_WFL_LINECOL (stmt) = location;
11522     }
11523   JAVA_MAYBE_GENERATE_DEBUG_INFO (stmt);
11524   return stmt;
11525 }
11526
11527 static tree
11528 build_expr_block (body, decls)
11529      tree body, decls;
11530 {
11531   tree node = make_node (BLOCK);
11532   BLOCK_EXPR_DECLS (node) = decls;
11533   BLOCK_EXPR_BODY (node) = body;
11534   if (body)
11535     TREE_TYPE (node) = TREE_TYPE (body);
11536   TREE_SIDE_EFFECTS (node) = 1;
11537   return node;
11538 }
11539
11540 /* Create a new function block and link it approriately to current
11541    function block chain */
11542
11543 static tree
11544 enter_block ()
11545 {
11546   return (enter_a_block (build_expr_block (NULL_TREE, NULL_TREE)));
11547 }
11548
11549 /* Link block B supercontext to the previous block. The current
11550    function DECL is used as supercontext when enter_a_block is called
11551    for the first time for a given function. The current function body
11552    (DECL_FUNCTION_BODY) is set to be block B.  */
11553
11554 static tree
11555 enter_a_block (b)
11556      tree b;
11557 {
11558   tree fndecl = current_function_decl; 
11559
11560   if (!fndecl) {
11561     BLOCK_SUPERCONTEXT (b) = current_static_block;
11562     current_static_block = b;
11563   }
11564
11565   else if (!DECL_FUNCTION_BODY (fndecl))
11566     {
11567       BLOCK_SUPERCONTEXT (b) = fndecl;
11568       DECL_FUNCTION_BODY (fndecl) = b;
11569     }
11570   else
11571     {
11572       BLOCK_SUPERCONTEXT (b) = DECL_FUNCTION_BODY (fndecl);
11573       DECL_FUNCTION_BODY (fndecl) = b;
11574     }
11575   return b;
11576 }
11577
11578 /* Exit a block by changing the current function body
11579    (DECL_FUNCTION_BODY) to the current block super context, only if
11580    the block being exited isn't the method's top level one.  */
11581
11582 static tree
11583 exit_block ()
11584 {
11585   tree b;
11586   if (current_function_decl)
11587     {
11588       b = DECL_FUNCTION_BODY (current_function_decl);
11589       if (BLOCK_SUPERCONTEXT (b) != current_function_decl)
11590         DECL_FUNCTION_BODY (current_function_decl) = BLOCK_SUPERCONTEXT (b);
11591     }
11592   else
11593     {
11594       b = current_static_block;
11595
11596       if (BLOCK_SUPERCONTEXT (b))
11597         current_static_block = BLOCK_SUPERCONTEXT (b);
11598     }
11599   return b;
11600 }
11601
11602 /* Lookup for NAME in the nested function's blocks, all the way up to
11603    the current toplevel one. It complies with Java's local variable
11604    scoping rules.  */
11605
11606 static tree
11607 lookup_name_in_blocks (name)
11608      tree name;
11609 {
11610   tree b = GET_CURRENT_BLOCK (current_function_decl);
11611
11612   while (b != current_function_decl)
11613     {
11614       tree current;
11615
11616       /* Paranoid sanity check. To be removed */
11617       if (TREE_CODE (b) != BLOCK)
11618         fatal ("non block expr function body - lookup_name_in_blocks");
11619
11620       for (current = BLOCK_EXPR_DECLS (b); current; 
11621            current = TREE_CHAIN (current))
11622         if (DECL_NAME (current) == name)
11623           return current;
11624       b = BLOCK_SUPERCONTEXT (b);
11625     }
11626   return NULL_TREE;
11627 }
11628
11629 static void
11630 maybe_absorb_scoping_blocks ()
11631 {
11632   while (BLOCK_EXPR_ORIGIN (GET_CURRENT_BLOCK (current_function_decl)))
11633     {
11634       tree b = exit_block ();
11635       java_method_add_stmt (current_function_decl, b);
11636       SOURCE_FRONTEND_DEBUG (("Absorbing scoping block at line %d", lineno));
11637     }
11638 }
11639
11640 \f
11641 /* This section of the source is reserved to build_* functions that
11642    are building incomplete tree nodes and the patch_* functions that
11643    are completing them.  */
11644
11645 /* Wrap a non WFL node around a WFL.  */
11646 static tree
11647 build_wfl_wrap (node, location)
11648     tree node;
11649     int location;
11650 {
11651   tree wfl, node_to_insert = node;
11652   
11653   /* We want to process THIS . xxx symbolicaly, to keep it consistent
11654      with the way we're processing SUPER. A THIS from a primary as a
11655      different form than a SUPER. Turn THIS into something symbolic */
11656   if (TREE_CODE (node) == THIS_EXPR)
11657     node_to_insert = wfl = build_wfl_node (this_identifier_node);
11658   else
11659     wfl = build_expr_wfl (NULL_TREE, ctxp->filename, 0, 0);
11660
11661   EXPR_WFL_LINECOL (wfl) = location;
11662   EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (node_to_insert, NULL_TREE);
11663   return wfl;
11664 }
11665
11666
11667 /* Build a super() constructor invocation. Returns empty_stmt_node if
11668    we're currently dealing with the class java.lang.Object. */
11669
11670 static tree
11671 build_super_invocation (mdecl)
11672      tree mdecl;
11673 {
11674   if (DECL_CONTEXT (mdecl) == object_type_node)
11675     return empty_stmt_node;
11676   else
11677     {
11678       tree super_wfl = build_wfl_node (super_identifier_node);
11679       tree a = NULL_TREE, t;
11680       /* If we're dealing with an anonymous class, pass the arguments
11681          of the crafted constructor along. */
11682       if (ANONYMOUS_CLASS_P (DECL_CONTEXT (mdecl)))
11683         {
11684           SKIP_THIS_AND_ARTIFICIAL_PARMS (t, mdecl);
11685           for (; t != end_params_node; t = TREE_CHAIN (t))
11686             a = tree_cons (NULL_TREE, build_wfl_node (TREE_PURPOSE (t)), a);
11687         }
11688       return build_method_invocation (super_wfl, a);
11689     }
11690 }
11691
11692 /* Build a SUPER/THIS qualified method invocation.  */
11693
11694 static tree
11695 build_this_super_qualified_invocation (use_this, name, args, lloc, rloc)
11696      int use_this;
11697      tree name, args;
11698      int lloc, rloc;
11699 {
11700   tree invok;
11701   tree wfl = 
11702     build_wfl_node (use_this ? this_identifier_node : super_identifier_node);
11703   EXPR_WFL_LINECOL (wfl) = lloc;
11704   invok = build_method_invocation (name, args);
11705   return make_qualified_primary (wfl, invok, rloc);
11706 }
11707
11708 /* Build an incomplete CALL_EXPR node. */
11709
11710 static tree
11711 build_method_invocation (name, args)
11712     tree name;
11713     tree args;
11714 {
11715   tree call = build (CALL_EXPR, NULL_TREE, name, args, NULL_TREE);
11716   TREE_SIDE_EFFECTS (call) = 1;
11717   EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
11718   return call;
11719 }
11720
11721 /* Build an incomplete new xxx(...) node. */
11722
11723 static tree
11724 build_new_invocation (name, args)
11725     tree name, args;
11726 {
11727   tree call = build (NEW_CLASS_EXPR, NULL_TREE, name, args, NULL_TREE);
11728   TREE_SIDE_EFFECTS (call) = 1;
11729   EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
11730   return call;
11731 }
11732
11733 /* Build an incomplete assignment expression. */
11734
11735 static tree
11736 build_assignment (op, op_location, lhs, rhs)
11737      int op, op_location;
11738      tree lhs, rhs;
11739 {
11740   tree assignment;
11741   /* Build the corresponding binop if we deal with a Compound
11742      Assignment operator. Mark the binop sub-tree as part of a
11743      Compound Assignment expression */
11744   if (op != ASSIGN_TK)
11745     {
11746       rhs = build_binop (BINOP_LOOKUP (op), op_location, lhs, rhs);
11747       COMPOUND_ASSIGN_P (rhs) = 1;
11748     }
11749   assignment = build (MODIFY_EXPR, NULL_TREE, lhs, rhs);
11750   TREE_SIDE_EFFECTS (assignment) = 1;
11751   EXPR_WFL_LINECOL (assignment) = op_location;
11752   return assignment;
11753 }
11754
11755 /* Print an INTEGER_CST node in a static buffer, and return the buffer. */
11756
11757 char *
11758 print_int_node (node)
11759     tree node;
11760 {
11761   static char buffer [80];
11762   if (TREE_CONSTANT_OVERFLOW (node))
11763     sprintf (buffer, "<overflow>");
11764     
11765   if (TREE_INT_CST_HIGH (node) == 0)
11766     sprintf (buffer, HOST_WIDE_INT_PRINT_UNSIGNED,
11767              TREE_INT_CST_LOW (node));
11768   else if (TREE_INT_CST_HIGH (node) == -1
11769            && TREE_INT_CST_LOW (node) != 0)
11770     {
11771       buffer [0] = '-';
11772       sprintf (&buffer [1], HOST_WIDE_INT_PRINT_UNSIGNED,
11773                -TREE_INT_CST_LOW (node));
11774     }
11775   else
11776     sprintf (buffer, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
11777              TREE_INT_CST_HIGH (node), TREE_INT_CST_LOW (node));
11778
11779   return buffer;
11780 }
11781
11782 /* Return 1 if an assignment to a FINAL is attempted in a non suitable
11783    context.  */
11784
11785 static int
11786 check_final_assignment (lvalue, wfl)
11787      tree lvalue, wfl;
11788 {
11789   if (TREE_CODE (lvalue) == COMPOUND_EXPR 
11790       && JDECL_P (TREE_OPERAND (lvalue, 1)))
11791     lvalue = TREE_OPERAND (lvalue, 1);
11792
11793   /* When generating class files, references to the `length' field
11794      look a bit different.  */
11795   if ((flag_emit_class_files
11796        && TREE_CODE (lvalue) == COMPONENT_REF
11797        && TYPE_ARRAY_P (TREE_TYPE (TREE_OPERAND (lvalue, 0)))
11798        && FIELD_FINAL (TREE_OPERAND (lvalue, 1)))
11799       || (TREE_CODE (lvalue) == FIELD_DECL
11800           && FIELD_FINAL (lvalue)
11801           && !DECL_CLINIT_P (current_function_decl)
11802           && !DECL_FINIT_P (current_function_decl)))
11803     {
11804       parse_error_context 
11805         (wfl, "Can't assign a value to the final variable `%s'",
11806          IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
11807       return 1;
11808     }
11809   return 0;
11810 }
11811
11812 /* Inline references to java.lang.PRIMTYPE.TYPE when accessed in
11813    read. This is needed to avoid circularities in the implementation
11814    of these fields in libjava. */
11815
11816 static tree
11817 maybe_build_primttype_type_ref (rhs, wfl)
11818     tree rhs, wfl;
11819 {
11820   tree to_return = NULL_TREE;
11821   tree rhs_type = TREE_TYPE (rhs);
11822   if (TREE_CODE (rhs) == COMPOUND_EXPR)
11823     {
11824       tree n = TREE_OPERAND (rhs, 1);
11825       if (TREE_CODE (n) == VAR_DECL 
11826           && DECL_NAME (n) == TYPE_identifier_node
11827           && rhs_type == class_ptr_type
11828           && TREE_CODE (EXPR_WFL_NODE (wfl)) == IDENTIFIER_NODE)
11829         {
11830           const char *self_name = IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl));
11831           if (!strncmp (self_name, "java.lang.", 10))
11832             to_return = build_primtype_type_ref (self_name);
11833         }
11834     }
11835   return (to_return ? to_return : rhs );
11836 }
11837
11838 /* 15.25 Assignment operators. */
11839
11840 static tree
11841 patch_assignment (node, wfl_op1, wfl_op2)
11842      tree node;
11843      tree wfl_op1;
11844      tree wfl_op2;
11845 {
11846   tree rhs = TREE_OPERAND (node, 1);
11847   tree lvalue = TREE_OPERAND (node, 0), llvalue;
11848   tree lhs_type = NULL_TREE, rhs_type, new_rhs = NULL_TREE;
11849   int error_found = 0;
11850   int lvalue_from_array = 0;
11851
11852   /* Can't assign to a (blank) final. */
11853   if (check_final_assignment (lvalue, wfl_op1))
11854     error_found = 1;
11855
11856   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11857
11858   /* Lhs can be a named variable */
11859   if (JDECL_P (lvalue))
11860     {
11861       lhs_type = TREE_TYPE (lvalue);
11862     }
11863   /* Or Lhs can be a array acccess. Should that be lvalue ? FIXME +
11864      comment on reason why */
11865   else if (TREE_CODE (wfl_op1) == ARRAY_REF)
11866     {
11867       lhs_type = TREE_TYPE (lvalue);
11868       lvalue_from_array = 1;
11869     }
11870   /* Or a field access */
11871   else if (TREE_CODE (lvalue) == COMPONENT_REF)
11872     lhs_type = TREE_TYPE (lvalue);
11873   /* Or a function return slot */
11874   else if (TREE_CODE (lvalue) == RESULT_DECL)
11875     lhs_type = TREE_TYPE (lvalue);
11876   /* Otherwise, we might want to try to write into an optimized static
11877      final, this is an of a different nature, reported further on. */
11878   else if (TREE_CODE (wfl_op1) == EXPR_WITH_FILE_LOCATION
11879            && resolve_expression_name (wfl_op1, &llvalue))
11880     {
11881       if (!error_found && check_final_assignment (llvalue, wfl_op1))
11882         {
11883           /* What we should do instead is resetting the all the flags
11884              previously set, exchange lvalue for llvalue and continue. */
11885           error_found = 1;
11886           return error_mark_node;
11887         }
11888       else 
11889         lhs_type = TREE_TYPE (lvalue);
11890     }
11891   else 
11892     {
11893       parse_error_context (wfl_op1, "Invalid left hand side of assignment");
11894       error_found = 1;
11895     }
11896
11897   rhs_type = TREE_TYPE (rhs);
11898   /* 5.1 Try the assignment conversion for builtin type. */
11899   new_rhs = try_builtin_assignconv (wfl_op1, lhs_type, rhs);
11900
11901   /* 5.2 If it failed, try a reference conversion */
11902   if (!new_rhs && (new_rhs = try_reference_assignconv (lhs_type, rhs)))
11903     lhs_type = promote_type (rhs_type);
11904
11905   /* 15.25.2 If we have a compound assignment, convert RHS into the
11906      type of the LHS */
11907   else if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
11908     new_rhs = convert (lhs_type, rhs);
11909
11910   /* Explicit cast required. This is an error */
11911   if (!new_rhs)
11912     {
11913       char *t1 = xstrdup (lang_printable_name (TREE_TYPE (rhs), 0));
11914       char *t2 = xstrdup (lang_printable_name (lhs_type, 0));
11915       tree wfl;
11916       char operation [32];      /* Max size known */
11917
11918       /* If the assignment is part of a declaration, we use the WFL of
11919          the declared variable to point out the error and call it a
11920          declaration problem. If the assignment is a genuine =
11921          operator, we call is a operator `=' problem, otherwise we
11922          call it an assignment problem. In both of these last cases,
11923          we use the WFL of the operator to indicate the error. */
11924
11925       if (MODIFY_EXPR_FROM_INITIALIZATION_P (node))
11926         {
11927           wfl = wfl_op1;
11928           strcpy (operation, "declaration");
11929         }
11930       else
11931         {
11932           wfl = wfl_operator;
11933           if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
11934             strcpy (operation, "assignment");
11935           else if (TREE_CODE (TREE_OPERAND (node, 0)) == RESULT_DECL)
11936             strcpy (operation, "`return'");
11937           else
11938             strcpy (operation, "`='");
11939         }
11940
11941       if (!valid_cast_to_p (rhs_type, lhs_type))
11942         parse_error_context
11943           (wfl, "Incompatible type for %s. Can't convert `%s' to `%s'",
11944            operation, t1, t2);
11945       else
11946         parse_error_context (wfl, "Incompatible type for %s. Explicit cast needed to convert `%s' to `%s'",
11947                              operation, t1, t2);
11948       free (t1); free (t2);
11949       error_found = 1;
11950     }
11951
11952   /* Inline read access to java.lang.PRIMTYPE.TYPE */
11953   if (new_rhs)
11954     new_rhs = maybe_build_primttype_type_ref (new_rhs, wfl_op2);
11955
11956   if (error_found)
11957     return error_mark_node;
11958
11959   /* 10.10: Array Store Exception runtime check */
11960   if (!flag_emit_class_files
11961       && !flag_emit_xref
11962       && lvalue_from_array 
11963       && JREFERENCE_TYPE_P (TYPE_ARRAY_ELEMENT (lhs_type)))
11964     {
11965       tree check;
11966       tree base = lvalue;
11967
11968       /* We need to retrieve the right argument for _Jv_CheckArrayStore */
11969       if (TREE_CODE (lvalue) == COMPOUND_EXPR)
11970         base = TREE_OPERAND (lvalue, 0);
11971       else
11972         {
11973           if (flag_bounds_check)
11974             base = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (base, 0), 1), 0);
11975           else
11976             base = TREE_OPERAND (TREE_OPERAND (base, 0), 0);
11977         }
11978
11979       /* Build the invocation of _Jv_CheckArrayStore */
11980       new_rhs = save_expr (new_rhs);
11981       check = build (CALL_EXPR, void_type_node,
11982                      build_address_of (soft_checkarraystore_node),
11983                      tree_cons (NULL_TREE, base,
11984                                 build_tree_list (NULL_TREE, new_rhs)),
11985                      NULL_TREE);
11986       TREE_SIDE_EFFECTS (check) = 1;
11987
11988       /* We have to decide on an insertion point */
11989       if (TREE_CODE (lvalue) == COMPOUND_EXPR)
11990         {
11991           tree t;
11992           if (flag_bounds_check)
11993             {
11994               t = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (lvalue, 1), 0), 0);
11995               TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (lvalue, 1), 0), 0) =
11996                 build (COMPOUND_EXPR, void_type_node, t, check);
11997             }
11998           else
11999             TREE_OPERAND (lvalue, 1) = build (COMPOUND_EXPR, lhs_type,
12000                                               check, TREE_OPERAND (lvalue, 1));
12001         }
12002       else 
12003         {
12004           /* Make sure the bound check will happen before the store check */
12005           if (flag_bounds_check)
12006             TREE_OPERAND (TREE_OPERAND (lvalue, 0), 0) =
12007               build (COMPOUND_EXPR, void_type_node,
12008                      TREE_OPERAND (TREE_OPERAND (lvalue, 0), 0), check);
12009           else
12010             lvalue = build (COMPOUND_EXPR, lhs_type, check, lvalue);
12011         }
12012     }
12013
12014   TREE_OPERAND (node, 0) = lvalue;
12015   TREE_OPERAND (node, 1) = new_rhs;
12016   TREE_TYPE (node) = lhs_type;
12017   return node;
12018 }
12019
12020 /* Check that type SOURCE can be cast into type DEST. If the cast
12021    can't occur at all, return 0 otherwise 1. This function is used to
12022    produce accurate error messages on the reasons why an assignment
12023    failed. */
12024
12025 static tree
12026 try_reference_assignconv (lhs_type, rhs)
12027      tree lhs_type, rhs;
12028 {
12029   tree new_rhs = NULL_TREE;
12030   tree rhs_type = TREE_TYPE (rhs);
12031
12032   if (!JPRIMITIVE_TYPE_P (rhs_type) && JREFERENCE_TYPE_P (lhs_type))
12033     {
12034       /* `null' may be assigned to any reference type */
12035       if (rhs == null_pointer_node)
12036         new_rhs = null_pointer_node;
12037       /* Try the reference assignment conversion */
12038       else if (valid_ref_assignconv_cast_p (rhs_type, lhs_type, 0))
12039         new_rhs = rhs;
12040       /* This is a magic assignment that we process differently */
12041       else if (rhs == soft_exceptioninfo_call_node)
12042         new_rhs = rhs;
12043     }
12044   return new_rhs;
12045 }
12046
12047 /* Check that RHS can be converted into LHS_TYPE by the assignment
12048    conversion (5.2), for the cases of RHS being a builtin type. Return
12049    NULL_TREE if the conversion fails or if because RHS isn't of a
12050    builtin type. Return a converted RHS if the conversion is possible.  */
12051
12052 static tree
12053 try_builtin_assignconv (wfl_op1, lhs_type, rhs)
12054      tree wfl_op1, lhs_type, rhs;
12055 {
12056   tree new_rhs = NULL_TREE;
12057   tree rhs_type = TREE_TYPE (rhs);
12058
12059   /* Zero accepted everywhere */
12060   if (TREE_CODE (rhs) == INTEGER_CST 
12061       && TREE_INT_CST_HIGH (rhs) == 0 && TREE_INT_CST_LOW (rhs) == 0
12062       && JPRIMITIVE_TYPE_P (rhs_type))
12063     new_rhs = convert (lhs_type, rhs);
12064
12065   /* 5.1.1 Try Identity Conversion,
12066      5.1.2 Try Widening Primitive Conversion */
12067   else if (valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type))
12068     new_rhs = convert (lhs_type, rhs);
12069
12070   /* Try a narrowing primitive conversion (5.1.3): 
12071        - expression is a constant expression of type int AND
12072        - variable is byte, short or char AND
12073        - The value of the expression is representable in the type of the 
12074          variable */
12075   else if (rhs_type == int_type_node && TREE_CONSTANT (rhs)
12076            && (lhs_type == byte_type_node || lhs_type == char_type_node
12077                || lhs_type == short_type_node))
12078     {
12079       if (int_fits_type_p (rhs, lhs_type))
12080         new_rhs = convert (lhs_type, rhs);
12081       else if (wfl_op1)         /* Might be called with a NULL */
12082         parse_warning_context 
12083           (wfl_op1, "Constant expression `%s' to wide for narrowing primitive conversion to `%s'", 
12084            print_int_node (rhs), lang_printable_name (lhs_type, 0));
12085       /* Reported a warning that will turn into an error further
12086          down, so we don't return */
12087     }
12088
12089   return new_rhs;
12090 }
12091
12092 /* Return 1 if RHS_TYPE can be converted to LHS_TYPE by identity
12093    conversion (5.1.1) or widening primitve conversion (5.1.2).  Return
12094    0 is the conversion test fails.  This implements parts the method
12095    invocation convertion (5.3).  */
12096
12097 static int
12098 valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type)
12099      tree lhs_type, rhs_type;
12100 {
12101   /* 5.1.1: This is the identity conversion part. */
12102   if (lhs_type == rhs_type)
12103     return 1;
12104
12105   /* Reject non primitive types */
12106   if (!JPRIMITIVE_TYPE_P (lhs_type) || !JPRIMITIVE_TYPE_P (rhs_type))
12107     return 0;
12108
12109   /* 5.1.2: widening primitive conversion. byte, even if it's smaller
12110      than a char can't be converted into a char. Short can't too, but
12111      the < test below takes care of that */
12112   if (lhs_type == char_type_node && rhs_type == byte_type_node)
12113     return 0;
12114
12115   /* Accept all promoted type here. Note, we can't use <= in the test
12116      below, because we still need to bounce out assignments of short
12117      to char and the likes */
12118   if (lhs_type == int_type_node
12119       && (rhs_type == promoted_byte_type_node
12120           || rhs_type == promoted_short_type_node
12121           || rhs_type == promoted_char_type_node
12122           || rhs_type == promoted_boolean_type_node))
12123     return 1;
12124
12125   /* From here, an integral is widened if its precision is smaller
12126      than the precision of the LHS or if the LHS is a floating point
12127      type, or the RHS is a float and the RHS a double. */
12128   if ((JINTEGRAL_TYPE_P (rhs_type) && JINTEGRAL_TYPE_P (lhs_type) 
12129        && (TYPE_PRECISION (rhs_type) < TYPE_PRECISION (lhs_type)))
12130       || (JINTEGRAL_TYPE_P (rhs_type) && JFLOAT_TYPE_P (lhs_type))
12131       || (rhs_type == float_type_node && lhs_type == double_type_node))
12132     return 1;
12133
12134   return 0;
12135 }
12136
12137 /* Check that something of SOURCE type can be assigned or cast to
12138    something of DEST type at runtime. Return 1 if the operation is
12139    valid, 0 otherwise. If CAST is set to 1, we're treating the case
12140    were SOURCE is cast into DEST, which borrows a lot of the
12141    assignment check. */
12142
12143 static int
12144 valid_ref_assignconv_cast_p (source, dest, cast)
12145      tree source;
12146      tree dest;
12147      int cast;
12148 {
12149   /* SOURCE or DEST might be null if not from a declared entity. */
12150   if (!source || !dest)
12151     return 0;
12152   if (JNULLP_TYPE_P (source))
12153     return 1;
12154   if (TREE_CODE (source) == POINTER_TYPE)
12155     source = TREE_TYPE (source);
12156   if (TREE_CODE (dest) == POINTER_TYPE)
12157     dest = TREE_TYPE (dest);
12158   /* Case where SOURCE is a class type */
12159   if (TYPE_CLASS_P (source))
12160     {
12161       if (TYPE_CLASS_P (dest))
12162         return  (source == dest 
12163                  || inherits_from_p (source, dest)
12164                  || (cast && inherits_from_p (dest, source)));
12165       if (TYPE_INTERFACE_P (dest))
12166         {
12167           /* If doing a cast and SOURCE is final, the operation is
12168              always correct a compile time (because even if SOURCE
12169              does not implement DEST, a subclass of SOURCE might). */
12170           if (cast && !CLASS_FINAL (TYPE_NAME (source)))
12171             return 1;
12172           /* Otherwise, SOURCE must implement DEST */
12173           return interface_of_p (dest, source);
12174         }
12175       /* DEST is an array, cast permited if SOURCE is of Object type */
12176       return (cast && source == object_type_node ? 1 : 0);
12177     }
12178   if (TYPE_INTERFACE_P (source))
12179     {
12180       if (TYPE_CLASS_P (dest))
12181         {
12182           /* If not casting, DEST must be the Object type */
12183           if (!cast)
12184             return dest == object_type_node;
12185           /* We're doing a cast. The cast is always valid is class
12186              DEST is not final, otherwise, DEST must implement SOURCE */
12187           else if (!CLASS_FINAL (TYPE_NAME (dest)))
12188             return 1;
12189           else
12190             return interface_of_p (source, dest);
12191         }
12192       if (TYPE_INTERFACE_P (dest))
12193         {
12194           /* If doing a cast, then if SOURCE and DEST contain method
12195              with the same signature but different return type, then
12196              this is a (compile time) error */
12197           if (cast)
12198             {
12199               tree method_source, method_dest;
12200               tree source_type;
12201               tree source_sig;
12202               tree source_name;
12203               for (method_source = TYPE_METHODS (source); method_source; 
12204                    method_source = TREE_CHAIN (method_source))
12205                 {
12206                   source_sig = 
12207                     build_java_argument_signature (TREE_TYPE (method_source));
12208                   source_type = TREE_TYPE (TREE_TYPE (method_source));
12209                   source_name = DECL_NAME (method_source);
12210                   for (method_dest = TYPE_METHODS (dest);
12211                        method_dest; method_dest = TREE_CHAIN (method_dest))
12212                     if (source_sig == 
12213                         build_java_argument_signature (TREE_TYPE (method_dest))
12214                         && source_name == DECL_NAME (method_dest)
12215                         && source_type != TREE_TYPE (TREE_TYPE (method_dest)))
12216                       return 0;
12217                 }
12218               return 1;
12219             }
12220           else
12221             return source == dest || interface_of_p (dest, source);
12222         }
12223       else                      /* Array */
12224         return (cast ? 
12225                 (DECL_NAME (TYPE_NAME (source)) == java_lang_cloneable) : 0);
12226     }
12227   if (TYPE_ARRAY_P (source))
12228     {
12229       if (TYPE_CLASS_P (dest))
12230         return dest == object_type_node;
12231       /* Can't cast an array to an interface unless the interface is
12232          java.lang.Cloneable */
12233       if (TYPE_INTERFACE_P (dest))
12234         return (DECL_NAME (TYPE_NAME (dest)) == java_lang_cloneable ? 1 : 0);
12235       else                      /* Arrays */
12236         {
12237           tree source_element_type = TYPE_ARRAY_ELEMENT (source);
12238           tree dest_element_type = TYPE_ARRAY_ELEMENT (dest);
12239           
12240           /* In case of severe errors, they turn out null */
12241           if (!dest_element_type || !source_element_type)
12242             return 0;
12243           if (source_element_type == dest_element_type)
12244             return 1;
12245           return valid_ref_assignconv_cast_p (source_element_type,
12246                                               dest_element_type, cast);
12247         }
12248       return 0;
12249     }
12250   return 0;
12251 }
12252
12253 static int
12254 valid_cast_to_p (source, dest)
12255      tree source;
12256      tree dest;
12257 {
12258   if (TREE_CODE (source) == POINTER_TYPE)
12259     source = TREE_TYPE (source);
12260   if (TREE_CODE (dest) == POINTER_TYPE)
12261     dest = TREE_TYPE (dest);
12262
12263   if (TREE_CODE (source) == RECORD_TYPE && TREE_CODE (dest) == RECORD_TYPE)
12264     return valid_ref_assignconv_cast_p (source, dest, 1);
12265
12266   else if (JNUMERIC_TYPE_P (source) && JNUMERIC_TYPE_P (dest))
12267     return 1;
12268
12269   return 0;
12270 }
12271
12272 /* Method invocation conversion test. Return 1 if type SOURCE can be
12273    converted to type DEST through the methond invocation conversion
12274    process (5.3) */
12275
12276 static tree
12277 do_unary_numeric_promotion (arg)
12278      tree arg;
12279 {
12280   tree type = TREE_TYPE (arg);
12281   if (TREE_CODE (type) == INTEGER_TYPE ? TYPE_PRECISION (type) < 32
12282       : TREE_CODE (type) == CHAR_TYPE)
12283     arg = convert (int_type_node, arg);
12284   return arg;
12285 }
12286
12287 /* Return a non zero value if SOURCE can be converted into DEST using
12288    the method invocation conversion rule (5.3).  */
12289 static int
12290 valid_method_invocation_conversion_p (dest, source)
12291      tree dest, source;
12292 {
12293   return ((JPRIMITIVE_TYPE_P (source) && JPRIMITIVE_TYPE_P (dest)
12294            && valid_builtin_assignconv_identity_widening_p (dest, source))
12295           || ((JREFERENCE_TYPE_P (source) || JNULLP_TYPE_P (source))
12296               && (JREFERENCE_TYPE_P (dest) || JNULLP_TYPE_P (dest))
12297               && valid_ref_assignconv_cast_p (source, dest, 0)));
12298 }
12299
12300 /* Build an incomplete binop expression. */
12301
12302 static tree
12303 build_binop (op, op_location, op1, op2)
12304      enum tree_code op;
12305      int op_location;
12306      tree op1, op2;
12307 {
12308   tree binop = build (op, NULL_TREE, op1, op2);
12309   TREE_SIDE_EFFECTS (binop) = 1;
12310   /* Store the location of the operator, for better error report. The
12311      string of the operator will be rebuild based on the OP value. */
12312   EXPR_WFL_LINECOL (binop) = op_location;
12313   return binop;
12314 }
12315
12316 /* Build the string of the operator retained by NODE. If NODE is part
12317    of a compound expression, add an '=' at the end of the string. This
12318    function is called when an error needs to be reported on an
12319    operator. The string is returned as a pointer to a static character
12320    buffer. */
12321
12322 static char *
12323 operator_string (node)
12324      tree node;
12325 {
12326 #define BUILD_OPERATOR_STRING(S)                                        \
12327   {                                                                     \
12328     sprintf (buffer, "%s%s", S, (COMPOUND_ASSIGN_P (node) ? "=" : "")); \
12329     return buffer;                                                      \
12330   }
12331   
12332   static char buffer [10];
12333   switch (TREE_CODE (node))
12334     {
12335     case MULT_EXPR: BUILD_OPERATOR_STRING ("*");
12336     case RDIV_EXPR: BUILD_OPERATOR_STRING ("/");
12337     case TRUNC_MOD_EXPR: BUILD_OPERATOR_STRING ("%");
12338     case PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
12339     case MINUS_EXPR: BUILD_OPERATOR_STRING ("-");
12340     case LSHIFT_EXPR: BUILD_OPERATOR_STRING ("<<");
12341     case RSHIFT_EXPR: BUILD_OPERATOR_STRING (">>");
12342     case URSHIFT_EXPR: BUILD_OPERATOR_STRING (">>>");
12343     case BIT_AND_EXPR: BUILD_OPERATOR_STRING ("&");
12344     case BIT_XOR_EXPR: BUILD_OPERATOR_STRING ("^");
12345     case BIT_IOR_EXPR: BUILD_OPERATOR_STRING ("|");
12346     case TRUTH_ANDIF_EXPR: BUILD_OPERATOR_STRING ("&&");
12347     case TRUTH_ORIF_EXPR: BUILD_OPERATOR_STRING ("||");
12348     case EQ_EXPR: BUILD_OPERATOR_STRING ("==");
12349     case NE_EXPR: BUILD_OPERATOR_STRING ("!=");
12350     case GT_EXPR: BUILD_OPERATOR_STRING (">");
12351     case GE_EXPR: BUILD_OPERATOR_STRING (">=");
12352     case LT_EXPR: BUILD_OPERATOR_STRING ("<");
12353     case LE_EXPR: BUILD_OPERATOR_STRING ("<=");
12354     case UNARY_PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
12355     case NEGATE_EXPR: BUILD_OPERATOR_STRING ("-");
12356     case TRUTH_NOT_EXPR: BUILD_OPERATOR_STRING ("!");
12357     case BIT_NOT_EXPR: BUILD_OPERATOR_STRING ("~");
12358     case PREINCREMENT_EXPR:     /* Fall through */
12359     case POSTINCREMENT_EXPR: BUILD_OPERATOR_STRING ("++");
12360     case PREDECREMENT_EXPR:     /* Fall through */
12361     case POSTDECREMENT_EXPR: BUILD_OPERATOR_STRING ("--");
12362     default:
12363       fatal ("unregistered operator %s - operator_string",
12364              tree_code_name [TREE_CODE (node)]);
12365     }
12366   return NULL;
12367 #undef BUILD_OPERATOR_STRING
12368 }
12369
12370 /* Return 1 if VAR_ACCESS1 is equivalent to VAR_ACCESS2.  */
12371
12372 static int
12373 java_decl_equiv (var_acc1, var_acc2)
12374      tree var_acc1, var_acc2;
12375 {
12376   if (JDECL_P (var_acc1))
12377     return (var_acc1 == var_acc2);
12378   
12379   return (TREE_CODE (var_acc1) == COMPONENT_REF
12380           && TREE_CODE (var_acc2) == COMPONENT_REF
12381           && TREE_OPERAND (TREE_OPERAND (var_acc1, 0), 0)
12382              == TREE_OPERAND (TREE_OPERAND (var_acc2, 0), 0)
12383           && TREE_OPERAND (var_acc1, 1) == TREE_OPERAND (var_acc2, 1));
12384 }
12385
12386 /* Return a non zero value if CODE is one of the operators that can be
12387    used in conjunction with the `=' operator in a compound assignment.  */
12388
12389 static int
12390 binop_compound_p (code)
12391     enum tree_code code;
12392 {
12393   int i;
12394   for (i = 0; i < BINOP_COMPOUND_CANDIDATES; i++)
12395     if (binop_lookup [i] == code)
12396       break;
12397
12398   return i < BINOP_COMPOUND_CANDIDATES;
12399 }
12400
12401 /* Reorganize after a fold to get SAVE_EXPR to generate what we want.  */
12402
12403 static tree
12404 java_refold (t)
12405      tree t;
12406 {
12407   tree c, b, ns, decl;
12408
12409   if (TREE_CODE (t) != MODIFY_EXPR)
12410     return t;
12411
12412   c = TREE_OPERAND (t, 1);
12413   if (! (c && TREE_CODE (c) == COMPOUND_EXPR
12414          && TREE_CODE (TREE_OPERAND (c, 0)) == MODIFY_EXPR
12415          && binop_compound_p (TREE_CODE (TREE_OPERAND (c, 1)))))
12416     return t;
12417
12418   /* Now the left branch of the binary operator. */
12419   b = TREE_OPERAND (TREE_OPERAND (c, 1), 0);
12420   if (! (b && TREE_CODE (b) == NOP_EXPR 
12421          && TREE_CODE (TREE_OPERAND (b, 0)) == SAVE_EXPR))
12422     return t;
12423
12424   ns = TREE_OPERAND (TREE_OPERAND (b, 0), 0);
12425   if (! (ns && TREE_CODE (ns) == NOP_EXPR
12426          && TREE_CODE (TREE_OPERAND (ns, 0)) == SAVE_EXPR))
12427     return t;
12428
12429   decl = TREE_OPERAND (TREE_OPERAND (ns, 0), 0);
12430   if ((JDECL_P (decl) || TREE_CODE (decl) == COMPONENT_REF)
12431       /* It's got to be the an equivalent decl */
12432       && java_decl_equiv (decl, TREE_OPERAND (TREE_OPERAND (c, 0), 0)))
12433     {
12434       /* Shorten the NOP_EXPR/SAVE_EXPR path. */
12435       TREE_OPERAND (TREE_OPERAND (c, 1), 0) = TREE_OPERAND (ns, 0);
12436       /* Substitute the COMPOUND_EXPR by the BINOP_EXPR */
12437       TREE_OPERAND (t, 1) = TREE_OPERAND (c, 1);
12438       /* Change the right part of the BINOP_EXPR */
12439       TREE_OPERAND (TREE_OPERAND (t, 1), 1) = TREE_OPERAND (c, 0);
12440     }
12441
12442   return t;
12443 }
12444
12445 /* Binary operators (15.16 up to 15.18). We return error_mark_node on
12446    errors but we modify NODE so that it contains the type computed
12447    according to the expression, when it's fixed. Otherwise, we write
12448    error_mark_node as the type. It allows us to further the analysis
12449    of remaining nodes and detects more errors in certain cases.  */
12450
12451 static tree
12452 patch_binop (node, wfl_op1, wfl_op2)
12453      tree node;
12454      tree wfl_op1;
12455      tree wfl_op2;
12456 {
12457   tree op1 = TREE_OPERAND (node, 0);
12458   tree op2 = TREE_OPERAND (node, 1);
12459   tree op1_type = TREE_TYPE (op1);
12460   tree op2_type = TREE_TYPE (op2);
12461   tree prom_type = NULL_TREE, cn;
12462   int code = TREE_CODE (node);
12463
12464   /* If 1, tell the routine that we have to return error_mark_node
12465      after checking for the initialization of the RHS */
12466   int error_found = 0;
12467
12468   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
12469
12470   switch (code)
12471     {
12472     /* 15.16 Multiplicative operators */
12473     case MULT_EXPR:             /* 15.16.1 Multiplication Operator * */
12474     case RDIV_EXPR:             /* 15.16.2 Division Operator / */
12475     case TRUNC_DIV_EXPR:        /* 15.16.2 Integral type Division Operator / */
12476     case TRUNC_MOD_EXPR:        /* 15.16.3 Remainder operator % */
12477       if (!JPRIMITIVE_TYPE_P (op1_type) || !JPRIMITIVE_TYPE_P (op2_type))
12478         {
12479           if (!JPRIMITIVE_TYPE_P (op1_type))
12480             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
12481           if (!JPRIMITIVE_TYPE_P (op2_type) && (op1_type != op2_type))
12482             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
12483           TREE_TYPE (node) = error_mark_node;
12484           error_found = 1;
12485           break;
12486         }
12487       prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12488       /* Change the division operator if necessary */
12489       if (code == RDIV_EXPR && TREE_CODE (prom_type) == INTEGER_TYPE)
12490         TREE_SET_CODE (node, TRUNC_DIV_EXPR);
12491
12492       if (TREE_CODE (prom_type) == INTEGER_TYPE
12493           && flag_use_divide_subroutine
12494           && ! flag_emit_class_files
12495           && (code == RDIV_EXPR || code == TRUNC_MOD_EXPR))
12496         return build_java_soft_divmod (TREE_CODE (node), prom_type, op1, op2);
12497  
12498       /* This one is more complicated. FLOATs are processed by a
12499          function call to soft_fmod. Duplicate the value of the
12500          COMPOUND_ASSIGN_P flag. */
12501       if (code == TRUNC_MOD_EXPR)
12502         {
12503           tree mod = build_java_binop (TRUNC_MOD_EXPR, prom_type, op1, op2);
12504           COMPOUND_ASSIGN_P (mod) = COMPOUND_ASSIGN_P (node);
12505           TREE_SIDE_EFFECTS (mod)
12506             = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
12507           return mod;
12508         }
12509       break;
12510
12511     /* 15.17 Additive Operators */
12512     case PLUS_EXPR:             /* 15.17.1 String Concatenation Operator + */
12513
12514       /* Operation is valid if either one argument is a string
12515          constant, a String object or a StringBuffer crafted for the
12516          purpose of the a previous usage of the String concatenation
12517          operator */
12518
12519       if (TREE_CODE (op1) == STRING_CST 
12520           || TREE_CODE (op2) == STRING_CST
12521           || JSTRING_TYPE_P (op1_type)
12522           || JSTRING_TYPE_P (op2_type)
12523           || IS_CRAFTED_STRING_BUFFER_P (op1)
12524           || IS_CRAFTED_STRING_BUFFER_P (op2))
12525         return build_string_concatenation (op1, op2);
12526
12527     case MINUS_EXPR:            /* 15.17.2 Additive Operators (+ and -) for
12528                                    Numeric Types */
12529       if (!JPRIMITIVE_TYPE_P (op1_type) || !JPRIMITIVE_TYPE_P (op2_type))
12530         {
12531           if (!JPRIMITIVE_TYPE_P (op1_type))
12532             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
12533           if (!JPRIMITIVE_TYPE_P (op2_type) && (op1_type != op2_type))
12534             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
12535           TREE_TYPE (node) = error_mark_node;
12536           error_found = 1;
12537           break;
12538         }
12539       prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12540       break;
12541
12542     /* 15.18 Shift Operators */
12543     case LSHIFT_EXPR:
12544     case RSHIFT_EXPR:
12545     case URSHIFT_EXPR:
12546       if (!JINTEGRAL_TYPE_P (op1_type) || !JINTEGRAL_TYPE_P (op2_type))
12547         {
12548           if (!JINTEGRAL_TYPE_P (op1_type))
12549             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
12550           else
12551             {
12552               if (JPRIMITIVE_TYPE_P (op2_type))
12553                 parse_error_context (wfl_operator,
12554                                      "Incompatible type for `%s'. Explicit cast needed to convert shift distance from `%s' to integral",
12555                                      operator_string (node),
12556                                      lang_printable_name (op2_type, 0));
12557               else
12558                 parse_error_context (wfl_operator,
12559                                      "Incompatible type for `%s'. Can't convert shift distance from `%s' to integral", 
12560                                      operator_string (node),
12561                                      lang_printable_name (op2_type, 0));
12562             }
12563           TREE_TYPE (node) = error_mark_node;
12564           error_found = 1;
12565           break;
12566         }
12567
12568       /* Unary numeric promotion (5.6.1) is performed on each operand
12569          separatly */
12570       op1 = do_unary_numeric_promotion (op1);
12571       op2 = do_unary_numeric_promotion (op2);
12572
12573       /* The type of the shift expression is the type of the promoted
12574          type of the left-hand operand */
12575       prom_type = TREE_TYPE (op1);
12576
12577       /* Shift int only up to 0x1f and long up to 0x3f */
12578       if (prom_type == int_type_node)
12579         op2 = fold (build (BIT_AND_EXPR, int_type_node, op2, 
12580                            build_int_2 (0x1f, 0)));
12581       else
12582         op2 = fold (build (BIT_AND_EXPR, int_type_node, op2, 
12583                            build_int_2 (0x3f, 0)));
12584
12585       /* The >>> operator is a >> operating on unsigned quantities */
12586       if (code == URSHIFT_EXPR && ! flag_emit_class_files)
12587         {
12588           tree to_return;
12589           tree utype = unsigned_type (prom_type);
12590           op1 = convert (utype, op1);
12591           TREE_SET_CODE (node, RSHIFT_EXPR);
12592           TREE_OPERAND (node, 0) = op1;
12593           TREE_OPERAND (node, 1) = op2;
12594           TREE_TYPE (node) = utype;
12595           to_return = convert (prom_type, node);
12596           /* Copy the original value of the COMPOUND_ASSIGN_P flag */
12597           COMPOUND_ASSIGN_P (to_return) = COMPOUND_ASSIGN_P (node);
12598           TREE_SIDE_EFFECTS (to_return)
12599             = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
12600           return to_return;
12601         }
12602       break;
12603
12604       /* 15.19.1 Type Comparison Operator instaceof */
12605     case INSTANCEOF_EXPR:
12606
12607       TREE_TYPE (node) = boolean_type_node;
12608
12609       if (!(op2_type = resolve_type_during_patch (op2)))
12610         return error_mark_node;
12611
12612       /* The first operand must be a reference type or the null type */
12613       if (!JREFERENCE_TYPE_P (op1_type) && op1 != null_pointer_node)
12614         error_found = 1;        /* Error reported further below */
12615
12616       /* The second operand must be a reference type */
12617       if (!JREFERENCE_TYPE_P (op2_type))
12618         {
12619           SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
12620           parse_error_context
12621             (wfl_operator, "Invalid argument `%s' for `instanceof'",
12622              lang_printable_name (op2_type, 0));
12623           error_found = 1;
12624         }
12625
12626       if (!error_found && valid_ref_assignconv_cast_p (op1_type, op2_type, 1))
12627         {
12628           /* If the first operand is null, the result is always false */
12629           if (op1 == null_pointer_node)
12630             return boolean_false_node;
12631           else if (flag_emit_class_files)
12632             {
12633               TREE_OPERAND (node, 1) = op2_type;
12634               TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1);
12635               return node;
12636             }
12637           /* Otherwise we have to invoke instance of to figure it out */
12638           else
12639             return build_instanceof (op1, op2_type);
12640         }
12641       /* There is no way the expression operand can be an instance of
12642          the type operand. This is a compile time error. */
12643       else
12644         {
12645           char *t1 = xstrdup (lang_printable_name (op1_type, 0));
12646           SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
12647           parse_error_context 
12648             (wfl_operator, "Impossible for `%s' to be instance of `%s'",
12649              t1, lang_printable_name (op2_type, 0));
12650           free (t1);
12651           error_found = 1;
12652         }
12653       
12654       break;
12655
12656       /* 15.21 Bitwise and Logical Operators */
12657     case BIT_AND_EXPR:
12658     case BIT_XOR_EXPR:
12659     case BIT_IOR_EXPR:
12660       if (JINTEGRAL_TYPE_P (op1_type) && JINTEGRAL_TYPE_P (op2_type))
12661         /* Binary numeric promotion is performed on both operand and the
12662            expression retain that type */
12663         prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12664
12665       else if (TREE_CODE (op1_type) == BOOLEAN_TYPE 
12666                && TREE_CODE (op1_type) == BOOLEAN_TYPE)
12667         /* The type of the bitwise operator expression is BOOLEAN */
12668         prom_type = boolean_type_node;
12669       else
12670         {
12671           if (!JINTEGRAL_TYPE_P (op1_type))
12672             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
12673           if (!JINTEGRAL_TYPE_P (op2_type) && (op1_type != op2_type))
12674             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op2_type);
12675           TREE_TYPE (node) = error_mark_node;
12676           error_found = 1;
12677           /* Insert a break here if adding thing before the switch's
12678              break for this case */
12679         }
12680       break;
12681
12682       /* 15.22 Conditional-And Operator */
12683     case TRUTH_ANDIF_EXPR:
12684       /* 15.23 Conditional-Or Operator */
12685     case TRUTH_ORIF_EXPR:
12686       /* Operands must be of BOOLEAN type */
12687       if (TREE_CODE (op1_type) != BOOLEAN_TYPE || 
12688           TREE_CODE (op2_type) != BOOLEAN_TYPE)
12689         {
12690           if (TREE_CODE (op1_type) != BOOLEAN_TYPE)
12691             ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op1_type);
12692           if (TREE_CODE (op2_type) != BOOLEAN_TYPE && (op1_type != op2_type))
12693             ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op2_type);
12694           TREE_TYPE (node) = boolean_type_node;
12695           error_found = 1;
12696           break;
12697         }
12698       /* The type of the conditional operators is BOOLEAN */
12699       prom_type = boolean_type_node;
12700       break;
12701
12702       /* 15.19.1 Numerical Comparison Operators <, <=, >, >= */
12703     case LT_EXPR:
12704     case GT_EXPR:
12705     case LE_EXPR:
12706     case GE_EXPR:
12707       /* The type of each of the operands must be a primitive numeric
12708          type */
12709       if (!JNUMERIC_TYPE_P (op1_type) || ! JNUMERIC_TYPE_P (op2_type))
12710         {
12711           if (!JNUMERIC_TYPE_P (op1_type))
12712             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
12713           if (!JNUMERIC_TYPE_P (op2_type) && (op1_type != op2_type))
12714             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
12715           TREE_TYPE (node) = boolean_type_node;
12716           error_found = 1;
12717           break;
12718         }
12719       /* Binary numeric promotion is performed on the operands */
12720       binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12721       /* The type of the relation expression is always BOOLEAN */
12722       prom_type = boolean_type_node;
12723       break;
12724
12725       /* 15.20 Equality Operator */
12726     case EQ_EXPR:
12727     case NE_EXPR:
12728       /* It's time for us to patch the strings. */
12729       if ((cn = patch_string (op1))) 
12730        {
12731          op1 = cn;
12732          op1_type = TREE_TYPE (op1);
12733        }
12734       if ((cn = patch_string (op2))) 
12735        {
12736          op2 = cn;
12737          op2_type = TREE_TYPE (op2);
12738        }
12739       
12740       /* 15.20.1 Numerical Equality Operators == and != */
12741       /* Binary numeric promotion is performed on the operands */
12742       if (JNUMERIC_TYPE_P (op1_type) && JNUMERIC_TYPE_P (op2_type))
12743         binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
12744       
12745       /* 15.20.2 Boolean Equality Operators == and != */
12746       else if (TREE_CODE (op1_type) == BOOLEAN_TYPE &&
12747           TREE_CODE (op2_type) == BOOLEAN_TYPE)
12748         ;                       /* Nothing to do here */
12749       
12750       /* 15.20.3 Reference Equality Operators == and != */
12751       /* Types have to be either references or the null type. If
12752          they're references, it must be possible to convert either
12753          type to the other by casting conversion. */
12754       else if (op1 == null_pointer_node || op2 == null_pointer_node 
12755                || (JREFERENCE_TYPE_P (op1_type) && JREFERENCE_TYPE_P (op2_type)
12756                    && (valid_ref_assignconv_cast_p (op1_type, op2_type, 1)
12757                        || valid_ref_assignconv_cast_p (op2_type, 
12758                                                        op1_type, 1))))
12759         ;                       /* Nothing to do here */
12760           
12761       /* Else we have an error figure what can't be converted into
12762          what and report the error */
12763       else
12764         {
12765           char *t1;
12766           t1 = xstrdup (lang_printable_name (op1_type, 0));
12767           parse_error_context 
12768             (wfl_operator,
12769              "Incompatible type for `%s'. Can't convert `%s' to `%s'",
12770              operator_string (node), t1, 
12771              lang_printable_name (op2_type, 0));
12772           free (t1);
12773           TREE_TYPE (node) = boolean_type_node;
12774           error_found = 1;
12775           break;
12776         }
12777       prom_type = boolean_type_node;
12778       break;
12779     }
12780
12781   if (error_found)
12782     return error_mark_node;
12783
12784   TREE_OPERAND (node, 0) = op1;
12785   TREE_OPERAND (node, 1) = op2;
12786   TREE_TYPE (node) = prom_type;
12787   TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
12788   
12789   if (flag_emit_xref)
12790     return node;
12791
12792   /* fold does not respect side-effect order as required for Java but not C.
12793    * Also, it sometimes create SAVE_EXPRs which are bad when emitting
12794    * bytecode.
12795    */
12796   if (flag_emit_class_files ? (TREE_CONSTANT (op1) && TREE_CONSTANT (op2))
12797       : ! TREE_SIDE_EFFECTS (node))
12798     node = fold (node);
12799   return node;
12800 }
12801
12802 /* Concatenate the STRING_CST CSTE and STRING. When AFTER is a non
12803    zero value, the value of CSTE comes after the valude of STRING */
12804
12805 static tree
12806 do_merge_string_cste (cste, string, string_len, after)
12807      tree cste;
12808      const char *string;
12809      int string_len, after;
12810 {
12811   int len = TREE_STRING_LENGTH (cste) + string_len;
12812   const char *old = TREE_STRING_POINTER (cste);
12813   TREE_STRING_LENGTH (cste) = len;
12814   TREE_STRING_POINTER (cste) = obstack_alloc (expression_obstack, len+1);
12815   if (after)
12816     {
12817       strcpy (TREE_STRING_POINTER (cste), string);
12818       strcat (TREE_STRING_POINTER (cste), old);
12819     }
12820   else
12821     {
12822       strcpy (TREE_STRING_POINTER (cste), old);
12823       strcat (TREE_STRING_POINTER (cste), string);
12824     }
12825   return cste;
12826 }
12827
12828 /* Tries to merge OP1 (a STRING_CST) and OP2 (if suitable). Return a
12829    new STRING_CST on success, NULL_TREE on failure */
12830
12831 static tree
12832 merge_string_cste (op1, op2, after)
12833      tree op1, op2;
12834      int after;
12835 {
12836   /* Handle two string constants right away */
12837   if (TREE_CODE (op2) == STRING_CST)
12838     return do_merge_string_cste (op1, TREE_STRING_POINTER (op2), 
12839                                  TREE_STRING_LENGTH (op2), after);
12840   
12841   /* Reasonable integer constant can be treated right away */
12842   if (TREE_CODE (op2) == INTEGER_CST && !TREE_CONSTANT_OVERFLOW (op2))
12843     {
12844       static const char *boolean_true = "true";
12845       static const char *boolean_false = "false";
12846       static const char *null_pointer = "null";
12847       char ch[3];
12848       const char *string;
12849       
12850       if (op2 == boolean_true_node)
12851         string = boolean_true;
12852       else if (op2 == boolean_false_node)
12853         string = boolean_false;
12854       else if (op2 == null_pointer_node)
12855         string = null_pointer;
12856       else if (TREE_TYPE (op2) == char_type_node)
12857         {
12858           ch[0] = (char )TREE_INT_CST_LOW (op2);
12859           ch[1] = '\0';
12860           string = ch;
12861         }
12862       else
12863           string = print_int_node (op2);
12864       
12865       return do_merge_string_cste (op1, string, strlen (string), after);
12866     }
12867   return NULL_TREE;
12868 }
12869
12870 /* Tries to statically concatenate OP1 and OP2 if possible. Either one
12871    has to be a STRING_CST and the other part must be a STRING_CST or a
12872    INTEGRAL constant. Return a new STRING_CST if the operation
12873    succeed, NULL_TREE otherwise.
12874
12875    If the case we want to optimize for space, we might want to return
12876    NULL_TREE for each invocation of this routine. FIXME */
12877
12878 static tree
12879 string_constant_concatenation (op1, op2)
12880      tree op1, op2;
12881 {
12882   if (TREE_CODE (op1) == STRING_CST || (TREE_CODE (op2) == STRING_CST))
12883     {
12884       tree string, rest;
12885       int invert;
12886       
12887       string = (TREE_CODE (op1) == STRING_CST ? op1 : op2);
12888       rest   = (string == op1 ? op2 : op1);
12889       invert = (string == op1 ? 0 : 1 );
12890       
12891       /* Walk REST, only if it looks reasonable */
12892       if (TREE_CODE (rest) != STRING_CST
12893           && !IS_CRAFTED_STRING_BUFFER_P (rest)
12894           && !JSTRING_TYPE_P (TREE_TYPE (rest))
12895           && TREE_CODE (rest) == EXPR_WITH_FILE_LOCATION)
12896         {
12897           rest = java_complete_tree (rest);
12898           if (rest == error_mark_node)
12899             return error_mark_node;
12900           rest = fold (rest);
12901         }
12902       return merge_string_cste (string, rest, invert);
12903     }
12904   return NULL_TREE;
12905 }
12906
12907 /* Implement the `+' operator. Does static optimization if possible,
12908    otherwise create (if necessary) and append elements to a
12909    StringBuffer. The StringBuffer will be carried around until it is
12910    used for a function call or an assignment. Then toString() will be
12911    called on it to turn it into a String object. */
12912
12913 static tree
12914 build_string_concatenation (op1, op2)
12915      tree op1, op2;
12916 {
12917   tree result;
12918   int side_effects = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
12919
12920   if (flag_emit_xref)
12921     return build (PLUS_EXPR, string_type_node, op1, op2);
12922   
12923   /* Try to do some static optimization */
12924   if ((result = string_constant_concatenation (op1, op2)))
12925     return result;
12926
12927   /* Discard empty strings on either side of the expression */
12928   if (TREE_CODE (op1) == STRING_CST && TREE_STRING_LENGTH (op1) == 0)
12929     {
12930       op1 = op2;
12931       op2 = NULL_TREE;
12932     }
12933   else if (TREE_CODE (op2) == STRING_CST && TREE_STRING_LENGTH (op2) == 0)
12934     op2 = NULL_TREE;
12935
12936   /* If operands are string constant, turn then into object references */
12937   if (TREE_CODE (op1) == STRING_CST)
12938     op1 = patch_string_cst (op1);
12939   if (op2 && TREE_CODE (op2) == STRING_CST)
12940     op2 = patch_string_cst (op2);
12941
12942   /* If either one of the constant is null and the other non null
12943      operand is a String object, return it. */
12944   if (JSTRING_TYPE_P (TREE_TYPE (op1)) && !op2)
12945     return op1;
12946
12947   /* If OP1 isn't already a StringBuffer, create and
12948      initialize a new one */
12949   if (!IS_CRAFTED_STRING_BUFFER_P (op1))
12950     {
12951       /* Two solutions here: 
12952          1) OP1 is a constant string reference, we call new StringBuffer(OP1)
12953          2) OP1 is something else, we call new StringBuffer().append(OP1).  */
12954       if (TREE_CONSTANT (op1) && JSTRING_TYPE_P (TREE_TYPE (op1)))
12955         op1 = BUILD_STRING_BUFFER (op1);
12956       else
12957         {
12958           tree aNew = BUILD_STRING_BUFFER (NULL_TREE);
12959           op1 = make_qualified_primary (aNew, BUILD_APPEND (op1), 0);
12960         }
12961     }
12962
12963   if (op2)
12964     {
12965       /* OP1 is no longer the last node holding a crafted StringBuffer */
12966       IS_CRAFTED_STRING_BUFFER_P (op1) = 0;
12967       /* Create a node for `{new...,xxx}.append (op2)' */
12968       if (op2)
12969         op1 = make_qualified_primary (op1, BUILD_APPEND (op2), 0);
12970     }
12971
12972   /* Mark the last node holding a crafted StringBuffer */
12973   IS_CRAFTED_STRING_BUFFER_P (op1) = 1;
12974
12975   TREE_SIDE_EFFECTS (op1) = side_effects;
12976   return op1;
12977 }
12978
12979 /* Patch the string node NODE. NODE can be a STRING_CST of a crafted
12980    StringBuffer. If no string were found to be patched, return
12981    NULL. */
12982
12983 static tree
12984 patch_string (node)
12985     tree node;
12986 {
12987   if (node == error_mark_node)
12988     return error_mark_node;
12989   if (TREE_CODE (node) == STRING_CST)
12990     return patch_string_cst (node);
12991   else if (IS_CRAFTED_STRING_BUFFER_P (node))
12992     {
12993       int saved = ctxp->explicit_constructor_p;
12994       tree invoke = build_method_invocation (wfl_to_string, NULL_TREE);
12995       tree ret;
12996       /* Temporary disable forbid the use of `this'. */
12997       ctxp->explicit_constructor_p = 0;
12998       ret = java_complete_tree (make_qualified_primary (node, invoke, 0));
12999       /* String concatenation arguments must be evaluated in order too. */
13000       ret = force_evaluation_order (ret);
13001       /* Restore it at its previous value */
13002       ctxp->explicit_constructor_p = saved;
13003       return ret;
13004     }
13005   return NULL_TREE;
13006 }
13007
13008 /* Build the internal representation of a string constant.  */
13009
13010 static tree
13011 patch_string_cst (node)
13012      tree node;
13013 {
13014   int location;
13015   if (! flag_emit_class_files)
13016     {
13017       push_obstacks (&permanent_obstack, &permanent_obstack);
13018       node = get_identifier (TREE_STRING_POINTER (node));
13019       location = alloc_name_constant (CONSTANT_String, node);
13020       node = build_ref_from_constant_pool (location);
13021       pop_obstacks ();
13022     }
13023   TREE_TYPE (node) = string_ptr_type_node;
13024   TREE_CONSTANT (node) = 1;
13025   return node;
13026 }
13027
13028 /* Build an incomplete unary operator expression. */
13029
13030 static tree
13031 build_unaryop (op_token, op_location, op1)
13032      int op_token, op_location;
13033      tree op1;
13034 {
13035   enum tree_code op;
13036   tree unaryop;
13037   switch (op_token)
13038     {
13039     case PLUS_TK: op = UNARY_PLUS_EXPR; break;
13040     case MINUS_TK: op = NEGATE_EXPR; break;
13041     case NEG_TK: op = TRUTH_NOT_EXPR; break;
13042     case NOT_TK: op = BIT_NOT_EXPR; break;
13043     default: fatal ("Unknown token `%d' for unary operator - build_unaryop",
13044                     op_token);
13045     }
13046
13047   unaryop = build1 (op, NULL_TREE, op1);
13048   TREE_SIDE_EFFECTS (unaryop) = 1;
13049   /* Store the location of the operator, for better error report. The
13050      string of the operator will be rebuild based on the OP value. */
13051   EXPR_WFL_LINECOL (unaryop) = op_location;
13052   return unaryop;
13053 }
13054
13055 /* Special case for the ++/-- operators, since they require an extra
13056    argument to build, which is set to NULL and patched
13057    later. IS_POST_P is 1 if the operator, 0 otherwise.  */
13058
13059 static tree
13060 build_incdec (op_token, op_location, op1, is_post_p)
13061      int op_token, op_location;
13062      tree op1;
13063      int is_post_p;
13064 {
13065   static enum tree_code lookup [2][2] = 
13066     {
13067       { PREDECREMENT_EXPR, PREINCREMENT_EXPR, },
13068       { POSTDECREMENT_EXPR, POSTINCREMENT_EXPR, },
13069     };
13070   tree node = build (lookup [is_post_p][(op_token - DECR_TK)], 
13071                      NULL_TREE, op1, NULL_TREE);
13072   TREE_SIDE_EFFECTS (node) = 1;
13073   /* Store the location of the operator, for better error report. The
13074      string of the operator will be rebuild based on the OP value. */
13075   EXPR_WFL_LINECOL (node) = op_location;
13076   return node;
13077 }     
13078
13079 /* Build an incomplete cast operator, based on the use of the
13080    CONVERT_EXPR. Note that TREE_TYPE of the constructed node is
13081    set. java_complete_tree is trained to walk a CONVERT_EXPR even
13082    though its type is already set.  */
13083
13084 static tree
13085 build_cast (location, type, exp)
13086      int location;
13087      tree type, exp;
13088 {
13089   tree node = build1 (CONVERT_EXPR, type, exp);
13090   EXPR_WFL_LINECOL (node) = location;
13091   return node;
13092 }
13093
13094 /* Build an incomplete class reference operator.  */
13095 static tree
13096 build_incomplete_class_ref (location, class_name)
13097     int location;
13098     tree class_name;
13099 {
13100   tree node = build1 (CLASS_LITERAL, NULL_TREE, class_name);
13101   EXPR_WFL_LINECOL (node) = location;
13102   return node;
13103 }
13104
13105 /* Complete an incomplete class reference operator.  */
13106 static tree
13107 patch_incomplete_class_ref (node)
13108     tree node;
13109 {
13110   tree type = TREE_OPERAND (node, 0);
13111   tree ref_type;
13112
13113   if (!(ref_type = resolve_type_during_patch (type)))
13114     return error_mark_node;
13115
13116   if (!flag_emit_class_files || JPRIMITIVE_TYPE_P (ref_type))
13117     {
13118       /* A class referenced by `foo.class' is initialized.  */
13119       return build_class_init (ref_type, build_class_ref (ref_type));
13120     }
13121
13122   /* If we're emitting class files and we have to deal with non
13123      primitive types, we invoke (and consider generating) the
13124      synthetic static method `class$'. */
13125   if (!TYPE_DOT_CLASS (current_class))
13126       build_dot_class_method (current_class);
13127   ref_type = 
13128     build_dot_class_method_invocation (DECL_NAME (TYPE_NAME (ref_type)));
13129   return java_complete_tree (ref_type);
13130 }
13131
13132 /* 15.14 Unary operators. We return error_mark_node in case of error,
13133    but preserve the type of NODE if the type is fixed.  */
13134
13135 static tree
13136 patch_unaryop (node, wfl_op)
13137      tree node;
13138      tree wfl_op;
13139 {
13140   tree op = TREE_OPERAND (node, 0);
13141   tree op_type = TREE_TYPE (op);
13142   tree prom_type = NULL_TREE, value, decl;
13143   int outer_field_flag = 0;
13144   int code = TREE_CODE (node);
13145   int error_found = 0;
13146
13147   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13148
13149   switch (code)
13150     {
13151       /* 15.13.2 Postfix Increment Operator ++ */
13152     case POSTINCREMENT_EXPR:
13153       /* 15.13.3 Postfix Increment Operator -- */
13154     case POSTDECREMENT_EXPR:
13155       /* 15.14.1 Prefix Increment Operator ++ */
13156     case PREINCREMENT_EXPR:
13157       /* 15.14.2 Prefix Decrement Operator -- */
13158     case PREDECREMENT_EXPR:
13159       op = decl = strip_out_static_field_access_decl (op);
13160       outer_field_flag = outer_field_expanded_access_p (op, NULL, NULL, NULL);
13161       /* We might be trying to change an outer field accessed using
13162          access method. */
13163       if (outer_field_flag)
13164         {
13165           /* Retrieve the decl of the field we're trying to access. We
13166              do that by first retrieving the function we would call to
13167              access the field. It has been already verified that this
13168              field isn't final */
13169           if (flag_emit_class_files)
13170             decl = TREE_OPERAND (op, 0);
13171           else
13172             decl = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (op, 0), 0), 0);
13173           decl = DECL_FUNCTION_ACCESS_DECL (decl);
13174         }
13175       /* We really should have a JAVA_ARRAY_EXPR to avoid this */
13176       else if (!JDECL_P (decl) 
13177           && TREE_CODE (decl) != COMPONENT_REF
13178           && !(flag_emit_class_files && TREE_CODE (decl) == ARRAY_REF)
13179           && TREE_CODE (decl) != INDIRECT_REF
13180           && !(TREE_CODE (decl) == COMPOUND_EXPR
13181                && TREE_OPERAND (decl, 1)
13182                && (TREE_CODE (TREE_OPERAND (decl, 1)) == INDIRECT_REF)))
13183         {
13184           tree lvalue;
13185           /* Before screaming, check that we're not in fact trying to
13186              increment a optimized static final access, in which case
13187              we issue an different error message. */
13188           if (!(TREE_CODE (wfl_op) == EXPR_WITH_FILE_LOCATION
13189                 && resolve_expression_name (wfl_op, &lvalue)
13190                 && check_final_assignment (lvalue, wfl_op)))
13191             parse_error_context (wfl_operator, "Invalid argument to `%s'",
13192                                  operator_string (node));
13193           TREE_TYPE (node) = error_mark_node;
13194           error_found = 1;
13195         }
13196       
13197       if (check_final_assignment (op, wfl_op))
13198         error_found = 1;
13199
13200       /* From now on, we know that op if a variable and that it has a
13201          valid wfl. We use wfl_op to locate errors related to the
13202          ++/-- operand. */
13203       else if (!JNUMERIC_TYPE_P (op_type))
13204         {
13205           parse_error_context
13206             (wfl_op, "Invalid argument type `%s' to `%s'",
13207              lang_printable_name (op_type, 0), operator_string (node));
13208           TREE_TYPE (node) = error_mark_node;
13209           error_found = 1;
13210         }
13211       else
13212         {
13213           /* Before the addition, binary numeric promotion is performed on
13214              both operands, if really necessary */
13215           if (JINTEGRAL_TYPE_P (op_type))
13216             {
13217               value = build_int_2 (1, 0);
13218               TREE_TYPE (value) = TREE_TYPE (node) = op_type;
13219             }
13220           else
13221             {
13222               value = build_int_2 (1, 0);
13223               TREE_TYPE (node) = 
13224                 binary_numeric_promotion (op_type, 
13225                                           TREE_TYPE (value), &op, &value);
13226             }
13227
13228           /* We remember we might be accessing an outer field */
13229           if (outer_field_flag)
13230             {
13231               /* We re-generate an access to the field */
13232               value = build (PLUS_EXPR, TREE_TYPE (op), 
13233                              build_outer_field_access (wfl_op, decl), value);
13234                                                     
13235               /* And we patch the original access$() into a write 
13236                  with plus_op as a rhs */
13237               return outer_field_access_fix (node, op, value);
13238             }
13239
13240           /* And write back into the node. */
13241           TREE_OPERAND (node, 0) = op;
13242           TREE_OPERAND (node, 1) = value;
13243           /* Convert the overall back into its original type, if
13244              necessary, and return */
13245           if (JINTEGRAL_TYPE_P (op_type))
13246             return fold (node);
13247           else
13248             return fold (convert (op_type, node));
13249         }
13250       break;
13251
13252       /* 15.14.3 Unary Plus Operator + */
13253     case UNARY_PLUS_EXPR:
13254       /* 15.14.4 Unary Minus Operator - */
13255     case NEGATE_EXPR:
13256       if (!JNUMERIC_TYPE_P (op_type))
13257         {
13258           ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op_type);
13259           TREE_TYPE (node) = error_mark_node;
13260           error_found = 1;
13261         }
13262       /* Unary numeric promotion is performed on operand */
13263       else
13264         {
13265           op = do_unary_numeric_promotion (op);
13266           prom_type = TREE_TYPE (op);
13267           if (code == UNARY_PLUS_EXPR)
13268             return fold (op);
13269         }
13270       break;
13271
13272       /* 15.14.5 Bitwise Complement Operator ~ */
13273     case BIT_NOT_EXPR:
13274       if (!JINTEGRAL_TYPE_P (op_type))
13275         {
13276           ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op_type);
13277           TREE_TYPE (node) = error_mark_node;
13278           error_found = 1;
13279         }
13280       else
13281         {
13282           op = do_unary_numeric_promotion (op);
13283           prom_type = TREE_TYPE (op);
13284         }
13285       break;
13286
13287       /* 15.14.6 Logical Complement Operator ! */
13288     case TRUTH_NOT_EXPR:
13289       if (TREE_CODE (op_type) != BOOLEAN_TYPE)
13290         {
13291           ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op_type);
13292           /* But the type is known. We will report an error if further
13293              attempt of a assignment is made with this rhs */
13294           TREE_TYPE (node) = boolean_type_node;
13295           error_found = 1;
13296         }
13297       else
13298         prom_type = boolean_type_node;
13299       break;
13300
13301       /* 15.15 Cast Expression */
13302     case CONVERT_EXPR:
13303       value = patch_cast (node, wfl_operator);
13304       if (value == error_mark_node)
13305         {
13306           /* If this cast is part of an assignment, we tell the code
13307              that deals with it not to complain about a mismatch,
13308              because things have been cast, anyways */
13309           TREE_TYPE (node) = error_mark_node;
13310           error_found = 1;
13311         }
13312       else
13313         {
13314           value = fold (value);
13315           TREE_SIDE_EFFECTS (value) = TREE_SIDE_EFFECTS (op);
13316           return value;
13317         }
13318       break;
13319     }
13320   
13321   if (error_found)
13322     return error_mark_node;
13323
13324   /* There are cases where node has been replaced by something else
13325      and we don't end up returning here: UNARY_PLUS_EXPR,
13326      CONVERT_EXPR, {POST,PRE}{INCR,DECR}EMENT_EXPR. */
13327   TREE_OPERAND (node, 0) = fold (op);
13328   TREE_TYPE (node) = prom_type;
13329   TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op);
13330   return fold (node);
13331 }
13332
13333 /* Generic type resolution that sometimes takes place during node
13334    patching. Returned the resolved type or generate an error
13335    message. Return the resolved type or NULL_TREE.  */
13336
13337 static tree
13338 resolve_type_during_patch (type)
13339      tree type;
13340 {
13341   if (unresolved_type_p (type, NULL))
13342     {
13343       tree type_decl = resolve_no_layout (EXPR_WFL_NODE (type), type);
13344       if (!type_decl)
13345         {
13346           parse_error_context (type, 
13347                                "Class `%s' not found in type declaration",
13348                                IDENTIFIER_POINTER (EXPR_WFL_NODE (type)));
13349           return NULL_TREE;
13350         }
13351       else
13352         {
13353           CLASS_LOADED_P (TREE_TYPE (type_decl)) = 1;
13354           return TREE_TYPE (type_decl);
13355         }
13356     }
13357   return type;
13358 }
13359 /* 5.5 Casting Conversion. error_mark_node is returned if an error is
13360    found. Otherwise NODE or something meant to replace it is returned.  */
13361
13362 static tree
13363 patch_cast (node, wfl_operator)
13364      tree node;
13365      tree wfl_operator;
13366 {
13367   tree op = TREE_OPERAND (node, 0);
13368   tree op_type = TREE_TYPE (op);
13369   tree cast_type = TREE_TYPE (node);
13370   char *t1;
13371
13372   /* First resolve OP_TYPE if unresolved */
13373   if (!(cast_type = resolve_type_during_patch (cast_type)))
13374     return error_mark_node;
13375
13376   /* Check on cast that are proven correct at compile time */
13377   if (JNUMERIC_TYPE_P (cast_type) && JNUMERIC_TYPE_P (op_type))
13378     {
13379       /* Same type */
13380       if (cast_type == op_type)
13381         return node;
13382
13383       /* float and double type are converted to the original type main
13384          variant and then to the target type. */
13385       if (JFLOAT_TYPE_P (op_type) && TREE_CODE (cast_type) == CHAR_TYPE)
13386         op = convert (integer_type_node, op);
13387
13388       /* Try widening/narowwing convertion. Potentially, things need
13389          to be worked out in gcc so we implement the extreme cases
13390          correctly. fold_convert() needs to be fixed. */
13391       return convert (cast_type, op);
13392     }
13393
13394   /* It's also valid to cast a boolean into a boolean */
13395   if (op_type == boolean_type_node && cast_type == boolean_type_node)
13396     return node;
13397
13398   /* null can be casted to references */
13399   if (op == null_pointer_node && JREFERENCE_TYPE_P (cast_type))
13400     return build_null_of_type (cast_type);
13401
13402   /* The remaining legal casts involve conversion between reference
13403      types. Check for their compile time correctness. */
13404   if (JREFERENCE_TYPE_P (op_type) && JREFERENCE_TYPE_P (cast_type) 
13405       && valid_ref_assignconv_cast_p (op_type, cast_type, 1))
13406     {
13407       TREE_TYPE (node) = promote_type (cast_type);
13408       /* Now, the case can be determined correct at compile time if
13409          OP_TYPE can be converted into CAST_TYPE by assignment
13410          conversion (5.2) */
13411
13412       if (valid_ref_assignconv_cast_p (op_type, cast_type, 0))
13413         {
13414           TREE_SET_CODE (node, NOP_EXPR);
13415           return node;
13416         }
13417
13418       if (flag_emit_class_files)
13419         {
13420           TREE_SET_CODE (node, CONVERT_EXPR);
13421           return node;
13422         }
13423
13424       /* The cast requires a run-time check */
13425       return build (CALL_EXPR, promote_type (cast_type),
13426                     build_address_of (soft_checkcast_node),
13427                     tree_cons (NULL_TREE, build_class_ref (cast_type),
13428                                build_tree_list (NULL_TREE, op)),
13429                     NULL_TREE);
13430     }
13431
13432   /* Any other casts are proven incorrect at compile time */
13433   t1 = xstrdup (lang_printable_name (op_type, 0));
13434   parse_error_context (wfl_operator, "Invalid cast from `%s' to `%s'",
13435                        t1, lang_printable_name (cast_type, 0));
13436   free (t1);
13437   return error_mark_node;
13438 }
13439
13440 /* Build a null constant and give it the type TYPE.  */
13441
13442 static tree
13443 build_null_of_type (type)
13444      tree type;
13445 {
13446   tree node = build_int_2 (0, 0);
13447   TREE_TYPE (node) = promote_type (type);
13448   return node;
13449 }
13450
13451 /* Build an ARRAY_REF incomplete tree node. Note that operand 1 isn't
13452    a list of indices. */
13453 static tree
13454 build_array_ref (location, array, index)
13455      int location;
13456      tree array, index;
13457 {
13458   tree node = build (ARRAY_REF, NULL_TREE, array, index);
13459   EXPR_WFL_LINECOL (node) = location;
13460   return node;
13461 }
13462
13463 /* 15.12 Array Access Expression */
13464
13465 static tree
13466 patch_array_ref (node)
13467      tree node;
13468 {
13469   tree array = TREE_OPERAND (node, 0);
13470   tree array_type  = TREE_TYPE (array);
13471   tree index = TREE_OPERAND (node, 1);
13472   tree index_type = TREE_TYPE (index);
13473   int error_found = 0;
13474
13475   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13476
13477   if (TREE_CODE (array_type) == POINTER_TYPE)
13478     array_type = TREE_TYPE (array_type);
13479
13480   /* The array reference must be an array */
13481   if (!TYPE_ARRAY_P (array_type))
13482     {
13483       parse_error_context 
13484         (wfl_operator,
13485          "`[]' can only be applied to arrays. It can't be applied to `%s'",
13486          lang_printable_name (array_type, 0));
13487       TREE_TYPE (node) = error_mark_node;
13488       error_found = 1;
13489     }
13490
13491   /* The array index undergoes unary numeric promotion. The promoted
13492      type must be int */
13493   index = do_unary_numeric_promotion (index);
13494   if (TREE_TYPE (index) != int_type_node)
13495     {
13496       if (valid_cast_to_p (index_type, int_type_node))
13497         parse_error_context (wfl_operator,
13498    "Incompatible type for `[]'. Explicit cast needed to convert `%s' to `int'",
13499                              lang_printable_name (index_type, 0));
13500       else
13501         parse_error_context (wfl_operator,
13502           "Incompatible type for `[]'. Can't convert `%s' to `int'",
13503                              lang_printable_name (index_type, 0));
13504       TREE_TYPE (node) = error_mark_node;
13505       error_found = 1;
13506     }
13507
13508   if (error_found)
13509     return error_mark_node;
13510
13511   array_type = TYPE_ARRAY_ELEMENT (array_type);
13512
13513   if (flag_emit_class_files || flag_emit_xref)
13514     {
13515       TREE_OPERAND (node, 0) = array;
13516       TREE_OPERAND (node, 1) = index;
13517     }
13518   else
13519     {
13520       /* The save_expr is for correct evaluation order.  It would be cleaner
13521          to use force_evaluation_order (see comment there), but that is
13522          difficult when we also have to deal with bounds checking. */
13523       if (TREE_SIDE_EFFECTS (index))
13524         array = save_expr (array);
13525       node = build_java_arrayaccess (array, array_type, index);
13526       if (TREE_SIDE_EFFECTS (index))
13527         node = build (COMPOUND_EXPR, array_type, array, node);
13528     }
13529   TREE_TYPE (node) = array_type;
13530   return node;
13531 }
13532
13533 /* 15.9 Array Creation Expressions */
13534
13535 static tree
13536 build_newarray_node (type, dims, extra_dims)
13537      tree type;
13538      tree dims;
13539      int extra_dims;
13540 {
13541   tree node =
13542     build (NEW_ARRAY_EXPR, NULL_TREE, type, nreverse (dims), 
13543            build_int_2 (extra_dims, 0));
13544   return node;
13545 }
13546
13547 static tree
13548 patch_newarray (node)
13549      tree node;
13550 {
13551   tree type = TREE_OPERAND (node, 0);
13552   tree dims = TREE_OPERAND (node, 1);
13553   tree cdim, array_type;
13554   int error_found = 0;
13555   int ndims = 0;
13556   int xdims = TREE_INT_CST_LOW (TREE_OPERAND (node, 2));
13557
13558   /* Dimension types are verified. It's better for the types to be
13559      verified in order. */
13560   for (cdim = dims, ndims = 0; cdim; cdim = TREE_CHAIN (cdim), ndims++ )
13561     {
13562       int dim_error = 0;
13563       tree dim = TREE_VALUE (cdim);
13564
13565       /* Dim might have been saved during its evaluation */
13566       dim = (TREE_CODE (dim) == SAVE_EXPR ? dim = TREE_OPERAND (dim, 0) : dim);
13567
13568       /* The type of each specified dimension must be an integral type. */
13569       if (!JINTEGRAL_TYPE_P (TREE_TYPE (dim)))
13570         dim_error = 1;
13571
13572       /* Each expression undergoes an unary numeric promotion (5.6.1) and the
13573          promoted type must be int. */
13574       else
13575         {
13576           dim = do_unary_numeric_promotion (dim);
13577           if (TREE_TYPE (dim) != int_type_node)
13578             dim_error = 1;
13579         }
13580
13581       /* Report errors on types here */
13582       if (dim_error)
13583         {
13584           parse_error_context 
13585             (TREE_PURPOSE (cdim), 
13586              "Incompatible type for dimension in array creation expression. %s convert `%s' to `int'", 
13587              (valid_cast_to_p (TREE_TYPE (dim), int_type_node) ?
13588               "Explicit cast needed to" : "Can't"),
13589              lang_printable_name (TREE_TYPE (dim), 0));
13590           error_found = 1;
13591         }
13592
13593       TREE_PURPOSE (cdim) = NULL_TREE;
13594     }
13595
13596   /* Resolve array base type if unresolved */
13597   if (!(type = resolve_type_during_patch (type)))
13598     error_found = 1;
13599
13600   if (error_found)
13601     {
13602       /* We don't want further evaluation of this bogus array creation
13603          operation */
13604       TREE_TYPE (node) = error_mark_node;
13605       return error_mark_node;
13606     }
13607
13608   /* Set array_type to the actual (promoted) array type of the result. */
13609   if (TREE_CODE (type) == RECORD_TYPE)
13610     type = build_pointer_type (type);
13611   while (--xdims >= 0)
13612     {
13613       type = promote_type (build_java_array_type (type, -1));
13614     }
13615   dims = nreverse (dims);
13616   array_type = type;
13617   for (cdim = dims; cdim; cdim = TREE_CHAIN (cdim))
13618     {
13619       type = array_type;
13620       array_type
13621         = build_java_array_type (type,
13622                                  TREE_CODE (cdim) == INTEGER_CST
13623                                  ? (HOST_WIDE_INT) TREE_INT_CST_LOW (cdim)
13624                                  : -1);
13625       array_type = promote_type (array_type);
13626     }
13627   dims = nreverse (dims);
13628
13629   /* The node is transformed into a function call. Things are done
13630      differently according to the number of dimensions. If the number
13631      of dimension is equal to 1, then the nature of the base type
13632      (primitive or not) matters. */
13633   if (ndims == 1)
13634     return build_new_array (type, TREE_VALUE (dims));
13635   
13636   /* Can't reuse what's already written in expr.c because it uses the
13637      JVM stack representation. Provide a build_multianewarray. FIXME */
13638   return build (CALL_EXPR, array_type,
13639                 build_address_of (soft_multianewarray_node),
13640                 tree_cons (NULL_TREE, build_class_ref (TREE_TYPE (array_type)),
13641                            tree_cons (NULL_TREE, 
13642                                       build_int_2 (ndims, 0), dims )),
13643                 NULL_TREE);
13644 }
13645
13646 /* 10.6 Array initializer.  */
13647
13648 /* Build a wfl for array element that don't have one, so we can
13649    pin-point errors.  */
13650
13651 static tree
13652 maybe_build_array_element_wfl (node)
13653      tree node;
13654 {
13655   if (TREE_CODE (node) != EXPR_WITH_FILE_LOCATION)
13656     return build_expr_wfl (NULL_TREE, ctxp->filename,
13657                            ctxp->elc.line, ctxp->elc.prev_col);
13658   else
13659     return NULL_TREE;
13660 }
13661
13662 /* Build a NEW_ARRAY_INIT that features a CONSTRUCTOR node. This makes
13663    identification of initialized arrays easier to detect during walk
13664    and expansion.  */
13665
13666 static tree
13667 build_new_array_init (location, values)
13668      int location;
13669      tree values;
13670 {
13671   tree constructor = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, values);
13672   tree to_return = build1 (NEW_ARRAY_INIT, NULL_TREE, constructor);
13673   EXPR_WFL_LINECOL (to_return) = location;
13674   return to_return;
13675 }
13676
13677 /* Expand a NEW_ARRAY_INIT node. Return error_mark_node if an error
13678    occurred.  Otherwise return NODE after having set its type
13679    appropriately.  */
13680
13681 static tree
13682 patch_new_array_init (type, node)
13683      tree type, node;
13684 {
13685   int error_seen = 0;
13686   tree current, element_type;
13687   HOST_WIDE_INT length;
13688   int all_constant = 1;
13689   tree init = TREE_OPERAND (node, 0);
13690
13691   if (TREE_CODE (type) != POINTER_TYPE || ! TYPE_ARRAY_P (TREE_TYPE (type)))
13692     {
13693       parse_error_context (node,
13694                            "Invalid array initializer for non-array type `%s'",
13695                            lang_printable_name (type, 1));
13696       return error_mark_node;
13697     }
13698   type = TREE_TYPE (type);
13699   element_type = TYPE_ARRAY_ELEMENT (type);
13700
13701   CONSTRUCTOR_ELTS (init) = nreverse (CONSTRUCTOR_ELTS (init));
13702
13703   for (length = 0, current = CONSTRUCTOR_ELTS (init);
13704        current;  length++, current = TREE_CHAIN (current))
13705     {
13706       tree elt = TREE_VALUE (current);
13707       if (elt == NULL_TREE || TREE_CODE (elt) != NEW_ARRAY_INIT)
13708         {
13709           error_seen |= array_constructor_check_entry (element_type, current);
13710           elt = TREE_VALUE (current);
13711           /* When compiling to native code, STRING_CST is converted to
13712              INDIRECT_REF, but still with a TREE_CONSTANT flag. */
13713           if (! TREE_CONSTANT (elt) || TREE_CODE (elt) == INDIRECT_REF)
13714             all_constant = 0;
13715         }
13716       else
13717         {
13718           TREE_VALUE (current) = patch_new_array_init (element_type, elt);
13719           TREE_PURPOSE (current) = NULL_TREE;
13720           all_constant = 0;
13721         }
13722       if (elt && TREE_CODE (elt) == TREE_LIST 
13723           && TREE_VALUE (elt) == error_mark_node)
13724         error_seen = 1;
13725     }
13726
13727   if (error_seen)
13728     return error_mark_node;
13729
13730   /* Create a new type. We can't reuse the one we have here by
13731      patching its dimension because it originally is of dimension -1
13732      hence reused by gcc. This would prevent triangular arrays. */
13733   type = build_java_array_type (element_type, length);
13734   TREE_TYPE (init) = TREE_TYPE (TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (type))));
13735   TREE_TYPE (node) = promote_type (type);
13736   TREE_CONSTANT (init) = all_constant;
13737   TREE_CONSTANT (node) = all_constant;
13738   return node;
13739 }
13740
13741 /* Verify that one entry of the initializer element list can be
13742    assigned to the array base type. Report 1 if an error occurred, 0
13743    otherwise.  */
13744
13745 static int
13746 array_constructor_check_entry (type, entry)
13747      tree type, entry;
13748 {
13749   char *array_type_string = NULL;       /* For error reports */
13750   tree value, type_value, new_value, wfl_value, patched;
13751   int error_seen = 0;
13752
13753   new_value = NULL_TREE;
13754   wfl_value = TREE_VALUE (entry);
13755
13756   push_obstacks (&permanent_obstack, &permanent_obstack);
13757   value = java_complete_tree (TREE_VALUE (entry));
13758   /* patch_string return error_mark_node if arg is error_mark_node */
13759   if ((patched = patch_string (value)))
13760     value = patched;
13761   if (value == error_mark_node)
13762     return 1;
13763   
13764   type_value = TREE_TYPE (value);
13765   
13766   /* At anytime, try_builtin_assignconv can report a warning on
13767      constant overflow during narrowing. */
13768   SET_WFL_OPERATOR (wfl_operator, TREE_PURPOSE (entry), wfl_value);
13769   new_value = try_builtin_assignconv (wfl_operator, type, value);
13770   if (!new_value && (new_value = try_reference_assignconv (type, value)))
13771     type_value = promote_type (type);
13772
13773   pop_obstacks ();
13774   /* Check and report errors */
13775   if (!new_value)
13776     {
13777       const char *msg = (!valid_cast_to_p (type_value, type) ?
13778                    "Can't" : "Explicit cast needed to");
13779       if (!array_type_string)
13780         array_type_string = xstrdup (lang_printable_name (type, 1));
13781       parse_error_context 
13782         (wfl_operator, "Incompatible type for array. %s convert `%s' to `%s'",
13783          msg, lang_printable_name (type_value, 1), array_type_string);
13784       error_seen = 1;
13785     }
13786   
13787   if (new_value)
13788     {
13789       new_value = maybe_build_primttype_type_ref (new_value, wfl_value);
13790       TREE_VALUE (entry) = new_value;
13791     }
13792
13793   if (array_type_string)
13794     free (array_type_string);
13795
13796   TREE_PURPOSE (entry) = NULL_TREE;
13797   return error_seen;
13798 }
13799
13800 static tree
13801 build_this (location)
13802      int location;
13803 {
13804   tree node = build_wfl_node (this_identifier_node);
13805   TREE_SET_CODE (node, THIS_EXPR);
13806   EXPR_WFL_LINECOL (node) = location;
13807   return node;
13808 }
13809
13810 /* 14.15 The return statement. It builds a modify expression that
13811    assigns the returned value to the RESULT_DECL that hold the value
13812    to be returned. */
13813
13814 static tree
13815 build_return (location, op)
13816      int location;
13817      tree op;
13818 {
13819   tree node = build1 (RETURN_EXPR, NULL_TREE, op);
13820   EXPR_WFL_LINECOL (node) = location;
13821   node = build_debugable_stmt (location, node);
13822   return node;
13823 }
13824
13825 static tree
13826 patch_return (node)
13827      tree node;
13828 {
13829   tree return_exp = TREE_OPERAND (node, 0);
13830   tree meth = current_function_decl;
13831   tree mtype = TREE_TYPE (TREE_TYPE (current_function_decl));
13832   int error_found = 0;
13833
13834   TREE_TYPE (node) = error_mark_node;
13835   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13836
13837   /* It's invalid to have a return value within a function that is
13838      declared with the keyword void or that is a constructor */
13839   if (return_exp && (mtype == void_type_node || DECL_CONSTRUCTOR_P (meth)))
13840     error_found = 1;
13841
13842   /* It's invalid to use a return statement in a static block */
13843   if (DECL_CLINIT_P (current_function_decl))
13844     error_found = 1;
13845
13846   /* It's invalid to have a no return value within a function that
13847      isn't declared with the keyword `void' */
13848   if (!return_exp && (mtype != void_type_node && !DECL_CONSTRUCTOR_P (meth)))
13849     error_found = 2;
13850   
13851   if (in_instance_initializer)
13852     error_found = 1;
13853
13854   if (error_found)
13855     {
13856       if (in_instance_initializer)
13857         parse_error_context (wfl_operator,
13858                              "`return' inside instance initializer");
13859         
13860       else if (DECL_CLINIT_P (current_function_decl))
13861         parse_error_context (wfl_operator,
13862                              "`return' inside static initializer");
13863
13864       else if (!DECL_CONSTRUCTOR_P (meth))
13865         {
13866           char *t = xstrdup (lang_printable_name (mtype, 0));
13867           parse_error_context (wfl_operator, 
13868                                "`return' with%s value from `%s %s'",
13869                                (error_found == 1 ? "" : "out"), 
13870                                t, lang_printable_name (meth, 0));
13871           free (t);
13872         }
13873       else
13874         parse_error_context (wfl_operator, 
13875                              "`return' with value from constructor `%s'",
13876                              lang_printable_name (meth, 0));
13877       return error_mark_node;
13878     }
13879
13880   /* If we have a return_exp, build a modify expression and expand
13881      it. Note: at that point, the assignment is declared valid, but we
13882      may want to carry some more hacks */
13883   if (return_exp)
13884     {
13885       tree exp = java_complete_tree (return_exp);
13886       tree modify, patched;
13887
13888       /* If the function returned value and EXP are booleans, EXP has
13889       to be converted into the type of DECL_RESULT, which is integer
13890       (see complete_start_java_method) */
13891       if (TREE_TYPE (exp) == boolean_type_node &&
13892           TREE_TYPE (TREE_TYPE (meth)) == boolean_type_node)
13893         exp = convert_to_integer (TREE_TYPE (DECL_RESULT (meth)), exp);
13894
13895       /* `null' can be assigned to a function returning a reference */
13896       if (JREFERENCE_TYPE_P (TREE_TYPE (TREE_TYPE (meth))) &&
13897           exp == null_pointer_node)
13898         exp = build_null_of_type (TREE_TYPE (TREE_TYPE (meth)));
13899
13900       if ((patched = patch_string (exp)))
13901         exp = patched;
13902       
13903       modify = build (MODIFY_EXPR, NULL_TREE, DECL_RESULT (meth), exp);
13904       EXPR_WFL_LINECOL (modify) = EXPR_WFL_LINECOL (node);
13905       modify = java_complete_tree (modify);
13906
13907       if (modify != error_mark_node)
13908         {
13909           TREE_SIDE_EFFECTS (modify) = 1;
13910           TREE_OPERAND (node, 0) = modify;
13911         }
13912       else
13913         return error_mark_node;
13914     }
13915   TREE_TYPE (node) = void_type_node;
13916   TREE_SIDE_EFFECTS (node) = 1;
13917   return node;
13918 }
13919
13920 /* 14.8 The if Statement */
13921
13922 static tree
13923 build_if_else_statement (location, expression, if_body, else_body)
13924      int location;
13925      tree expression, if_body, else_body;
13926 {
13927   tree node;
13928   if (!else_body)
13929     else_body = empty_stmt_node;
13930   node = build (COND_EXPR, NULL_TREE, expression, if_body, else_body);
13931   EXPR_WFL_LINECOL (node) = location;
13932   node = build_debugable_stmt (location, node);
13933   return node;
13934 }
13935
13936 static tree
13937 patch_if_else_statement (node)
13938      tree node;
13939 {
13940   tree expression = TREE_OPERAND (node, 0);
13941
13942   TREE_TYPE (node) = error_mark_node;
13943   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
13944
13945   /* The type of expression must be boolean */
13946   if (TREE_TYPE (expression) != boolean_type_node
13947       && TREE_TYPE (expression) != promoted_boolean_type_node)
13948     {
13949       parse_error_context 
13950         (wfl_operator, 
13951          "Incompatible type for `if'. Can't convert `%s' to `boolean'", 
13952          lang_printable_name (TREE_TYPE (expression), 0));
13953       return error_mark_node;
13954     }
13955   
13956   TREE_TYPE (node) = void_type_node;
13957   TREE_SIDE_EFFECTS (node) = 1;
13958   CAN_COMPLETE_NORMALLY (node)
13959     = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1))
13960     | CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 2));
13961   return node;
13962 }
13963
13964 /* 14.6 Labeled Statements */
13965
13966 /* Action taken when a lableled statement is parsed. a new
13967    LABELED_BLOCK_EXPR is created. No statement is attached to the
13968    label, yet.  LABEL can be NULL_TREE for artificially-generated blocks. */
13969
13970 static tree
13971 build_labeled_block (location, label)
13972      int location;
13973      tree label;
13974 {
13975   tree label_name ;
13976   tree label_decl, node;
13977   if (label == NULL_TREE || label == continue_identifier_node)
13978     label_name = label;
13979   else
13980     {
13981       label_name = merge_qualified_name (label_id, label);
13982       /* Issue an error if we try to reuse a label that was previously
13983          declared */
13984       if (IDENTIFIER_LOCAL_VALUE (label_name))
13985         {
13986           EXPR_WFL_LINECOL (wfl_operator) = location;
13987           parse_error_context (wfl_operator,
13988             "Declaration of `%s' shadows a previous label declaration",
13989                                IDENTIFIER_POINTER (label));
13990           EXPR_WFL_LINECOL (wfl_operator) = 
13991             EXPR_WFL_LINECOL (IDENTIFIER_LOCAL_VALUE (label_name));
13992           parse_error_context (wfl_operator,
13993             "This is the location of the previous declaration of label `%s'",
13994                                IDENTIFIER_POINTER (label));
13995           java_error_count--;
13996         }
13997     }
13998
13999   label_decl = create_label_decl (label_name);
14000   node = build (LABELED_BLOCK_EXPR, NULL_TREE, label_decl, NULL_TREE);
14001   EXPR_WFL_LINECOL (node) = location;
14002   TREE_SIDE_EFFECTS (node) = 1;
14003   return node;
14004 }
14005
14006 /* A labeled statement LBE is attached a statement.  */
14007
14008 static tree
14009 finish_labeled_statement (lbe, statement)
14010      tree lbe;                  /* Labeled block expr */
14011      tree statement;
14012 {
14013   /* In anyways, tie the loop to its statement */
14014   LABELED_BLOCK_BODY (lbe) = statement;
14015   pop_labeled_block ();
14016   POP_LABELED_BLOCK ();
14017   return lbe;
14018 }
14019
14020 /* 14.10, 14.11, 14.12 Loop Statements */
14021
14022 /* Create an empty LOOP_EXPR and make it the last in the nested loop
14023    list. */
14024
14025 static tree
14026 build_new_loop (loop_body)
14027      tree loop_body;
14028 {
14029   tree loop =  build (LOOP_EXPR, NULL_TREE, loop_body);
14030   TREE_SIDE_EFFECTS (loop) = 1;
14031   PUSH_LOOP (loop);
14032   return loop;
14033 }
14034
14035 /* Create a loop body according to the following structure:
14036      COMPOUND_EXPR
14037        COMPOUND_EXPR            (loop main body)
14038          EXIT_EXPR              (this order is for while/for loops.
14039          LABELED_BLOCK_EXPR      the order is reversed for do loops)
14040            LABEL_DECL           (a continue occuring here branches at the 
14041            BODY                  end of this labeled block)
14042        INCREMENT                (if any)
14043
14044   REVERSED, if non zero, tells that the loop condition expr comes
14045   after the body, like in the do-while loop.
14046
14047   To obtain a loop, the loop body structure described above is
14048   encapsulated within a LOOP_EXPR surrounded by a LABELED_BLOCK_EXPR:
14049
14050    LABELED_BLOCK_EXPR
14051      LABEL_DECL                   (use this label to exit the loop)
14052      LOOP_EXPR
14053        <structure described above> */
14054
14055 static tree
14056 build_loop_body (location, condition, reversed)
14057      int location;
14058      tree condition;
14059      int reversed;
14060 {
14061   tree first, second, body;
14062
14063   condition = build (EXIT_EXPR, NULL_TREE, condition); /* Force walk */
14064   EXPR_WFL_LINECOL (condition) = location; /* For accurate error report */
14065   condition = build_debugable_stmt (location, condition);
14066   TREE_SIDE_EFFECTS (condition) = 1;
14067
14068   body = build_labeled_block (0, continue_identifier_node);
14069   first = (reversed ? body : condition);
14070   second = (reversed ? condition : body);
14071   return 
14072     build (COMPOUND_EXPR, NULL_TREE, 
14073            build (COMPOUND_EXPR, NULL_TREE, first, second), empty_stmt_node);
14074 }
14075
14076 /* Install CONDITION (if any) and loop BODY (using REVERSED to tell
14077    their order) on the current loop. Unlink the current loop from the
14078    loop list.  */
14079
14080 static tree
14081 finish_loop_body (location, condition, body, reversed)
14082      int location;
14083      tree condition, body;
14084      int reversed;
14085 {
14086   tree to_return = ctxp->current_loop;
14087   tree loop_body = LOOP_EXPR_BODY (to_return);
14088   if (condition)
14089     {
14090       tree cnode = LOOP_EXPR_BODY_CONDITION_EXPR (loop_body, reversed);
14091       /* We wrapped the EXIT_EXPR around a WFL so we can debug it.
14092          The real EXIT_EXPR is one operand further. */
14093       EXPR_WFL_LINECOL (cnode) = location;
14094       /* This one is for accurate error reports */
14095       EXPR_WFL_LINECOL (TREE_OPERAND (cnode, 0)) = location;
14096       TREE_OPERAND (TREE_OPERAND (cnode, 0), 0) = condition;
14097     }
14098   LOOP_EXPR_BODY_BODY_EXPR (loop_body, reversed) = body;
14099   POP_LOOP ();
14100   return to_return;
14101 }
14102
14103 /* Tailored version of finish_loop_body for FOR loops, when FOR
14104    loops feature the condition part */
14105
14106 static tree
14107 finish_for_loop (location, condition, update, body)
14108     int location;
14109     tree condition, update, body;
14110 {
14111   /* Put the condition and the loop body in place */
14112   tree loop = finish_loop_body (location, condition, body, 0);
14113   /* LOOP is the current loop which has been now popped of the loop
14114      stack. Install the update block */
14115   LOOP_EXPR_BODY_UPDATE_BLOCK (LOOP_EXPR_BODY (loop)) = update;
14116   return loop;
14117 }
14118
14119 /* Try to find the loop a block might be related to. This comprises
14120    the case where the LOOP_EXPR is found as the second operand of a
14121    COMPOUND_EXPR, because the loop happens to have an initialization
14122    part, then expressed as the first operand of the COMPOUND_EXPR. If
14123    the search finds something, 1 is returned. Otherwise, 0 is
14124    returned. The search is assumed to start from a
14125    LABELED_BLOCK_EXPR's block.  */
14126
14127 static tree
14128 search_loop (statement)
14129     tree statement;
14130 {
14131   if (TREE_CODE (statement) == LOOP_EXPR)
14132     return statement;
14133
14134   if (TREE_CODE (statement) == BLOCK)
14135     statement = BLOCK_SUBBLOCKS (statement);
14136   else
14137     return NULL_TREE;
14138
14139   if (statement && TREE_CODE (statement) == COMPOUND_EXPR)
14140     while (statement && TREE_CODE (statement) == COMPOUND_EXPR)
14141       statement = TREE_OPERAND (statement, 1);
14142
14143   return (TREE_CODE (statement) == LOOP_EXPR
14144           && FOR_LOOP_P (statement) ? statement : NULL_TREE);
14145 }
14146
14147 /* Return 1 if LOOP can be found in the labeled block BLOCK. 0 is
14148    returned otherwise.  */
14149
14150 static int
14151 labeled_block_contains_loop_p (block, loop)
14152     tree block, loop;
14153 {
14154   if (!block)
14155     return 0;
14156
14157   if (LABELED_BLOCK_BODY (block) == loop)
14158     return 1;
14159
14160   if (FOR_LOOP_P (loop) && search_loop (LABELED_BLOCK_BODY (block)) == loop)
14161     return 1;
14162
14163   return 0;
14164 }
14165
14166 /* If the loop isn't surrounded by a labeled statement, create one and
14167    insert LOOP as its body.  */
14168
14169 static tree
14170 patch_loop_statement (loop)
14171      tree loop;
14172 {
14173   tree loop_label;
14174
14175   TREE_TYPE (loop) = void_type_node;
14176   if (labeled_block_contains_loop_p (ctxp->current_labeled_block, loop))
14177     return loop;
14178
14179   loop_label = build_labeled_block (0, NULL_TREE);
14180   /* LOOP is an EXPR node, so it should have a valid EXPR_WFL_LINECOL
14181      that LOOP_LABEL could enquire about, for a better accuracy. FIXME */
14182   LABELED_BLOCK_BODY (loop_label) = loop;
14183   PUSH_LABELED_BLOCK (loop_label);
14184   return loop_label;
14185 }
14186
14187 /* 14.13, 14.14: break and continue Statements */
14188
14189 /* Build a break or a continue statement. a null NAME indicates an
14190    unlabeled break/continue statement.  */
14191
14192 static tree
14193 build_bc_statement (location, is_break, name)
14194      int location, is_break;
14195      tree name;
14196 {
14197   tree break_continue, label_block_expr = NULL_TREE;
14198
14199   if (name)
14200     {
14201       if (!(label_block_expr = IDENTIFIER_LOCAL_VALUE 
14202             (merge_qualified_name (label_id, EXPR_WFL_NODE (name)))))
14203         /* Null means that we don't have a target for this named
14204            break/continue. In this case, we make the target to be the
14205            label name, so that the error can be reported accuratly in
14206            patch_bc_statement. */
14207         label_block_expr = EXPR_WFL_NODE (name);
14208     }
14209   /* Unlabeled break/continue will be handled during the
14210      break/continue patch operation */
14211   break_continue 
14212     = build (EXIT_BLOCK_EXPR, NULL_TREE, label_block_expr, NULL_TREE);
14213
14214   IS_BREAK_STMT_P (break_continue) = is_break;
14215   TREE_SIDE_EFFECTS (break_continue) = 1;
14216   EXPR_WFL_LINECOL (break_continue) = location;
14217   break_continue = build_debugable_stmt (location, break_continue);
14218   return break_continue;
14219 }
14220
14221 /* Verification of a break/continue statement. */
14222
14223 static tree
14224 patch_bc_statement (node)
14225      tree node;
14226 {
14227   tree bc_label = EXIT_BLOCK_LABELED_BLOCK (node), target_stmt;
14228   tree labeled_block = ctxp->current_labeled_block;
14229   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14230  
14231   /* Having an identifier here means that the target is unknown. */
14232   if (bc_label != NULL_TREE && TREE_CODE (bc_label) == IDENTIFIER_NODE)
14233     {
14234       parse_error_context (wfl_operator, "No label definition found for `%s'",
14235                            IDENTIFIER_POINTER (bc_label));
14236       return error_mark_node;
14237     }
14238   if (! IS_BREAK_STMT_P (node))
14239     {
14240       /* It's a continue statement. */
14241       for (;; labeled_block = TREE_CHAIN (labeled_block))
14242         {
14243           if (labeled_block == NULL_TREE)
14244             {
14245               if (bc_label == NULL_TREE)
14246                 parse_error_context (wfl_operator,
14247                                      "`continue' must be in loop");
14248               else
14249                 parse_error_context 
14250                   (wfl_operator, "continue label `%s' does not name a loop",
14251                    IDENTIFIER_POINTER (bc_label));
14252               return error_mark_node;
14253             }
14254           if ((DECL_NAME (LABELED_BLOCK_LABEL (labeled_block))
14255                == continue_identifier_node)
14256               && (bc_label == NULL_TREE
14257                   || TREE_CHAIN (labeled_block) == bc_label))
14258             {
14259               bc_label = labeled_block;
14260               break;
14261             }
14262         }
14263     }
14264   else if (!bc_label)
14265     { 
14266       for (;; labeled_block = TREE_CHAIN (labeled_block))
14267         {
14268           if (labeled_block == NULL_TREE)
14269             {
14270               parse_error_context (wfl_operator,
14271                                      "`break' must be in loop or switch");
14272               return error_mark_node;
14273             }
14274           target_stmt = LABELED_BLOCK_BODY (labeled_block);
14275           if (TREE_CODE (target_stmt) == SWITCH_EXPR
14276               || search_loop (target_stmt))
14277             {
14278               bc_label = labeled_block;
14279               break;
14280             }
14281         }
14282     }
14283
14284   EXIT_BLOCK_LABELED_BLOCK (node) = bc_label;
14285   CAN_COMPLETE_NORMALLY (bc_label) = 1;
14286
14287   /* Our break/continue don't return values. */
14288   TREE_TYPE (node) = void_type_node;
14289   /* Encapsulate the break within a compound statement so that it's
14290      expanded all the times by expand_expr (and not clobbered
14291      sometimes, like after a if statement) */
14292   node = add_stmt_to_compound (NULL_TREE, void_type_node, node);
14293   TREE_SIDE_EFFECTS (node) = 1;
14294   return node;
14295 }
14296
14297 /* Process the exit expression belonging to a loop. Its type must be
14298    boolean.  */
14299
14300 static tree
14301 patch_exit_expr (node)
14302      tree node;
14303 {
14304   tree expression = TREE_OPERAND (node, 0);
14305   TREE_TYPE (node) = error_mark_node;
14306   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14307
14308   /* The type of expression must be boolean */
14309   if (TREE_TYPE (expression) != boolean_type_node)
14310     {
14311       parse_error_context 
14312         (wfl_operator, 
14313     "Incompatible type for loop conditional. Can't convert `%s' to `boolean'", 
14314          lang_printable_name (TREE_TYPE (expression), 0));
14315       return error_mark_node;
14316     }
14317   /* Now we know things are allright, invert the condition, fold and
14318      return */
14319   TREE_OPERAND (node, 0) = 
14320     fold (build1 (TRUTH_NOT_EXPR, boolean_type_node, expression));
14321
14322   if (! integer_zerop (TREE_OPERAND (node, 0))
14323       && ctxp->current_loop != NULL_TREE
14324       && TREE_CODE (ctxp->current_loop) == LOOP_EXPR)
14325     CAN_COMPLETE_NORMALLY (ctxp->current_loop) = 1;
14326   if (! integer_onep (TREE_OPERAND (node, 0)))
14327     CAN_COMPLETE_NORMALLY (node) = 1;
14328
14329
14330   TREE_TYPE (node) = void_type_node;
14331   return node;
14332 }
14333
14334 /* 14.9 Switch statement */
14335
14336 static tree
14337 patch_switch_statement (node)
14338      tree node;
14339 {
14340   tree se = TREE_OPERAND (node, 0), se_type;
14341
14342   /* Complete the switch expression */
14343   se = TREE_OPERAND (node, 0) = java_complete_tree (se);
14344   se_type = TREE_TYPE (se);
14345   /* The type of the switch expression must be char, byte, short or
14346      int */
14347   if (!JINTEGRAL_TYPE_P (se_type))
14348     {
14349       EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
14350       parse_error_context (wfl_operator,
14351           "Incompatible type for `switch'. Can't convert `%s' to `int'",
14352                            lang_printable_name (se_type, 0));
14353       /* This is what java_complete_tree will check */
14354       TREE_OPERAND (node, 0) = error_mark_node;
14355       return error_mark_node;
14356     }
14357
14358   TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
14359
14360   /* Ready to return */
14361   if (TREE_CODE (TREE_OPERAND (node, 1)) == ERROR_MARK)
14362     {
14363       TREE_TYPE (node) = error_mark_node;
14364       return error_mark_node;
14365     }
14366   TREE_TYPE (node) = void_type_node;
14367   TREE_SIDE_EFFECTS (node) = 1;
14368   CAN_COMPLETE_NORMALLY (node)
14369     = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)) 
14370       || ! SWITCH_HAS_DEFAULT (node);
14371   return node;
14372 }
14373
14374 /* 14.18 The try/catch statements */
14375
14376 static tree
14377 build_try_statement (location, try_block, catches)
14378      int location;
14379      tree try_block, catches;
14380 {
14381   tree node = build (TRY_EXPR, NULL_TREE, try_block, catches);
14382   EXPR_WFL_LINECOL (node) = location;
14383   return node;
14384 }
14385
14386 static tree
14387 build_try_finally_statement (location, try_block, finally)
14388      int location;
14389      tree try_block, finally;
14390 {
14391   tree node = build (TRY_FINALLY_EXPR, NULL_TREE, try_block, finally);
14392   EXPR_WFL_LINECOL (node) = location;
14393   return node;
14394 }
14395
14396 static tree
14397 patch_try_statement (node)
14398      tree node;
14399 {
14400   int error_found = 0;
14401   tree try = TREE_OPERAND (node, 0);
14402   /* Exception handlers are considered in left to right order */
14403   tree catch = nreverse (TREE_OPERAND (node, 1));
14404   tree current, caught_type_list = NULL_TREE;
14405
14406   /* Check catch clauses, if any. Every time we find an error, we try
14407      to process the next catch clause. We process the catch clause before
14408      the try block so that when processing the try block we can check thrown
14409      exceptions againts the caught type list. */
14410   for (current = catch; current; current = TREE_CHAIN (current))
14411     {
14412       tree carg_decl, carg_type;
14413       tree sub_current, catch_block, catch_clause;
14414       int unreachable;
14415
14416       /* At this point, the structure of the catch clause is
14417            CATCH_EXPR           (catch node)
14418              BLOCK              (with the decl of the parameter)
14419                COMPOUND_EXPR
14420                  MODIFY_EXPR   (assignment of the catch parameter)
14421                  BLOCK          (catch clause block)
14422        */
14423       catch_clause = TREE_OPERAND (current, 0);
14424       carg_decl = BLOCK_EXPR_DECLS (catch_clause);
14425       carg_type = TREE_TYPE (TREE_TYPE (carg_decl));
14426
14427       /* Catch clauses can't have more than one parameter declared,
14428          but it's already enforced by the grammar. Make sure that the
14429          only parameter of the clause statement in of class Throwable
14430          or a subclass of Throwable, but that was done earlier. The
14431          catch clause parameter type has also been resolved. */
14432       
14433       /* Just make sure that the catch clause parameter type inherits
14434          from java.lang.Throwable */
14435       if (!inherits_from_p (carg_type, throwable_type_node))
14436         {
14437           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
14438           parse_error_context (wfl_operator,
14439                                "Can't catch class `%s'. Catch clause parameter type must be a subclass of class `java.lang.Throwable'",
14440                                lang_printable_name (carg_type, 0));
14441           error_found = 1;
14442           continue;
14443         }
14444       
14445       /* Partial check for unreachable catch statement: The catch
14446          clause is reachable iff is no earlier catch block A in
14447          the try statement such that the type of the catch
14448          clause's parameter is the same as or a subclass of the
14449          type of A's parameter */
14450       unreachable = 0;
14451       for (sub_current = catch;
14452            sub_current != current; sub_current = TREE_CHAIN (sub_current))
14453         {
14454           tree sub_catch_clause, decl;
14455           sub_catch_clause = TREE_OPERAND (sub_current, 0);
14456           decl = BLOCK_EXPR_DECLS (sub_catch_clause);
14457
14458           if (inherits_from_p (carg_type, TREE_TYPE (TREE_TYPE (decl))))
14459             {
14460               EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
14461               parse_error_context 
14462                 (wfl_operator,
14463                  "`catch' not reached because of the catch clause at line %d",
14464                  EXPR_WFL_LINENO (sub_current));
14465               unreachable = error_found = 1;
14466               break;
14467             }
14468         }
14469       /* Complete the catch clause block */
14470       catch_block = java_complete_tree (TREE_OPERAND (current, 0));
14471       if (catch_block == error_mark_node)
14472         {
14473           error_found = 1;
14474           continue;
14475         }
14476       if (CAN_COMPLETE_NORMALLY (catch_block))
14477         CAN_COMPLETE_NORMALLY (node) = 1;
14478       TREE_OPERAND (current, 0) = catch_block;
14479
14480       if (unreachable)
14481         continue;
14482
14483       /* Things to do here: the exception must be thrown */
14484
14485       /* Link this type to the caught type list */
14486       caught_type_list = tree_cons (NULL_TREE, carg_type, caught_type_list);
14487     }
14488
14489   PUSH_EXCEPTIONS (caught_type_list);
14490   if ((try = java_complete_tree (try)) == error_mark_node)
14491     error_found = 1;
14492   if (CAN_COMPLETE_NORMALLY (try))
14493     CAN_COMPLETE_NORMALLY (node) = 1;
14494   POP_EXCEPTIONS ();
14495
14496   /* Verification ends here */
14497   if (error_found) 
14498     return error_mark_node;
14499
14500   TREE_OPERAND (node, 0) = try;
14501   TREE_OPERAND (node, 1) = catch;
14502   TREE_TYPE (node) = void_type_node;
14503   return node;
14504 }
14505
14506 /* 14.17 The synchronized Statement */
14507
14508 static tree
14509 patch_synchronized_statement (node, wfl_op1)
14510     tree node, wfl_op1;
14511 {
14512   tree expr = java_complete_tree (TREE_OPERAND (node, 0));
14513   tree block = TREE_OPERAND (node, 1);
14514
14515   tree enter, exit, expr_decl, assignment;
14516
14517   if (expr == error_mark_node)
14518     {
14519       block = java_complete_tree (block);
14520       return expr;
14521     }
14522
14523   /* The TYPE of expr must be a reference type */
14524   if (!JREFERENCE_TYPE_P (TREE_TYPE (expr)))
14525     {
14526       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
14527       parse_error_context (wfl_operator, "Incompatible type for `synchronized'. Can't convert `%s' to `java.lang.Object'",
14528                            lang_printable_name (TREE_TYPE (expr), 0));
14529       return error_mark_node;
14530     }
14531
14532   if (flag_emit_xref)
14533     {
14534       TREE_OPERAND (node, 0) = expr;
14535       TREE_OPERAND (node, 1) = java_complete_tree (block);
14536       CAN_COMPLETE_NORMALLY (node) = 1;
14537       return node;
14538     }
14539
14540   /* Generate a try-finally for the synchronized statement, except
14541      that the handler that catches all throw exception calls
14542      _Jv_MonitorExit and then rethrow the exception.
14543      The synchronized statement is then implemented as:
14544      TRY 
14545        {
14546          _Jv_MonitorEnter (expression)
14547          synchronized_block
14548          _Jv_MonitorExit (expression)
14549        }
14550      CATCH_ALL
14551        {
14552          e = _Jv_exception_info ();
14553          _Jv_MonitorExit (expression)
14554          Throw (e);
14555        } */
14556
14557   expr_decl = build_decl (VAR_DECL, generate_name (), TREE_TYPE (expr));
14558   BUILD_MONITOR_ENTER (enter, expr_decl);
14559   BUILD_MONITOR_EXIT (exit, expr_decl);
14560   CAN_COMPLETE_NORMALLY (enter) = 1;
14561   CAN_COMPLETE_NORMALLY (exit) = 1;
14562   assignment = build (MODIFY_EXPR, NULL_TREE, expr_decl, expr);
14563   TREE_SIDE_EFFECTS (assignment) = 1;
14564   node = build1 (CLEANUP_POINT_EXPR, NULL_TREE,
14565                  build (COMPOUND_EXPR, NULL_TREE,
14566                         build (WITH_CLEANUP_EXPR, NULL_TREE,
14567                                build (COMPOUND_EXPR, NULL_TREE,
14568                                       assignment, enter),
14569                                NULL_TREE, exit),
14570                         block));
14571   node = build_expr_block (node, expr_decl);
14572
14573   return java_complete_tree (node);
14574 }
14575
14576 /* 14.16 The throw Statement */
14577
14578 static tree
14579 patch_throw_statement (node, wfl_op1)
14580     tree node, wfl_op1;
14581 {
14582   tree expr = TREE_OPERAND (node, 0);
14583   tree type = TREE_TYPE (expr);
14584   int unchecked_ok = 0, tryblock_throws_ok = 0;
14585
14586   /* Thrown expression must be assignable to java.lang.Throwable */
14587   if (!try_reference_assignconv (throwable_type_node, expr))
14588     {
14589       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
14590       parse_error_context (wfl_operator,
14591     "Can't throw `%s'; it must be a subclass of class `java.lang.Throwable'",
14592                            lang_printable_name (type, 0));
14593       /* If the thrown expression was a reference, we further the
14594          compile-time check. */
14595       if (!JREFERENCE_TYPE_P (type))
14596         return error_mark_node;
14597     }
14598
14599   /* At least one of the following must be true */
14600
14601   /* The type of the throw expression is a not checked exception,
14602      i.e. is a unchecked expression. */
14603   unchecked_ok = IS_UNCHECKED_EXCEPTION_P (TREE_TYPE (type));
14604
14605   SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
14606   /* An instance can't throw a checked excetion unless that exception
14607      is explicitely declared in the `throws' clause of each
14608      constructor. This doesn't apply to anonymous classes, since they
14609      don't have declared constructors. */
14610   if (!unchecked_ok 
14611       && in_instance_initializer && !ANONYMOUS_CLASS_P (current_class))
14612     {
14613       tree current;
14614       for (current = TYPE_METHODS (current_class); current; 
14615            current = TREE_CHAIN (current))
14616         if (DECL_CONSTRUCTOR_P (current) 
14617             && !check_thrown_exceptions_do (TREE_TYPE (expr)))
14618           {
14619             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)", 
14620                                  lang_printable_name (TREE_TYPE (expr), 0));
14621             return error_mark_node;
14622           }
14623     }
14624
14625   /* Throw is contained in a try statement and at least one catch
14626      clause can receive the thrown expression or the current method is
14627      declared to throw such an exception. Or, the throw statement is
14628      contained in a method or constructor declaration and the type of
14629      the Expression is assignable to at least one type listed in the
14630      throws clause the declaration. */
14631   if (!unchecked_ok)
14632     tryblock_throws_ok = check_thrown_exceptions_do (TREE_TYPE (expr));
14633   if (!(unchecked_ok || tryblock_throws_ok))
14634     {
14635       /* If there is a surrounding try block that has no matching
14636          clatch clause, report it first. A surrounding try block exits
14637          only if there is something after the list of checked
14638          exception thrown by the current function (if any). */
14639       if (IN_TRY_BLOCK_P ())
14640         parse_error_context (wfl_operator, "Checked exception `%s' can't be caught by any of the catch clause(s) of the surrounding `try' block",
14641                              lang_printable_name (type, 0));
14642       /* If we have no surrounding try statement and the method doesn't have
14643          any throws, report it now. FIXME */
14644
14645       /* We report that the exception can't be throw from a try block
14646          in all circumstances but when the `throw' is inside a static
14647          block. */
14648       else if (!EXCEPTIONS_P (currently_caught_type_list) 
14649                && !tryblock_throws_ok)
14650         {
14651           if (DECL_CLINIT_P (current_function_decl))
14652             parse_error_context (wfl_operator,
14653                    "Checked exception `%s' can't be thrown in initializer",
14654                                  lang_printable_name (type, 0));
14655           else
14656             parse_error_context (wfl_operator,
14657                    "Checked exception `%s' isn't thrown from a `try' block", 
14658                                  lang_printable_name (type, 0));
14659         }
14660       /* Otherwise, the current method doesn't have the appropriate
14661          throws declaration */
14662       else
14663         parse_error_context (wfl_operator, "Checked exception `%s' doesn't match any of current method's `throws' declaration(s)", 
14664                              lang_printable_name (type, 0));
14665       return error_mark_node;
14666     }
14667
14668   if (! flag_emit_class_files && ! flag_emit_xref)
14669     BUILD_THROW (node, expr);
14670
14671   /* If doing xrefs, keep the location where the `throw' was seen. */
14672   if (flag_emit_xref)
14673     EXPR_WFL_LINECOL (node) = EXPR_WFL_LINECOL (wfl_op1);
14674   return node;
14675 }
14676
14677 /* Check that exception said to be thrown by method DECL can be
14678    effectively caught from where DECL is invoked.  */
14679
14680 static void
14681 check_thrown_exceptions (location, decl)
14682      int location;
14683      tree decl;
14684 {
14685   tree throws;
14686   /* For all the unchecked exceptions thrown by DECL */
14687   for (throws = DECL_FUNCTION_THROWS (decl); throws; 
14688        throws = TREE_CHAIN (throws)) 
14689     if (!check_thrown_exceptions_do (TREE_VALUE (throws)))
14690       {
14691 #if 1
14692         /* Temporary hack to suppresses errors about cloning arrays. FIXME */
14693         if (DECL_NAME (decl) == get_identifier ("clone"))
14694           continue;
14695 #endif
14696         EXPR_WFL_LINECOL (wfl_operator) = location;
14697         if (DECL_FINIT_P (current_function_decl))
14698           parse_error_context
14699             (wfl_operator, "Exception `%s' can't be thrown in initializer",
14700              lang_printable_name (TREE_VALUE (throws), 0));
14701         else 
14702           {
14703             parse_error_context 
14704               (wfl_operator, "Exception `%s' must be caught, or it must be declared in the `throws' clause of `%s'", 
14705                lang_printable_name (TREE_VALUE (throws), 0),
14706                (DECL_INIT_P (current_function_decl) ?
14707                 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))) :
14708                 IDENTIFIER_POINTER (DECL_NAME (current_function_decl))));
14709           }
14710       }
14711 }
14712
14713 /* Return 1 if checked EXCEPTION is caught at the current nesting level of
14714    try-catch blocks, OR is listed in the `throws' clause of the
14715    current method.  */
14716
14717 static int
14718 check_thrown_exceptions_do (exception)
14719      tree exception;
14720 {
14721   tree list = currently_caught_type_list;
14722   resolve_and_layout (exception, NULL_TREE);
14723   /* First, all the nested try-catch-finally at that stage. The
14724      last element contains `throws' clause exceptions, if any. */
14725   if (IS_UNCHECKED_EXCEPTION_P (exception))
14726     return 1;
14727   while (list)
14728     {
14729       tree caught;
14730       for (caught = TREE_VALUE (list); caught; caught = TREE_CHAIN (caught))
14731         if (valid_ref_assignconv_cast_p (exception, TREE_VALUE (caught), 0))
14732           return 1;
14733       list = TREE_CHAIN (list);
14734     }
14735   return 0;
14736 }
14737
14738 static void
14739 purge_unchecked_exceptions (mdecl)
14740      tree mdecl;
14741 {
14742   tree throws = DECL_FUNCTION_THROWS (mdecl);
14743   tree new = NULL_TREE;
14744
14745   while (throws)
14746     {
14747       tree next = TREE_CHAIN (throws);
14748       if (!IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (throws)))
14749         {
14750           TREE_CHAIN (throws) = new;
14751           new = throws;
14752         }
14753       throws = next;
14754     }
14755   /* List is inverted here, but it doesn't matter */
14756   DECL_FUNCTION_THROWS (mdecl) = new;
14757 }
14758
14759 /* 15.24 Conditional Operator ?: */
14760
14761 static tree
14762 patch_conditional_expr (node, wfl_cond, wfl_op1)
14763      tree node, wfl_cond, wfl_op1;
14764 {
14765   tree cond = TREE_OPERAND (node, 0);
14766   tree op1 = TREE_OPERAND (node, 1);
14767   tree op2 = TREE_OPERAND (node, 2);
14768   tree resulting_type = NULL_TREE;
14769   tree t1, t2, patched;
14770   int error_found = 0;
14771
14772   /* Operands of ?: might be StringBuffers crafted as a result of a
14773      string concatenation. Obtain a descent operand here.  */
14774   if ((patched = patch_string (op1)))
14775     TREE_OPERAND (node, 1) = op1 = patched;
14776   if ((patched = patch_string (op2)))
14777     TREE_OPERAND (node, 2) = op2 = patched;
14778
14779   t1 = TREE_TYPE (op1);
14780   t2 = TREE_TYPE (op2);
14781
14782   /* The first expression must be a boolean */
14783   if (TREE_TYPE (cond) != boolean_type_node)
14784     {
14785       SET_WFL_OPERATOR (wfl_operator, node, wfl_cond);
14786       parse_error_context (wfl_operator,
14787                "Incompatible type for `?:'. Can't convert `%s' to `boolean'",
14788                            lang_printable_name (TREE_TYPE (cond), 0));
14789       error_found = 1;
14790     }
14791
14792   /* Second and third can be numeric, boolean (i.e. primitive),
14793      references or null. Anything else results in an error */
14794   if (!((JNUMERIC_TYPE_P (t1) && JNUMERIC_TYPE_P (t2))
14795         || ((JREFERENCE_TYPE_P (t1) || op1 == null_pointer_node) 
14796             && (JREFERENCE_TYPE_P (t2) || op2 == null_pointer_node))
14797         || (t1 == boolean_type_node && t2 == boolean_type_node)))
14798     error_found = 1;
14799
14800   /* Determine the type of the conditional expression. Same types are
14801      easy to deal with */
14802   else if (t1 == t2)
14803     resulting_type = t1;
14804
14805   /* There are different rules for numeric types */
14806   else if (JNUMERIC_TYPE_P (t1))
14807     {
14808       /* if byte/short found, the resulting type is short */
14809       if ((t1 == byte_type_node && t2 == short_type_node)
14810           || (t1 == short_type_node && t2 == byte_type_node))
14811         resulting_type = short_type_node;
14812
14813       /* If t1 is a constant int and t2 is of type byte, short or char
14814          and t1's value fits in t2, then the resulting type is t2 */
14815       else if ((t1 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 1)))
14816           && JBSC_TYPE_P (t2) && int_fits_type_p (TREE_OPERAND (node, 1), t2))
14817         resulting_type = t2;
14818
14819       /* If t2 is a constant int and t1 is of type byte, short or char
14820          and t2's value fits in t1, then the resulting type is t1 */
14821       else if ((t2 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 2)))
14822           && JBSC_TYPE_P (t1) && int_fits_type_p (TREE_OPERAND (node, 2), t1))
14823         resulting_type = t1;
14824
14825       /* Otherwise, binary numeric promotion is applied and the
14826          resulting type is the promoted type of operand 1 and 2 */
14827       else 
14828         resulting_type = binary_numeric_promotion (t1, t2, 
14829                                                    &TREE_OPERAND (node, 1), 
14830                                                    &TREE_OPERAND (node, 2));
14831     }
14832
14833   /* Cases of a reference and a null type */
14834   else if (JREFERENCE_TYPE_P (t1) && op2 == null_pointer_node)
14835     resulting_type = t1;
14836
14837   else if (JREFERENCE_TYPE_P (t2) && op1 == null_pointer_node)
14838     resulting_type = t2;
14839
14840   /* Last case: different reference types. If a type can be converted
14841      into the other one by assignment conversion, the latter
14842      determines the type of the expression */
14843   else if ((resulting_type = try_reference_assignconv (t1, op2)))
14844     resulting_type = promote_type (t1);
14845
14846   else if ((resulting_type = try_reference_assignconv (t2, op1)))
14847     resulting_type = promote_type (t2);
14848
14849   /* If we don't have any resulting type, we're in trouble */
14850   if (!resulting_type)
14851     {
14852       char *t = xstrdup (lang_printable_name (t1, 0));
14853       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
14854       parse_error_context (wfl_operator,
14855                  "Incompatible type for `?:'. Can't convert `%s' to `%s'",
14856                            t, lang_printable_name (t2, 0));
14857       free (t);
14858       error_found = 1;
14859     }
14860
14861   if (error_found)
14862     {
14863       TREE_TYPE (node) = error_mark_node;
14864       return error_mark_node;
14865     }
14866
14867   TREE_TYPE (node) = resulting_type;
14868   TREE_SET_CODE (node, COND_EXPR);
14869   CAN_COMPLETE_NORMALLY (node) = 1;
14870   return node;
14871 }
14872
14873 /* Try to constant fold NODE.
14874    If NODE is not a constant expression, return NULL_EXPR.
14875    CONTEXT is a static final VAR_DECL whose initializer we are folding. */
14876
14877 static tree
14878 fold_constant_for_init (node, context)
14879      tree node;
14880      tree context;
14881 {
14882   tree op0, op1, val;
14883   enum tree_code code = TREE_CODE (node);
14884
14885   if (code == STRING_CST || code == INTEGER_CST || code == REAL_CST)
14886     return node;
14887
14888   switch (code)
14889     {
14890     case PLUS_EXPR:
14891     case MINUS_EXPR:
14892     case MULT_EXPR:
14893     case TRUNC_MOD_EXPR:
14894     case RDIV_EXPR:
14895     case LSHIFT_EXPR:
14896     case RSHIFT_EXPR:
14897     case URSHIFT_EXPR:
14898     case BIT_AND_EXPR:
14899     case BIT_XOR_EXPR:
14900     case BIT_IOR_EXPR:
14901     case TRUTH_ANDIF_EXPR:
14902     case TRUTH_ORIF_EXPR:
14903     case EQ_EXPR: 
14904     case NE_EXPR:
14905     case GT_EXPR:
14906     case GE_EXPR:
14907     case LT_EXPR:
14908     case LE_EXPR:
14909       op0 = TREE_OPERAND (node, 0);
14910       op1 = TREE_OPERAND (node, 1);
14911       val = fold_constant_for_init (op0, context);
14912       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14913         return NULL_TREE;
14914       TREE_OPERAND (node, 0) = val;
14915       val = fold_constant_for_init (op1, context);
14916       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14917         return NULL_TREE;
14918       TREE_OPERAND (node, 1) = val;
14919       return patch_binop (node, op0, op1);
14920
14921     case UNARY_PLUS_EXPR:
14922     case NEGATE_EXPR:
14923     case TRUTH_NOT_EXPR:
14924     case BIT_NOT_EXPR:
14925     case CONVERT_EXPR:
14926       op0 = TREE_OPERAND (node, 0);
14927       val = fold_constant_for_init (op0, context);
14928       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14929         return NULL_TREE;
14930       TREE_OPERAND (node, 0) = val;
14931       return patch_unaryop (node, op0);
14932       break;
14933
14934     case COND_EXPR:
14935       val = fold_constant_for_init (TREE_OPERAND (node, 0), context);
14936       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14937         return NULL_TREE;
14938       TREE_OPERAND (node, 0) = val;
14939       val = fold_constant_for_init (TREE_OPERAND (node, 1), context);
14940       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14941         return NULL_TREE;
14942       TREE_OPERAND (node, 1) = val;
14943       val = fold_constant_for_init (TREE_OPERAND (node, 2), context);
14944       if (val == NULL_TREE || ! TREE_CONSTANT (val))
14945         return NULL_TREE;
14946       TREE_OPERAND (node, 2) = val;
14947       return integer_zerop (TREE_OPERAND (node, 0)) ? TREE_OPERAND (node, 1)
14948         : TREE_OPERAND (node, 2);
14949
14950     case VAR_DECL:
14951     case FIELD_DECL:
14952       if (! FIELD_FINAL (node)
14953           || DECL_INITIAL (node) == NULL_TREE)
14954         return NULL_TREE;
14955       val = DECL_INITIAL (node);
14956       /* Guard against infinite recursion. */
14957       DECL_INITIAL (node) = NULL_TREE;
14958       val = fold_constant_for_init (val, node);
14959       DECL_INITIAL (node) = val;
14960       return val;
14961
14962     case EXPR_WITH_FILE_LOCATION:
14963       /* Compare java_complete_tree and resolve_expression_name. */
14964       if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
14965           || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
14966         {
14967           tree name = EXPR_WFL_NODE (node);
14968           tree decl;
14969           if (PRIMARY_P (node))
14970             return NULL_TREE;
14971           else if (! QUALIFIED_P (name))
14972             {
14973               decl = lookup_field_wrapper (DECL_CONTEXT (context), name);
14974               if (decl == NULL_TREE 
14975                   || (! FIELD_STATIC (decl) && ! FIELD_FINAL (decl)))
14976                 return NULL_TREE;
14977               return fold_constant_for_init (decl, decl);
14978             }
14979           else
14980             {
14981               /* Wait until the USE_COMPONENT_REF re-write.  FIXME. */
14982               qualify_ambiguous_name (node);
14983               if (resolve_field_access (node, &decl, NULL)
14984                   && decl != NULL_TREE)
14985                 return fold_constant_for_init (decl, decl);
14986               return NULL_TREE;
14987             }
14988         }
14989       else
14990         {
14991           op0 = TREE_OPERAND (node, 0);
14992           val = fold_constant_for_init (op0, context);
14993           if (val == NULL_TREE || ! TREE_CONSTANT (val))
14994             return NULL_TREE;
14995           TREE_OPERAND (node, 0) = val;
14996           return val;
14997         }
14998
14999 #ifdef USE_COMPONENT_REF
15000     case IDENTIFIER:
15001     case COMPONENT_REF:
15002       ?;
15003 #endif
15004
15005     default:
15006       return NULL_TREE;
15007     }
15008 }
15009
15010 #ifdef USE_COMPONENT_REF
15011 /* Context is 'T' for TypeName, 'P' for PackageName,
15012    'M' for MethodName, 'E' for ExpressionName, and 'A' for AmbiguousName. */
15013
15014 tree
15015 resolve_simple_name (name, context)
15016      tree name;
15017      int context;
15018 {
15019 }
15020
15021 tree
15022 resolve_qualified_name (name, context)
15023      tree name;
15024      int context;
15025 {
15026 }
15027 #endif