OSDN Git Service

1999-12-14 Alexandre Petit-Bianco <apbianco@cygnus.com>
[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 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 PROTO ((int));
75 static void  classitf_redefinition_error PROTO ((const char *,tree, tree, tree));
76 static void  variable_redefinition_error PROTO ((tree, tree, tree, int));
77 static void  check_modifiers PROTO ((const char *, int, int));
78 static tree  create_class PROTO ((int, tree, tree, tree));
79 static tree  create_interface PROTO ((int, tree, tree));
80 static tree  find_field PROTO ((tree, tree));
81 static tree lookup_field_wrapper PROTO ((tree, tree));
82 static int   duplicate_declaration_error_p PROTO ((tree, tree, tree));
83 static void  register_fields PROTO ((int, tree, tree));
84 static tree parser_qualified_classname PROTO ((tree));
85 static int  parser_check_super PROTO ((tree, tree, tree));
86 static int  parser_check_super_interface PROTO ((tree, tree, tree));
87 static void check_modifiers_consistency PROTO ((int));
88 static tree lookup_cl PROTO ((tree));
89 static tree lookup_java_method2 PROTO ((tree, tree, int));
90 static tree method_header PROTO ((int, tree, tree, tree));
91 static void fix_method_argument_names PROTO ((tree ,tree));
92 static tree method_declarator PROTO ((tree, tree));
93 static void parse_warning_context PVPROTO ((tree cl, const char *msg, ...))
94   ATTRIBUTE_PRINTF_2;
95 static void issue_warning_error_from_context PROTO ((tree, const char *msg, va_list));
96 static void parse_ctor_invocation_error PROTO ((void));
97 static tree parse_jdk1_1_error PROTO ((const char *));
98 static void complete_class_report_errors PROTO ((jdep *));
99 static int process_imports PROTO ((void));
100 static void read_import_dir PROTO ((tree));
101 static int find_in_imports_on_demand PROTO ((tree));
102 static int find_in_imports PROTO ((tree));
103 static int check_pkg_class_access PROTO ((tree, tree));
104 static tree resolve_package PROTO ((tree, tree *));
105 static tree lookup_package_type PROTO ((const char *, int));
106 static tree lookup_package_type_and_set_next PROTO ((const char *, int, tree *));
107 static tree resolve_class PROTO ((tree, tree, tree));
108 static void declare_local_variables PROTO ((int, tree, tree));
109 static void source_start_java_method PROTO ((tree));
110 static void source_end_java_method PROTO ((void));
111 static void expand_start_java_method PROTO ((tree));
112 static tree find_name_in_single_imports PROTO ((tree));
113 static void check_abstract_method_header PROTO ((tree));
114 static tree lookup_java_interface_method2 PROTO ((tree, tree));
115 static tree resolve_expression_name PROTO ((tree, tree *));
116 static tree maybe_create_class_interface_decl PROTO ((tree, tree, tree));
117 static int check_class_interface_creation PROTO ((int, int, tree, 
118                                                   tree, tree, tree));
119 static tree patch_method_invocation PROTO ((tree, tree, tree, 
120                                             int *, tree *));
121 static int breakdown_qualified PROTO ((tree *, tree *, tree));
122 static tree resolve_and_layout PROTO ((tree, tree));
123 static tree resolve_no_layout PROTO ((tree, tree));
124 static int invocation_mode PROTO ((tree, int));
125 static tree find_applicable_accessible_methods_list PROTO ((int, tree, 
126                                                             tree, tree));
127 static void search_applicable_methods_list PROTO ((int, tree, tree, tree, 
128                                                    tree *, tree *));
129 static tree find_most_specific_methods_list PROTO ((tree));
130 static int argument_types_convertible PROTO ((tree, tree));
131 static tree patch_invoke PROTO ((tree, tree, tree));
132 static tree lookup_method_invoke PROTO ((int, tree, tree, tree, tree));
133 static tree register_incomplete_type PROTO ((int, tree, tree, tree));
134 static tree obtain_incomplete_type PROTO ((tree));
135 static tree java_complete_lhs PROTO ((tree));
136 static tree java_complete_tree PROTO ((tree));
137 static int java_pre_expand_clinit PROTO ((tree));
138 static void java_complete_expand_method PROTO ((tree));
139 static int  unresolved_type_p PROTO ((tree, tree *));
140 static void create_jdep_list PROTO ((struct parser_ctxt *));
141 static tree build_expr_block PROTO ((tree, tree));
142 static tree enter_block PROTO ((void));
143 static tree enter_a_block PROTO ((tree));
144 static tree exit_block PROTO ((void));
145 static tree lookup_name_in_blocks PROTO ((tree));
146 static void maybe_absorb_scoping_blocks PROTO ((void));
147 static tree build_method_invocation PROTO ((tree, tree));
148 static tree build_new_invocation PROTO ((tree, tree));
149 static tree build_assignment PROTO ((int, int, tree, tree));
150 static tree build_binop PROTO ((enum tree_code, int, tree, tree));
151 static int check_final_assignment PROTO ((tree ,tree));
152 static tree patch_assignment PROTO ((tree, tree, tree ));
153 static tree patch_binop PROTO ((tree, tree, tree));
154 static tree build_unaryop PROTO ((int, int, tree));
155 static tree build_incdec PROTO ((int, int, tree, int));
156 static tree patch_unaryop PROTO ((tree, tree));
157 static tree build_cast PROTO ((int, tree, tree));
158 static tree build_null_of_type PROTO ((tree));
159 static tree patch_cast PROTO ((tree, tree));
160 static int valid_ref_assignconv_cast_p PROTO ((tree, tree, int));
161 static int valid_builtin_assignconv_identity_widening_p PROTO ((tree, tree));
162 static int valid_cast_to_p PROTO ((tree, tree));
163 static int valid_method_invocation_conversion_p PROTO ((tree, tree));
164 static tree try_builtin_assignconv PROTO ((tree, tree, tree));
165 static tree try_reference_assignconv PROTO ((tree, tree));
166 static tree build_unresolved_array_type PROTO ((tree));
167 static tree build_array_from_name PROTO ((tree, tree, tree, tree *));
168 static tree build_array_ref PROTO ((int, tree, tree));
169 static tree patch_array_ref PROTO ((tree));
170 static tree make_qualified_name PROTO ((tree, tree, int));
171 static tree merge_qualified_name PROTO ((tree, tree));
172 static tree make_qualified_primary PROTO ((tree, tree, int));
173 static int resolve_qualified_expression_name PROTO ((tree, tree *, 
174                                                      tree *, tree *));
175 static void qualify_ambiguous_name PROTO ((tree));
176 static void maybe_generate_clinit PROTO ((void));
177 static tree resolve_field_access PROTO ((tree, tree *, tree *));
178 static tree build_newarray_node PROTO ((tree, tree, int));
179 static tree patch_newarray PROTO ((tree));
180 static tree resolve_type_during_patch PROTO ((tree));
181 static tree build_this PROTO ((int));
182 static tree build_return PROTO ((int, tree));
183 static tree patch_return PROTO ((tree));
184 static tree maybe_access_field PROTO ((tree, tree, tree));
185 static int complete_function_arguments PROTO ((tree));
186 static int check_for_static_method_reference PROTO ((tree, tree, tree, tree, tree));
187 static int not_accessible_p PROTO ((tree, tree, int));
188 static void check_deprecation PROTO ((tree, tree));
189 static int class_in_current_package PROTO ((tree));
190 static tree build_if_else_statement PROTO ((int, tree, tree, tree));
191 static tree patch_if_else_statement PROTO ((tree));
192 static tree add_stmt_to_compound PROTO ((tree, tree, tree));
193 static tree add_stmt_to_block PROTO ((tree, tree, tree));
194 static tree patch_exit_expr PROTO ((tree));
195 static tree build_labeled_block PROTO ((int, tree));
196 static tree finish_labeled_statement PROTO ((tree, tree));
197 static tree build_bc_statement PROTO ((int, int, tree));
198 static tree patch_bc_statement PROTO ((tree));
199 static tree patch_loop_statement PROTO ((tree));
200 static tree build_new_loop PROTO ((tree));
201 static tree build_loop_body PROTO ((int, tree, int));
202 static tree finish_loop_body PROTO ((int, tree, tree, int));
203 static tree build_debugable_stmt PROTO ((int, tree));
204 static tree finish_for_loop PROTO ((int, tree, tree, tree));
205 static tree patch_switch_statement PROTO ((tree));
206 static tree string_constant_concatenation PROTO ((tree, tree));
207 static tree build_string_concatenation PROTO ((tree, tree));
208 static tree patch_string_cst PROTO ((tree));
209 static tree patch_string PROTO ((tree));
210 static tree build_try_statement PROTO ((int, tree, tree));
211 static tree build_try_finally_statement PROTO ((int, tree, tree));
212 static tree patch_try_statement PROTO ((tree));
213 static tree patch_synchronized_statement PROTO ((tree, tree));
214 static tree patch_throw_statement PROTO ((tree, tree));
215 static void check_thrown_exceptions PROTO ((int, tree));
216 static int check_thrown_exceptions_do PROTO ((tree));
217 static void purge_unchecked_exceptions PROTO ((tree));
218 static void check_throws_clauses PROTO ((tree, tree, tree));
219 static void finish_method_declaration PROTO ((tree));
220 static tree build_super_invocation PROTO ((tree));
221 static int verify_constructor_circularity PROTO ((tree, tree));
222 static char *constructor_circularity_msg PROTO ((tree, tree));
223 static tree build_this_super_qualified_invocation PROTO ((int, tree, tree,
224                                                           int, int));
225 static const char *get_printable_method_name PROTO ((tree));
226 static tree patch_conditional_expr PROTO ((tree, tree, tree));
227 static void maybe_generate_finit PROTO ((void));
228 static void fix_constructors PROTO ((tree));
229 static int verify_constructor_super PROTO ((void));
230 static tree create_artificial_method PROTO ((tree, int, tree, tree, tree));
231 static void start_artificial_method_body PROTO ((tree));
232 static void end_artificial_method_body PROTO ((tree));
233 static int check_method_redefinition PROTO ((tree, tree));
234 static int reset_method_name PROTO ((tree));
235 static void java_check_regular_methods PROTO ((tree));
236 static void java_check_abstract_methods PROTO ((tree));
237 static tree maybe_build_primttype_type_ref PROTO ((tree, tree));
238 static void unreachable_stmt_error PROTO ((tree));
239 static tree find_expr_with_wfl PROTO ((tree));
240 static void missing_return_error PROTO ((tree));
241 static tree build_new_array_init PROTO ((int, tree));
242 static tree patch_new_array_init PROTO ((tree, tree));
243 static tree maybe_build_array_element_wfl PROTO ((tree));
244 static int array_constructor_check_entry PROTO ((tree, tree));
245 static const char *purify_type_name PROTO ((const char *));
246 static tree fold_constant_for_init PROTO ((tree, tree));
247 static tree strip_out_static_field_access_decl PROTO ((tree));
248 static jdeplist *reverse_jdep_list PROTO ((struct parser_ctxt *));
249 static void static_ref_err PROTO ((tree, tree, tree));
250 static void parser_add_interface PROTO ((tree, tree, tree));
251 static void add_superinterfaces PROTO ((tree, tree));
252 static tree jdep_resolve_class PROTO ((jdep *));
253 static int note_possible_classname PROTO ((const char *, int));
254 static void java_complete_expand_methods PROTO ((void));
255 static void java_expand_finals PROTO ((void));
256 static tree cut_identifier_in_qualified PROTO ((tree));
257 static tree java_stabilize_reference PROTO ((tree));
258 static tree do_unary_numeric_promotion PROTO ((tree));
259 static char * operator_string PROTO ((tree));
260 static tree do_merge_string_cste PROTO ((tree, const char *, int, int));
261 static tree merge_string_cste PROTO ((tree, tree, int));
262 static tree java_refold PROTO ((tree));
263 static int java_decl_equiv PROTO ((tree, tree));
264 static int binop_compound_p PROTO ((enum tree_code));
265 static tree search_loop PROTO ((tree));
266 static int labeled_block_contains_loop_p PROTO ((tree, tree));
267 static void check_abstract_method_definitions PROTO ((int, tree, tree));
268 static void java_check_abstract_method_definitions PROTO ((tree));
269
270 /* Number of error found so far. */
271 int java_error_count; 
272 /* Number of warning found so far. */
273 int java_warning_count;
274 /* Tell when not to fold, when doing xrefs */
275 int do_not_fold;
276
277 /* The current parser context */
278 struct parser_ctxt *ctxp;
279
280 /* List of things that were analyzed for which code will be generated */
281 static struct parser_ctxt *ctxp_for_generation = NULL;
282
283 /* binop_lookup maps token to tree_code. It is used where binary
284    operations are involved and required by the parser. RDIV_EXPR
285    covers both integral/floating point division. The code is changed
286    once the type of both operator is worked out.  */
287
288 static enum tree_code binop_lookup[19] = 
289   { 
290     PLUS_EXPR, MINUS_EXPR, MULT_EXPR, RDIV_EXPR, TRUNC_MOD_EXPR,
291     LSHIFT_EXPR, RSHIFT_EXPR, URSHIFT_EXPR, 
292     BIT_AND_EXPR, BIT_XOR_EXPR, BIT_IOR_EXPR,
293     TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR,
294     EQ_EXPR, NE_EXPR, GT_EXPR, GE_EXPR, LT_EXPR, LE_EXPR,
295    };
296 #define BINOP_LOOKUP(VALUE)                                             \
297   binop_lookup [((VALUE) - PLUS_TK)%                                    \
298                 (sizeof (binop_lookup) / sizeof (binop_lookup[0]))]
299
300 /* This is the end index for binary operators that can also be used
301    in compound assignements. */
302 #define BINOP_COMPOUND_CANDIDATES 11
303
304 /* Fake WFL used to report error message. It is initialized once if
305    needed and reused with it's location information is overriden.  */
306 tree wfl_operator = NULL_TREE;
307
308 /* The "$L" identifier we use to create labels.  */
309 static tree label_id = NULL_TREE;
310
311 /* The "StringBuffer" identifier used for the String `+' operator. */
312 static tree wfl_string_buffer = NULL_TREE; 
313
314 /* The "append" identifier used for String `+' operator.  */
315 static tree wfl_append = NULL_TREE;
316
317 /* The "toString" identifier used for String `+' operator. */
318 static tree wfl_to_string = NULL_TREE;
319
320 /* The "java.lang" import qualified name.  */
321 static tree java_lang_id = NULL_TREE;
322
323 /* The "java.lang.Cloneable" qualified name.  */
324 static tree java_lang_cloneable = NULL_TREE;
325
326 /* Context and flag for static blocks */
327 static tree current_static_block = NULL_TREE;
328
329 %}
330
331 %union {
332   tree node;
333   int sub_token;
334   struct {
335     int token;
336     int location;
337   } operator;
338   int value;
339 }
340
341 %{
342 #include "lex.c"
343 %}
344
345 %pure_parser
346
347 /* Things defined here have to match the order of what's in the
348    binop_lookup table.  */
349
350 %token   PLUS_TK         MINUS_TK        MULT_TK         DIV_TK    REM_TK
351 %token   LS_TK           SRS_TK          ZRS_TK
352 %token   AND_TK          XOR_TK          OR_TK
353 %token   BOOL_AND_TK BOOL_OR_TK 
354 %token   EQ_TK NEQ_TK GT_TK GTE_TK LT_TK LTE_TK
355
356 /* This maps to the same binop_lookup entry than the token above */
357
358 %token   PLUS_ASSIGN_TK  MINUS_ASSIGN_TK MULT_ASSIGN_TK DIV_ASSIGN_TK
359 %token   REM_ASSIGN_TK   
360 %token   LS_ASSIGN_TK    SRS_ASSIGN_TK   ZRS_ASSIGN_TK
361 %token   AND_ASSIGN_TK   XOR_ASSIGN_TK   OR_ASSIGN_TK
362
363
364 /* Modifier TOKEN have to be kept in this order. Don't scramble it */
365
366 %token   PUBLIC_TK       PRIVATE_TK         PROTECTED_TK
367 %token   STATIC_TK       FINAL_TK           SYNCHRONIZED_TK
368 %token   VOLATILE_TK     TRANSIENT_TK       NATIVE_TK
369 %token   PAD_TK          ABSTRACT_TK        MODIFIER_TK
370
371 /* Keep those two in order, too */
372 %token   DECR_TK INCR_TK
373
374 /* From now one, things can be in any order */
375
376 %token   DEFAULT_TK      IF_TK              THROW_TK
377 %token   BOOLEAN_TK      DO_TK              IMPLEMENTS_TK
378 %token   THROWS_TK       BREAK_TK           IMPORT_TK       
379 %token   ELSE_TK         INSTANCEOF_TK      RETURN_TK
380 %token   VOID_TK         CATCH_TK           INTERFACE_TK
381 %token   CASE_TK         EXTENDS_TK         FINALLY_TK
382 %token   SUPER_TK        WHILE_TK           CLASS_TK
383 %token   SWITCH_TK       CONST_TK           TRY_TK
384 %token   FOR_TK          NEW_TK             CONTINUE_TK
385 %token   GOTO_TK         PACKAGE_TK         THIS_TK
386
387 %token   BYTE_TK         SHORT_TK           INT_TK            LONG_TK
388 %token   CHAR_TK         INTEGRAL_TK
389
390 %token   FLOAT_TK        DOUBLE_TK          FP_TK
391
392 %token   ID_TK
393
394 %token   REL_QM_TK         REL_CL_TK NOT_TK  NEG_TK
395
396 %token   ASSIGN_ANY_TK   ASSIGN_TK
397 %token   OP_TK  CP_TK  OCB_TK  CCB_TK  OSB_TK  CSB_TK  SC_TK  C_TK DOT_TK
398
399 %token   STRING_LIT_TK   CHAR_LIT_TK        INT_LIT_TK        FP_LIT_TK
400 %token   TRUE_TK         FALSE_TK           BOOL_LIT_TK       NULL_TK
401
402 %type    <value>        modifiers MODIFIER_TK
403
404 %type    <node>         super ID_TK identifier
405 %type    <node>         name simple_name qualified_name
406 %type    <node>         class_declaration type_declaration compilation_unit
407                         field_declaration method_declaration extends_interfaces
408                         interfaces interface_type_list
409                         interface_declaration class_member_declaration
410                         import_declarations package_declaration 
411                         type_declarations interface_body
412                         interface_member_declaration constant_declaration
413                         interface_member_declarations interface_type
414                         abstract_method_declaration interface_type_list
415 %type    <node>         class_body_declaration class_member_declaration
416                         static_initializer constructor_declaration block
417 %type    <node>         class_body_declarations constructor_header
418 %type    <node>         class_or_interface_type class_type class_type_list
419                         constructor_declarator explicit_constructor_invocation
420 %type    <node>         dim_expr dim_exprs this_or_super throws
421
422 %type    <node>         variable_declarator_id variable_declarator
423                         variable_declarators variable_initializer
424                         variable_initializers constructor_body
425                         array_initializer
426
427 %type    <node>         class_body block_end constructor_block_end
428 %type    <node>         statement statement_without_trailing_substatement
429                         labeled_statement if_then_statement label_decl
430                         if_then_else_statement while_statement for_statement
431                         statement_nsi labeled_statement_nsi do_statement
432                         if_then_else_statement_nsi while_statement_nsi
433                         for_statement_nsi statement_expression_list for_init
434                         for_update statement_expression expression_statement
435                         primary_no_new_array expression primary
436                         array_creation_expression array_type
437                         class_instance_creation_expression field_access
438                         method_invocation array_access something_dot_new
439                         argument_list postfix_expression while_expression 
440                         post_increment_expression post_decrement_expression
441                         unary_expression_not_plus_minus unary_expression
442                         pre_increment_expression pre_decrement_expression
443                         unary_expression_not_plus_minus cast_expression
444                         multiplicative_expression additive_expression
445                         shift_expression relational_expression 
446                         equality_expression and_expression 
447                         exclusive_or_expression inclusive_or_expression
448                         conditional_and_expression conditional_or_expression
449                         conditional_expression assignment_expression
450                         left_hand_side assignment for_header for_begin
451                         constant_expression do_statement_begin empty_statement
452                         switch_statement synchronized_statement throw_statement
453                         try_statement switch_expression switch_block
454                         catches catch_clause catch_clause_parameter finally
455 %type    <node>         return_statement break_statement continue_statement
456
457 %type    <operator>     ASSIGN_TK      MULT_ASSIGN_TK  DIV_ASSIGN_TK  
458 %type    <operator>     REM_ASSIGN_TK  PLUS_ASSIGN_TK  MINUS_ASSIGN_TK
459 %type    <operator>     LS_ASSIGN_TK   SRS_ASSIGN_TK   ZRS_ASSIGN_TK
460 %type    <operator>     AND_ASSIGN_TK  XOR_ASSIGN_TK   OR_ASSIGN_TK
461 %type    <operator>     ASSIGN_ANY_TK  assignment_operator
462 %token   <operator>     EQ_TK GTE_TK ZRS_TK SRS_TK GT_TK LTE_TK LS_TK 
463 %token   <operator>     BOOL_AND_TK AND_TK BOOL_OR_TK OR_TK INCR_TK PLUS_TK
464 %token   <operator>     DECR_TK MINUS_TK MULT_TK DIV_TK XOR_TK REM_TK NEQ_TK
465 %token   <operator>     NEG_TK REL_QM_TK REL_CL_TK NOT_TK LT_TK OCB_TK CCB_TK
466 %token   <operator>     OP_TK OSB_TK DOT_TK THROW_TK INSTANCEOF_TK
467 %type    <operator>     THIS_TK SUPER_TK RETURN_TK BREAK_TK CONTINUE_TK 
468 %type    <operator>     CASE_TK DEFAULT_TK TRY_TK CATCH_TK SYNCHRONIZED_TK
469
470 %type    <node>         method_body 
471         
472 %type    <node>         literal INT_LIT_TK FP_LIT_TK BOOL_LIT_TK CHAR_LIT_TK
473                         STRING_LIT_TK NULL_TK VOID_TK
474
475 %type    <node>         IF_TK WHILE_TK FOR_TK
476
477 %type    <node>         formal_parameter_list formal_parameter
478                         method_declarator method_header
479
480 %type    <node>         primitive_type reference_type type
481                         BOOLEAN_TK INTEGRAL_TK FP_TK
482
483 %%
484 /* 19.2 Production from 2.3: The Syntactic Grammar  */
485 goal:
486         compilation_unit
487                 {}
488 ;
489
490 /* 19.3 Productions from 3: Lexical structure  */
491 literal:
492         INT_LIT_TK
493 |       FP_LIT_TK
494 |       BOOL_LIT_TK
495 |       CHAR_LIT_TK
496 |       STRING_LIT_TK
497 |       NULL_TK
498 ;
499
500 /* 19.4 Productions from 4: Types, Values and Variables  */
501 type:
502         primitive_type
503 |       reference_type
504 ;
505
506 primitive_type:
507         INTEGRAL_TK
508 |       FP_TK
509 |       BOOLEAN_TK
510 ;
511
512 reference_type:
513         class_or_interface_type
514 |       array_type
515 ;
516
517 class_or_interface_type:
518         name
519 ;
520
521 class_type:
522         class_or_interface_type /* Default rule */
523 ;
524
525 interface_type:
526          class_or_interface_type
527 ;
528
529 array_type:
530         primitive_type OSB_TK CSB_TK
531                 { 
532                   $$ = build_java_array_type ($1, -1);
533                   CLASS_LOADED_P ($$) = 1;
534                 }
535 |       name OSB_TK CSB_TK
536                 { $$ = build_unresolved_array_type ($1); }
537 |       array_type OSB_TK CSB_TK
538                 { $$ = build_unresolved_array_type ($1); }
539 |       primitive_type OSB_TK error
540                 {RULE ("']' expected"); RECOVER;}
541 |       array_type OSB_TK error
542                 {RULE ("']' expected"); RECOVER;}
543 ;
544
545 /* 19.5 Productions from 6: Names  */
546 name:
547         simple_name             /* Default rule */
548 |       qualified_name          /* Default rule */
549 ;
550
551 simple_name:
552         identifier              /* Default rule */
553 ;
554
555 qualified_name:
556         name DOT_TK identifier
557                 { $$ = make_qualified_name ($1, $3, $2.location); }
558 ;
559
560 identifier:
561         ID_TK
562 ;
563
564 /* 19.6: Production from 7: Packages  */
565 compilation_unit:
566                 {$$ = NULL;}
567 |       package_declaration
568 |       import_declarations
569 |       type_declarations
570 |       package_declaration import_declarations
571 |       package_declaration type_declarations
572 |       import_declarations type_declarations
573 |       package_declaration import_declarations type_declarations
574 ;
575
576 import_declarations:
577         import_declaration
578                 {
579                   $$ = NULL;
580                 }
581 |       import_declarations import_declaration
582                 {
583                   $$ = NULL;
584                 }
585 ;
586
587 type_declarations:
588         type_declaration
589 |       type_declarations type_declaration
590 ;
591
592 package_declaration:
593         PACKAGE_TK name SC_TK
594                 { ctxp->package = EXPR_WFL_NODE ($2); }
595 |       PACKAGE_TK error
596                 {yyerror ("Missing name"); RECOVER;}
597 |       PACKAGE_TK name error
598                 {yyerror ("';' expected"); RECOVER;}
599 ;
600
601 import_declaration:
602         single_type_import_declaration
603 |       type_import_on_demand_declaration
604 ;
605
606 single_type_import_declaration:
607         IMPORT_TK name SC_TK
608                 {
609                   tree name = EXPR_WFL_NODE ($2), node, last_name;
610                   int   i = IDENTIFIER_LENGTH (name)-1;
611                   const char *last = &IDENTIFIER_POINTER (name)[i];
612                   while (last != IDENTIFIER_POINTER (name))
613                     {
614                       if (last [0] == '.')
615                         break;
616                       last--;
617                     }
618                   last_name = get_identifier (++last);
619                   if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (last_name))
620                     {
621                       tree err = find_name_in_single_imports (last_name);
622                       if (err && err != name)
623                         parse_error_context
624                           ($2, "Ambiguous class: `%s' and `%s'",
625                            IDENTIFIER_POINTER (name), 
626                            IDENTIFIER_POINTER (err));
627                       else
628                         REGISTER_IMPORT ($2, last_name)
629                     }
630                   else
631                     REGISTER_IMPORT ($2, last_name);
632                 }
633 |       IMPORT_TK error
634                 {yyerror ("Missing name"); RECOVER;}
635 |       IMPORT_TK name error
636                 {yyerror ("';' expected"); RECOVER;}
637 ;
638
639 type_import_on_demand_declaration:
640         IMPORT_TK name DOT_TK MULT_TK SC_TK
641                 {
642                   tree name = EXPR_WFL_NODE ($2);
643                   /* Don't import java.lang.* twice. */
644                   if (name != java_lang_id)
645                     {
646                       tree node = build_tree_list ($2, NULL_TREE);
647                       read_import_dir ($2);
648                       TREE_CHAIN (node) = ctxp->import_demand_list;
649                       ctxp->import_demand_list = node;
650                     }
651                 }
652 |       IMPORT_TK name DOT_TK error
653                 {yyerror ("'*' expected"); RECOVER;}
654 |       IMPORT_TK name DOT_TK MULT_TK error
655                 {yyerror ("';' expected"); RECOVER;}
656 ;
657
658 type_declaration:
659         class_declaration
660                 {
661                   maybe_generate_finit ();
662                   maybe_generate_clinit ();
663                   $$ = $1;
664                 }
665 |       interface_declaration
666                 {
667                   maybe_generate_clinit ();
668                   $$ = $1;
669                 }
670 |       SC_TK
671                 { $$ = NULL; }
672 |       error
673                 {
674                   YYERROR_NOW;
675                   yyerror ("Class or interface declaration expected");
676                 }
677 ;
678
679 /* 19.7 Shortened from the original:
680    modifiers: modifier | modifiers modifier
681    modifier: any of public...  */
682 modifiers:
683         MODIFIER_TK
684                 {
685                   $$ = (1 << $1);
686                 }
687 |       modifiers MODIFIER_TK
688                 {
689                   int acc = (1 << $2);
690                   if ($$ & acc)
691                     parse_error_context 
692                       (ctxp->modifier_ctx [$2], "Modifier `%s' declared twice",
693                        java_accstring_lookup (acc));
694                   else
695                     {
696                       $$ |= acc;
697                     }
698                 }
699 ;
700
701 /* 19.8.1 Production from $8.1: Class Declaration */
702 class_declaration:
703         modifiers CLASS_TK identifier super interfaces
704                 { create_class ($1, $3, $4, $5); }
705         class_body
706                 { 
707                   $$ = $7;
708                 }
709 |       CLASS_TK identifier super interfaces 
710                 { create_class (0, $2, $3, $4); }
711         class_body
712                 {       
713                   $$ = $6;
714                 }
715 |       modifiers CLASS_TK error
716                 {yyerror ("Missing class name"); RECOVER;}
717 |       CLASS_TK error
718                 {yyerror ("Missing class name"); RECOVER;}
719 |       CLASS_TK identifier error
720                 {
721                   if (!ctxp->class_err) yyerror ("'{' expected"); 
722                   DRECOVER(class1);
723                 }
724 |       modifiers CLASS_TK identifier error
725                 {if (!ctxp->class_err) yyerror ("'{' expected"); RECOVER;}
726 ;
727
728 super:
729                 { $$ = NULL; }
730 |       EXTENDS_TK class_type
731                 { $$ = $2; }
732 |       EXTENDS_TK class_type error
733                 {yyerror ("'{' expected"); ctxp->class_err=1;}
734 |       EXTENDS_TK error
735                 {yyerror ("Missing super class name"); ctxp->class_err=1;}
736 ;
737
738 interfaces:
739                 { $$ = NULL_TREE; }
740 |       IMPLEMENTS_TK interface_type_list
741                 { $$ = $2; }
742 |       IMPLEMENTS_TK error
743                 {
744                   ctxp->class_err=1;
745                   yyerror ("Missing interface name"); 
746                 }
747 ;
748
749 interface_type_list:
750         interface_type
751                 { 
752                   ctxp->interface_number = 1;
753                   $$ = build_tree_list ($1, NULL_TREE);
754                 }
755 |       interface_type_list C_TK interface_type
756                 { 
757                   ctxp->interface_number++;
758                   $$ = chainon ($1, build_tree_list ($3, NULL_TREE));
759                 }
760 |       interface_type_list C_TK error
761                 {yyerror ("Missing interface name"); RECOVER;}
762 ;
763
764 class_body:
765         OCB_TK CCB_TK
766                 { 
767                   /* Store the location of the `}' when doing xrefs */
768                   if (flag_emit_xref)
769                     DECL_END_SOURCE_LINE (ctxp->current_parsed_class) = 
770                       EXPR_WFL_ADD_COL ($2.location, 1);
771                   $$ = ctxp->current_parsed_class;
772                 }
773 |       OCB_TK class_body_declarations CCB_TK
774                 { 
775                   /* Store the location of the `}' when doing xrefs */
776                   if (flag_emit_xref)
777                     DECL_END_SOURCE_LINE (ctxp->current_parsed_class) = 
778                       EXPR_WFL_ADD_COL ($3.location, 1);
779                   $$ = ctxp->current_parsed_class;
780                 }
781 ;
782
783 class_body_declarations:
784         class_body_declaration
785 |       class_body_declarations class_body_declaration
786 ;
787
788 class_body_declaration:
789         class_member_declaration
790 |       static_initializer
791 |       constructor_declaration
792 |       block                   /* Added, JDK1.1, instance initializer */
793                 { $$ = parse_jdk1_1_error ("instance initializer"); }
794 ;
795
796 class_member_declaration:
797         field_declaration
798 |       field_declaration SC_TK
799                 { $$ = $1; }
800 |       method_declaration
801 |       class_declaration       /* Added, JDK1.1 inner classes */
802                 { $$ = parse_jdk1_1_error ("inner classe declaration"); }
803 |       interface_declaration   /* Added, JDK1.1 inner classes */
804                 { $$ = parse_jdk1_1_error ("inner interface declaration"); }
805 ;
806
807 /* 19.8.2 Productions from 8.3: Field Declarations  */
808 field_declaration:
809         type variable_declarators SC_TK
810                 { register_fields (0, $1, $2); }
811 |       modifiers type variable_declarators SC_TK
812                 {
813                   check_modifiers 
814                     ("Illegal modifier `%s' for field declaration",
815                      $1, FIELD_MODIFIERS);
816                   check_modifiers_consistency ($1);
817                   register_fields ($1, $2, $3);
818                 }
819 ;
820
821 variable_declarators:
822         /* Should we use build_decl_list () instead ? FIXME */
823         variable_declarator     /* Default rule */
824 |       variable_declarators C_TK variable_declarator
825                 { $$ = chainon ($1, $3); }
826 |       variable_declarators C_TK error
827                 {yyerror ("Missing term"); RECOVER;}
828 ;
829
830 variable_declarator:
831         variable_declarator_id
832                 { $$ = build_tree_list ($1, NULL_TREE); }
833 |       variable_declarator_id ASSIGN_TK variable_initializer
834                 { 
835                   if (java_error_count)
836                     $3 = NULL_TREE;
837                   $$ = build_tree_list 
838                     ($1, build_assignment ($2.token, $2.location, $1, $3));
839                 }
840 |       variable_declarator_id ASSIGN_TK error
841                 {
842                   yyerror ("Missing variable initializer");
843                   $$ = build_tree_list ($1, NULL_TREE);
844                   RECOVER;
845                 }
846 |       variable_declarator_id ASSIGN_TK variable_initializer error
847                 {
848                   yyerror ("';' expected");
849                   $$ = build_tree_list ($1, NULL_TREE);
850                   RECOVER;
851                 }
852 ;
853
854 variable_declarator_id:
855         identifier
856 |       variable_declarator_id OSB_TK CSB_TK
857                 { $$ = build_unresolved_array_type ($1); }
858 |       identifier error
859                 {yyerror ("Invalid declaration"); DRECOVER(vdi);}
860 |       variable_declarator_id OSB_TK error
861                 {yyerror ("']' expected"); DRECOVER(vdi);}
862 |       variable_declarator_id CSB_TK error
863                 {yyerror ("Unbalanced ']'"); DRECOVER(vdi);}
864 ;
865
866 variable_initializer:
867         expression
868 |       array_initializer
869 ;
870
871 /* 19.8.3 Productions from 8.4: Method Declarations  */
872 method_declaration:
873         method_header 
874                 {
875                   current_function_decl = $1;
876                   source_start_java_method (current_function_decl);
877                 }
878         method_body
879                 { finish_method_declaration ($3); }
880 |       method_header error
881                 {YYNOT_TWICE yyerror ("'{' expected"); RECOVER;}
882 ;
883
884 method_header:  
885         type method_declarator throws
886                 { $$ = method_header (0, $1, $2, $3); }
887 |       VOID_TK method_declarator throws
888                 { $$ = method_header (0, void_type_node, $2, $3); }
889 |       modifiers type method_declarator throws
890                 { $$ = method_header ($1, $2, $3, $4); }
891 |       modifiers VOID_TK method_declarator throws
892                 { $$ = method_header ($1, void_type_node, $3, $4); }
893 |       type error
894                 {
895                   yyerror ("Invalid method declaration, method name required");
896                   RECOVER;
897                 }
898 |       modifiers type error
899                 {RECOVER;}
900 |       VOID_TK error
901                 {yyerror ("Identifier expected"); RECOVER;}
902 |       modifiers VOID_TK error
903                 {yyerror ("Identifier expected"); RECOVER;}
904 |       modifiers error
905                 {
906                   yyerror ("Invalid method declaration, return type required");
907                   RECOVER;
908                 }
909 ;
910
911 method_declarator:
912         identifier OP_TK CP_TK
913                 { $$ = method_declarator ($1, NULL_TREE); }
914 |       identifier OP_TK formal_parameter_list CP_TK
915                 { $$ = method_declarator ($1, $3); }
916 |       method_declarator OSB_TK CSB_TK
917                 {
918                   EXPR_WFL_LINECOL (wfl_operator) = $2.location;
919                   TREE_PURPOSE ($1) = 
920                     build_unresolved_array_type (TREE_PURPOSE ($1));
921                   parse_warning_context 
922                     (wfl_operator, 
923                      "Discouraged form of returned type specification");
924                 }
925 |       identifier OP_TK error
926                 {yyerror ("')' expected"); DRECOVER(method_declarator);}
927 |       method_declarator OSB_TK error
928                 {yyerror ("']' expected"); RECOVER;}
929 ;
930
931 formal_parameter_list:
932         formal_parameter
933                 {
934                   ctxp->formal_parameter_number = 1;
935                 }
936 |       formal_parameter_list C_TK formal_parameter
937                 {
938                   ctxp->formal_parameter_number += 1;
939                   $$ = chainon ($1, $3);
940                 }
941 |       formal_parameter_list C_TK error
942                 {yyerror ("Missing formal parameter term"); RECOVER;}
943 ;
944
945 formal_parameter:
946         type variable_declarator_id
947                 {
948                   $$ = build_tree_list ($2, $1);
949                 }
950 |       modifiers type variable_declarator_id /* Added, JDK1.1 final parms */
951                 { 
952                   parse_jdk1_1_error ("final parameters");
953                   $$ = build_tree_list ($3, $2);
954                 }
955 |       type error
956                 {yyerror ("Missing identifier"); RECOVER;}
957 |       modifiers type error
958                 {
959                   SOURCE_FRONTEND_DEBUG (("Modifiers: %d", $1));
960                   yyerror ("Missing identifier"); RECOVER;
961                 }
962 ;
963
964 throws:
965                 { $$ = NULL_TREE; }
966 |       THROWS_TK class_type_list
967                 { $$ = $2; }
968 |       THROWS_TK error
969                 {yyerror ("Missing class type term"); RECOVER;}
970 ;
971
972 class_type_list:
973         class_type
974                 { $$ = build_tree_list ($1, $1); }
975 |       class_type_list C_TK class_type
976                 { $$ = tree_cons ($3, $3, $1); }
977 |       class_type_list C_TK error
978                 {yyerror ("Missing class type term"); RECOVER;}
979 ;
980
981 method_body:
982         block
983 |       block SC_TK
984 |       SC_TK
985                 { $$ = NULL_TREE; } /* Probably not the right thing to do. */
986 ;
987
988 /* 19.8.4 Productions from 8.5: Static Initializers  */
989 static_initializer:
990         static block
991                 {
992                   TREE_CHAIN ($2) = ctxp->static_initialized;
993                   ctxp->static_initialized = $2;
994                 }
995 |       static block SC_TK      /* Shouldn't be here. FIXME */
996                 {
997                   TREE_CHAIN ($2) = ctxp->static_initialized;
998                   ctxp->static_initialized = $2;
999                 }
1000 ;
1001
1002 static:                         /* Test lval.sub_token here */
1003         MODIFIER_TK
1004                 {
1005                   SOURCE_FRONTEND_DEBUG (("Modifiers: %d", $1));
1006                 }
1007 ;
1008
1009 /* 19.8.5 Productions from 8.6: Constructor Declarations  */
1010 constructor_declaration:
1011         constructor_header
1012                 {
1013                   current_function_decl = $1;
1014                   source_start_java_method (current_function_decl);
1015                 }
1016         constructor_body
1017                 { finish_method_declaration ($3); }
1018 ;
1019
1020 constructor_header:
1021         constructor_declarator throws
1022                 { $$ = method_header (0, NULL_TREE, $1, $2); }
1023 |       modifiers constructor_declarator throws
1024                 { $$ = method_header ($1, NULL_TREE, $2, $3); }
1025 ;
1026
1027 constructor_declarator:
1028         simple_name OP_TK CP_TK
1029                 { $$ = method_declarator ($1, NULL_TREE); }
1030 |       simple_name OP_TK formal_parameter_list CP_TK
1031                 { $$ = method_declarator ($1, $3); }
1032 ;
1033
1034 constructor_body:
1035         /* Unlike regular method, we always need a complete (empty)
1036            body so we can safely perform all the required code
1037            addition (super invocation and field initialization) */
1038         block_begin constructor_block_end
1039                 { 
1040                   BLOCK_EXPR_BODY ($2) = empty_stmt_node;
1041                   $$ = $2;
1042                 }
1043 |       block_begin explicit_constructor_invocation constructor_block_end
1044                 { $$ = $3; }
1045 |       block_begin block_statements constructor_block_end
1046                 { $$ = $3; }
1047 |       block_begin explicit_constructor_invocation block_statements constructor_block_end
1048                 { $$ = $4; }
1049 ;
1050
1051 constructor_block_end:
1052         block_end
1053 |       block_end SC_TK
1054
1055 /* Error recovery for that rule moved down expression_statement: rule.  */
1056 explicit_constructor_invocation:
1057         this_or_super OP_TK CP_TK SC_TK
1058                 { 
1059                   $$ = build_method_invocation ($1, NULL_TREE); 
1060                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $$);
1061                   $$ = java_method_add_stmt (current_function_decl, $$);
1062                 }
1063 |       this_or_super OP_TK argument_list CP_TK SC_TK
1064                 { 
1065                   $$ = build_method_invocation ($1, $3); 
1066                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $$);
1067                   $$ = java_method_add_stmt (current_function_decl, $$);
1068                 }
1069         /* Added, JDK1.1 inner classes. Modified because the rule
1070            'primary' couldn't work.  */
1071 |       name DOT_TK SUPER_TK OP_TK argument_list CP_TK SC_TK
1072                 {$$ = parse_jdk1_1_error ("explicit constructor invocation"); }
1073 |       name DOT_TK SUPER_TK OP_TK CP_TK SC_TK
1074                 {$$ = parse_jdk1_1_error ("explicit constructor invocation"); }
1075 ;
1076
1077 this_or_super:                  /* Added, simplifies error diagnostics */
1078         THIS_TK
1079                 {
1080                   tree wfl = build_wfl_node (this_identifier_node);
1081                   EXPR_WFL_LINECOL (wfl) = $1.location;
1082                   $$ = wfl;
1083                 }
1084 |       SUPER_TK
1085                 {
1086                   tree wfl = build_wfl_node (super_identifier_node);
1087                   EXPR_WFL_LINECOL (wfl) = $1.location;
1088                   $$ = wfl;
1089                 }
1090 ;
1091
1092 /* 19.9 Productions from 9: Interfaces  */
1093 /* 19.9.1 Productions from 9.1: Interfaces Declarations  */
1094 interface_declaration:
1095         INTERFACE_TK identifier
1096                 { create_interface (0, $2, NULL_TREE); }
1097         interface_body
1098                 {
1099                   $$ = $4;
1100                 }
1101 |       modifiers INTERFACE_TK identifier
1102                 { create_interface ($1, $3, NULL_TREE); }
1103         interface_body
1104                 {
1105                   $$ = $5;
1106                 }
1107 |       INTERFACE_TK identifier extends_interfaces
1108                 { create_interface (0, $2, $3); }
1109         interface_body
1110                 {
1111                   $$ = $5;
1112                 }
1113 |       modifiers INTERFACE_TK identifier extends_interfaces
1114                 { create_interface ($1, $3, $4); }
1115         interface_body
1116                 {
1117                   $$ = $6;
1118                 }
1119 |       INTERFACE_TK identifier error
1120                 {yyerror ("'{' expected"); RECOVER;}
1121 |       modifiers INTERFACE_TK identifier error
1122                 {yyerror ("'{' expected"); RECOVER;}
1123 ;
1124
1125 extends_interfaces:
1126         EXTENDS_TK interface_type
1127                 { 
1128                   ctxp->interface_number = 1;
1129                   $$ = build_tree_list ($2, NULL_TREE);
1130                 }
1131 |       extends_interfaces C_TK interface_type
1132                 { 
1133                   ctxp->interface_number++;
1134                   $$ = chainon ($1, build_tree_list ($3, NULL_TREE));
1135                 }
1136 |       EXTENDS_TK error
1137                 {yyerror ("Invalid interface type"); RECOVER;}
1138 |       extends_interfaces C_TK error
1139                 {yyerror ("Missing term"); RECOVER;}
1140 ;
1141
1142 interface_body:
1143         OCB_TK CCB_TK
1144                 { $$ = NULL_TREE; }
1145 |       OCB_TK interface_member_declarations CCB_TK
1146                 { $$ = NULL_TREE; }
1147 ;
1148
1149 interface_member_declarations:
1150         interface_member_declaration
1151 |       interface_member_declarations interface_member_declaration
1152 ;
1153
1154 interface_member_declaration:
1155         constant_declaration
1156 |       abstract_method_declaration
1157 |       class_declaration       /* Added, JDK1.1 inner classes */
1158                 { $$ = parse_jdk1_1_error ("inner class declaration"); }
1159 |       interface_declaration   /* Added, JDK1.1 inner classes */
1160                 { $$ = parse_jdk1_1_error ("inner interface declaration"); }
1161 ;
1162
1163 constant_declaration:
1164         field_declaration
1165 ;
1166
1167 abstract_method_declaration:
1168         method_header SC_TK
1169                 { 
1170                   check_abstract_method_header ($1);
1171                   current_function_decl = NULL_TREE; /* FIXME ? */
1172                 }
1173 |       method_header error
1174                 {yyerror ("';' expected"); RECOVER;}
1175 ;
1176
1177 /* 19.10 Productions from 10: Arrays  */
1178 array_initializer:
1179         OCB_TK CCB_TK
1180                 { $$ = build_new_array_init ($1.location, NULL_TREE); }
1181 |       OCB_TK variable_initializers CCB_TK
1182                 { $$ = build_new_array_init ($1.location, $2); }
1183 |       OCB_TK variable_initializers C_TK CCB_TK
1184                 { $$ = build_new_array_init ($1.location, $2); }
1185 ;
1186
1187 variable_initializers:
1188         variable_initializer
1189                 { 
1190                   $$ = tree_cons (maybe_build_array_element_wfl ($1), 
1191                                   $1, NULL_TREE);
1192                 }
1193 |       variable_initializers C_TK variable_initializer
1194                 {
1195                   $$ = tree_cons (maybe_build_array_element_wfl ($3), $3, $1);
1196                 }
1197 |       variable_initializers C_TK error
1198                 {yyerror ("Missing term"); RECOVER;}
1199 ;
1200
1201 /* 19.11 Production from 14: Blocks and Statements  */
1202 block:
1203         OCB_TK CCB_TK
1204                 { 
1205                   /* Store the location of the `}' when doing xrefs */
1206                   if (current_function_decl && flag_emit_xref)
1207                     DECL_END_SOURCE_LINE (current_function_decl) = 
1208                       EXPR_WFL_ADD_COL ($2.location, 1);
1209                   $$ = empty_stmt_node; 
1210                 }
1211 |       block_begin block_statements block_end
1212                 { $$ = $3; }
1213 ;
1214
1215 block_begin:
1216         OCB_TK
1217                 { enter_block (); }
1218 ;
1219
1220 block_end:
1221         CCB_TK
1222                 { 
1223                   maybe_absorb_scoping_blocks ();
1224                   /* Store the location of the `}' when doing xrefs */
1225                   if (current_function_decl && flag_emit_xref)
1226                     DECL_END_SOURCE_LINE (current_function_decl) = 
1227                       EXPR_WFL_ADD_COL ($1.location, 1);                  
1228                   $$ = exit_block ();
1229                 }
1230 ;
1231
1232 block_statements:
1233         block_statement
1234 |       block_statements block_statement
1235 ;
1236
1237 block_statement:
1238         local_variable_declaration_statement
1239 |       statement
1240                 { java_method_add_stmt (current_function_decl, $1); }
1241 |       class_declaration       /* Added, JDK1.1 inner classes */
1242                 { parse_jdk1_1_error ("inner class declaration"); }
1243 ;
1244
1245 local_variable_declaration_statement:
1246         local_variable_declaration SC_TK /* Can't catch missing ';' here */
1247 ;
1248
1249 local_variable_declaration:
1250         type variable_declarators
1251                 { declare_local_variables (0, $1, $2); }
1252 |       modifiers type variable_declarators /* Added, JDK1.1 final locals */
1253                 { declare_local_variables ($1, $2, $3); }
1254 ;
1255
1256 statement:
1257         statement_without_trailing_substatement
1258 |       labeled_statement
1259 |       if_then_statement
1260 |       if_then_else_statement
1261 |       while_statement
1262 |       for_statement
1263                 { $$ = exit_block (); }
1264 ;
1265
1266 statement_nsi:
1267         statement_without_trailing_substatement
1268 |       labeled_statement_nsi
1269 |       if_then_else_statement_nsi
1270 |       while_statement_nsi
1271 |       for_statement_nsi
1272                 { $$ = exit_block (); }
1273 ;
1274
1275 statement_without_trailing_substatement:
1276         block
1277 |       empty_statement
1278 |       expression_statement
1279 |       switch_statement
1280 |       do_statement
1281 |       break_statement
1282 |       continue_statement
1283 |       return_statement
1284 |       synchronized_statement
1285 |       throw_statement
1286 |       try_statement
1287 ;
1288
1289 empty_statement:
1290         SC_TK
1291                 { $$ = empty_stmt_node; }
1292 ;
1293
1294 label_decl:
1295         identifier REL_CL_TK
1296                 {
1297                   $$ = build_labeled_block (EXPR_WFL_LINECOL ($1), 
1298                                             EXPR_WFL_NODE ($1));
1299                   pushlevel (2);
1300                   push_labeled_block ($$);
1301                   PUSH_LABELED_BLOCK ($$);
1302                 }
1303 ;
1304
1305 labeled_statement:
1306         label_decl statement
1307                 { $$ = finish_labeled_statement ($1, $2); }
1308 |       identifier error
1309                 {yyerror ("':' expected"); RECOVER;}
1310 ;
1311
1312 labeled_statement_nsi:
1313         label_decl statement_nsi
1314                 { $$ = finish_labeled_statement ($1, $2); }
1315 ;
1316
1317 /* We concentrate here a bunch of error handling rules that we couldn't write
1318    earlier, because expression_statement catches a missing ';'.  */
1319 expression_statement:
1320         statement_expression SC_TK
1321                 {
1322                   /* We have a statement. Generate a WFL around it so
1323                      we can debug it */
1324                   $$ = build_expr_wfl ($1, input_filename, lineno, 0);
1325                   /* We know we have a statement, so set the debug
1326                      info to be eventually generate here. */
1327                   $$ = JAVA_MAYBE_GENERATE_DEBUG_INFO ($$);
1328                 }
1329 |       error SC_TK 
1330                 {
1331                   if (ctxp->prevent_ese != lineno)
1332                     yyerror ("Invalid expression statement");
1333                   DRECOVER (expr_stmt);
1334                 }
1335 |       error OCB_TK
1336                 {
1337                   if (ctxp->prevent_ese != lineno)
1338                     yyerror ("Invalid expression statement");
1339                   DRECOVER (expr_stmt);
1340                 }
1341 |       error CCB_TK
1342                 {
1343                   if (ctxp->prevent_ese != lineno)
1344                     yyerror ("Invalid expression statement");
1345                   DRECOVER (expr_stmt);
1346                 }
1347 |       this_or_super OP_TK error
1348                 {yyerror ("')' expected"); RECOVER;}
1349 |       this_or_super OP_TK CP_TK error
1350                 {
1351                   parse_ctor_invocation_error ();
1352                   RECOVER;
1353                 }
1354 |       this_or_super OP_TK argument_list error
1355                 {yyerror ("')' expected"); RECOVER;}
1356 |       this_or_super OP_TK argument_list CP_TK error
1357                 {
1358                   parse_ctor_invocation_error ();
1359                   RECOVER;
1360                 }
1361 |       name DOT_TK SUPER_TK error
1362                 {yyerror ("'(' expected"); RECOVER;}
1363 |       name DOT_TK SUPER_TK OP_TK error
1364                 {yyerror ("')' expected"); RECOVER;}
1365 |       name DOT_TK SUPER_TK OP_TK argument_list error
1366                 {yyerror ("')' expected"); RECOVER;}
1367 |       name DOT_TK SUPER_TK OP_TK argument_list CP_TK error
1368                 {yyerror ("';' expected"); RECOVER;}
1369 |       name DOT_TK SUPER_TK OP_TK CP_TK error
1370                 {yyerror ("';' expected"); RECOVER;}
1371 ;
1372
1373 statement_expression: 
1374         assignment
1375 |       pre_increment_expression
1376 |       pre_decrement_expression
1377 |       post_increment_expression
1378 |       post_decrement_expression
1379 |       method_invocation
1380 |       class_instance_creation_expression
1381 ;
1382
1383 if_then_statement:
1384         IF_TK OP_TK expression CP_TK statement
1385                 { 
1386                   $$ = build_if_else_statement ($2.location, $3, 
1387                                                 $5, NULL_TREE);
1388                 }
1389 |       IF_TK error
1390                 {yyerror ("'(' expected"); RECOVER;}
1391 |       IF_TK OP_TK error
1392                 {yyerror ("Missing term"); RECOVER;}
1393 |       IF_TK OP_TK expression error
1394                 {yyerror ("')' expected"); RECOVER;}
1395 ;
1396
1397 if_then_else_statement:
1398         IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement
1399                 { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
1400 ;
1401
1402 if_then_else_statement_nsi:
1403         IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement_nsi
1404                 { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
1405 ;
1406
1407 switch_statement:
1408         switch_expression
1409                 {
1410                   enter_block ();
1411                 }
1412         switch_block
1413                 { 
1414                   /* Make into "proper list" of COMPOUND_EXPRs.
1415                      I.e. make the last statment also have its own
1416                      COMPOUND_EXPR. */
1417                   maybe_absorb_scoping_blocks ();
1418                   TREE_OPERAND ($1, 1) = exit_block ();
1419                   $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $1);
1420                 }
1421 ;
1422
1423 switch_expression:
1424         SWITCH_TK OP_TK expression CP_TK
1425                 { 
1426                   $$ = build (SWITCH_EXPR, NULL_TREE, $3, NULL_TREE);
1427                   EXPR_WFL_LINECOL ($$) = $2.location;
1428                 }
1429 |       SWITCH_TK error
1430                 {yyerror ("'(' expected"); RECOVER;}
1431 |       SWITCH_TK OP_TK error
1432                 {yyerror ("Missing term or ')'"); DRECOVER(switch_statement);}
1433 |       SWITCH_TK OP_TK expression CP_TK error
1434                 {yyerror ("'{' expected"); RECOVER;}
1435 ;
1436
1437 /* Default assignment is there to avoid type node on switch_block
1438    node. */
1439
1440 switch_block:
1441         OCB_TK CCB_TK
1442                 { $$ = NULL_TREE; }
1443 |       OCB_TK switch_labels CCB_TK
1444                 { $$ = NULL_TREE; }
1445 |       OCB_TK switch_block_statement_groups CCB_TK
1446                 { $$ = NULL_TREE; }
1447 |       OCB_TK switch_block_statement_groups switch_labels CCB_TK
1448                 { $$ = NULL_TREE; }
1449 ;
1450
1451 switch_block_statement_groups: 
1452         switch_block_statement_group
1453 |       switch_block_statement_groups switch_block_statement_group
1454 ;
1455
1456 switch_block_statement_group:
1457         switch_labels block_statements
1458 ;
1459
1460 switch_labels:
1461         switch_label
1462 |       switch_labels switch_label
1463 ;
1464
1465 switch_label:
1466         CASE_TK constant_expression REL_CL_TK
1467                 { 
1468                   tree lab = build1 (CASE_EXPR, NULL_TREE, $2);
1469                   EXPR_WFL_LINECOL (lab) = $1.location;
1470                   java_method_add_stmt (current_function_decl, lab);
1471                 }
1472 |       DEFAULT_TK REL_CL_TK
1473                 { 
1474                   tree lab = build1 (DEFAULT_EXPR, NULL_TREE, NULL_TREE);
1475                   EXPR_WFL_LINECOL (lab) = $1.location;
1476                   java_method_add_stmt (current_function_decl, lab);
1477                 }
1478 |       CASE_TK error
1479                 {yyerror ("Missing or invalid constant expression"); RECOVER;}
1480 |       CASE_TK constant_expression error
1481                 {yyerror ("':' expected"); RECOVER;}
1482 |       DEFAULT_TK error
1483                 {yyerror ("':' expected"); RECOVER;}
1484 ;
1485
1486 while_expression:
1487         WHILE_TK OP_TK expression CP_TK
1488                 { 
1489                   tree body = build_loop_body ($2.location, $3, 0);
1490                   $$ = build_new_loop (body);
1491                 }
1492 ;
1493
1494 while_statement:
1495         while_expression statement
1496                 { $$ = finish_loop_body (0, NULL_TREE, $2, 0); }
1497 |       WHILE_TK error
1498                 {YYERROR_NOW; yyerror ("'(' expected"); RECOVER;}
1499 |       WHILE_TK OP_TK error
1500                 {yyerror ("Missing term and ')' expected"); RECOVER;}
1501 |       WHILE_TK OP_TK expression error
1502                 {yyerror ("')' expected"); RECOVER;}
1503 ;
1504
1505 while_statement_nsi:
1506         while_expression statement_nsi
1507                 { $$ = finish_loop_body (0, NULL_TREE, $2, 0); }
1508 ;
1509
1510 do_statement_begin:
1511         DO_TK
1512                 { 
1513                   tree body = build_loop_body (0, NULL_TREE, 1);
1514                   $$ = build_new_loop (body);
1515                 }
1516         /* Need error handing here. FIXME */
1517 ;
1518
1519 do_statement: 
1520         do_statement_begin statement WHILE_TK OP_TK expression CP_TK SC_TK
1521                 { $$ = finish_loop_body ($4.location, $5, $2, 1); }
1522 ;
1523
1524 for_statement:
1525         for_begin SC_TK expression SC_TK for_update CP_TK statement
1526                 { $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7); }
1527 |       for_begin SC_TK SC_TK for_update CP_TK statement
1528                 { 
1529                   $$ = finish_for_loop (0, NULL_TREE, $4, $6);
1530                   /* We have not condition, so we get rid of the EXIT_EXPR */
1531                   LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) = 
1532                     empty_stmt_node;
1533                 }
1534 |       for_begin SC_TK error
1535                 {yyerror ("Invalid control expression"); RECOVER;}
1536 |       for_begin SC_TK expression SC_TK error
1537                 {yyerror ("Invalid update expression"); RECOVER;}
1538 |       for_begin SC_TK SC_TK error
1539                 {yyerror ("Invalid update expression"); RECOVER;}
1540 ;
1541
1542 for_statement_nsi:
1543         for_begin SC_TK expression SC_TK for_update CP_TK statement_nsi
1544                 { $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7);}
1545 |       for_begin SC_TK SC_TK for_update CP_TK statement_nsi
1546                 { 
1547                   $$ = finish_for_loop (0, NULL_TREE, $4, $6);
1548                   /* We have not condition, so we get rid of the EXIT_EXPR */
1549                   LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) = 
1550                     empty_stmt_node;
1551                 }
1552 ;
1553
1554 for_header:
1555         FOR_TK OP_TK
1556                 { 
1557                   /* This scope defined for local variable that may be
1558                      defined within the scope of the for loop */
1559                   enter_block (); 
1560                 }
1561 |       FOR_TK error
1562                 {yyerror ("'(' expected"); DRECOVER(for_1);}
1563 |       FOR_TK OP_TK error
1564                 {yyerror ("Invalid init statement"); RECOVER;}
1565 ;
1566
1567 for_begin:
1568         for_header for_init
1569                 { 
1570                   /* We now declare the loop body. The loop is
1571                      declared as a for loop. */
1572                   tree body = build_loop_body (0, NULL_TREE, 0);
1573                   $$ =  build_new_loop (body);
1574                   IS_FOR_LOOP_P ($$) = 1;
1575                   /* The loop is added to the current block the for
1576                      statement is defined within */
1577                   java_method_add_stmt (current_function_decl, $$);
1578                 }
1579 ;
1580 for_init:                       /* Can be empty */
1581                 { $$ = empty_stmt_node; }
1582 |       statement_expression_list
1583                 { 
1584                   /* Init statement recorded within the previously
1585                      defined block scope */
1586                   $$ = java_method_add_stmt (current_function_decl, $1);
1587                 }
1588 |       local_variable_declaration
1589                 { 
1590                   /* Local variable are recorded within the previously
1591                      defined block scope */
1592                   $$ = NULL_TREE;
1593                 }
1594 |       statement_expression_list error
1595                 {yyerror ("';' expected"); DRECOVER(for_init_1);}
1596 ;
1597
1598 for_update:                     /* Can be empty */
1599                 {$$ = empty_stmt_node;}
1600 |       statement_expression_list
1601                 { $$ = build_debugable_stmt (BUILD_LOCATION (), $1); }
1602 ;
1603
1604 statement_expression_list:
1605         statement_expression
1606                 { $$ = add_stmt_to_compound (NULL_TREE, NULL_TREE, $1); }
1607 |       statement_expression_list C_TK statement_expression
1608                 { $$ = add_stmt_to_compound ($1, NULL_TREE, $3); }
1609 |       statement_expression_list C_TK error
1610                 {yyerror ("Missing term"); RECOVER;}
1611 ;
1612
1613 break_statement:
1614         BREAK_TK SC_TK
1615                 { $$ = build_bc_statement ($1.location, 1, NULL_TREE); }
1616 |       BREAK_TK identifier SC_TK
1617                 { $$ = build_bc_statement ($1.location, 1, $2); }
1618 |       BREAK_TK error
1619                 {yyerror ("Missing term"); RECOVER;}
1620 |       BREAK_TK identifier error
1621                 {yyerror ("';' expected"); RECOVER;}
1622 ;
1623
1624 continue_statement:
1625         CONTINUE_TK SC_TK
1626                 { $$ = build_bc_statement ($1.location, 0, NULL_TREE); }
1627 |       CONTINUE_TK identifier SC_TK
1628                 { $$ = build_bc_statement ($1.location, 0, $2); }
1629 |       CONTINUE_TK error
1630                 {yyerror ("Missing term"); RECOVER;}
1631 |       CONTINUE_TK identifier error
1632                 {yyerror ("';' expected"); RECOVER;}
1633 ;
1634
1635 return_statement:
1636         RETURN_TK SC_TK
1637                 { $$ = build_return ($1.location, NULL_TREE); }
1638 |       RETURN_TK expression SC_TK
1639                 { $$ = build_return ($1.location, $2); }
1640 |       RETURN_TK error
1641                 {yyerror ("Missing term"); RECOVER;}
1642 |       RETURN_TK expression error
1643                 {yyerror ("';' expected"); RECOVER;}
1644 ;
1645
1646 throw_statement:
1647         THROW_TK expression SC_TK
1648                 { 
1649                   $$ = build1 (THROW_EXPR, NULL_TREE, $2);
1650                   EXPR_WFL_LINECOL ($$) = $1.location;
1651                 }
1652 |       THROW_TK error
1653                 {yyerror ("Missing term"); RECOVER;}
1654 |       THROW_TK expression error
1655                 {yyerror ("';' expected"); RECOVER;}
1656 ;
1657
1658 synchronized_statement:
1659         synchronized OP_TK expression CP_TK block
1660                 { 
1661                   $$ = build (SYNCHRONIZED_EXPR, NULL_TREE, $3, $5);
1662                   EXPR_WFL_LINECOL ($$) = 
1663                     EXPR_WFL_LINECOL (MODIFIER_WFL (SYNCHRONIZED_TK));
1664                 }
1665 |       synchronized OP_TK expression CP_TK error
1666                 {yyerror ("'{' expected"); RECOVER;}
1667 |       synchronized error
1668                 {yyerror ("'(' expected"); RECOVER;}
1669 |       synchronized OP_TK error CP_TK
1670                 {yyerror ("Missing term"); RECOVER;}
1671 |       synchronized OP_TK error
1672                 {yyerror ("Missing term"); RECOVER;}
1673 ;
1674
1675 synchronized:
1676         modifiers
1677                 {
1678                   check_modifiers ("Illegal modifier `%s'. Only "
1679                                    "`synchronized' was expected here",
1680                                    $1, ACC_SYNCHRONIZED);
1681                   if ($1 != ACC_SYNCHRONIZED)
1682                     MODIFIER_WFL (SYNCHRONIZED_TK) = 
1683                       build_wfl_node (NULL_TREE);
1684                 }
1685 ;
1686
1687 try_statement:
1688         TRY_TK block catches
1689                 { $$ = build_try_statement ($1.location, $2, $3); }
1690 |       TRY_TK block finally
1691                 { $$ = build_try_finally_statement ($1.location, $2, $3); }
1692 |       TRY_TK block catches finally
1693                 { $$ = build_try_finally_statement 
1694                     ($1.location, build_try_statement ($1.location,
1695                                                        $2, $3), $4);
1696                 }
1697 |       TRY_TK error
1698                 {yyerror ("'{' expected"); DRECOVER (try_statement);}
1699 ;
1700
1701 catches:
1702         catch_clause
1703 |       catches catch_clause
1704                 { 
1705                   TREE_CHAIN ($2) = $1;
1706                   $$ = $2;
1707                 }
1708 ;
1709
1710 catch_clause:
1711         catch_clause_parameter block
1712                 { 
1713                   java_method_add_stmt (current_function_decl, $2);
1714                   exit_block ();
1715                   $$ = $1;
1716                 }
1717
1718 catch_clause_parameter:
1719         CATCH_TK OP_TK formal_parameter CP_TK
1720                 { 
1721                   /* We add a block to define a scope for
1722                      formal_parameter (CCBP). The formal parameter is
1723                      declared initialized by the appropriate function
1724                      call */
1725                   tree ccpb = enter_block ();
1726                   tree init = build_assignment (ASSIGN_TK, $2.location, 
1727                                                 TREE_PURPOSE ($3), 
1728                                                 soft_exceptioninfo_call_node);
1729                   declare_local_variables (0, TREE_VALUE ($3),
1730                                            build_tree_list (TREE_PURPOSE ($3),
1731                                                             init));
1732                   $$ = build1 (CATCH_EXPR, NULL_TREE, ccpb);
1733                   EXPR_WFL_LINECOL ($$) = $1.location;
1734                 }
1735 |       CATCH_TK error
1736                 {yyerror ("'(' expected"); RECOVER; $$ = NULL_TREE;}
1737 |       CATCH_TK OP_TK error 
1738                 {
1739                   yyerror ("Missing term or ')' expected"); 
1740                   RECOVER; $$ = NULL_TREE;
1741                 }
1742 |       CATCH_TK OP_TK error CP_TK /* That's for () */
1743                 {yyerror ("Missing term"); RECOVER; $$ = NULL_TREE;}
1744 ;
1745
1746 finally:
1747         FINALLY_TK block
1748                 { $$ = $2; }
1749 |       FINALLY_TK error
1750                 {yyerror ("'{' expected"); RECOVER; }
1751 ;
1752
1753 /* 19.12 Production from 15: Expressions  */
1754 primary:
1755         primary_no_new_array
1756 |       array_creation_expression
1757 ;
1758
1759 primary_no_new_array:
1760         literal
1761 |       THIS_TK
1762                 { $$ = build_this ($1.location); }
1763 |       OP_TK expression CP_TK
1764                 {$$ = $2;}
1765 |       class_instance_creation_expression
1766 |       field_access
1767 |       method_invocation
1768 |       array_access
1769         /* type DOT_TK CLASS_TK doens't work. So we split the rule
1770            'type' into its components. Missing is something for array,
1771            which will complete the reference_type part. FIXME */
1772 |       name DOT_TK CLASS_TK           /* Added, JDK1.1 class literals */
1773                 { $$ = parse_jdk1_1_error ("named class literals"); }
1774 |       primitive_type DOT_TK CLASS_TK /* Added, JDK1.1 class literals */
1775                 { $$ = build_class_ref ($1); }
1776 |       VOID_TK DOT_TK CLASS_TK        /* Added, JDK1.1 class literals */
1777                 { $$ = build_class_ref (void_type_node); }
1778         /* Added, JDK1.1 inner classes. Documentation is wrong
1779            refering to a 'ClassName' (class_name) rule that doesn't
1780            exist. Used name instead.  */
1781 |       name DOT_TK THIS_TK
1782                 { $$ = parse_jdk1_1_error ("class literals"); }
1783 |       OP_TK expression error 
1784                 {yyerror ("')' expected"); RECOVER;}
1785 |       name DOT_TK error
1786                 {yyerror ("'class' or 'this' expected" ); RECOVER;}
1787 |       primitive_type DOT_TK error
1788                 {yyerror ("'class' expected" ); RECOVER;}
1789 |       VOID_TK DOT_TK error
1790                 {yyerror ("'class' expected" ); RECOVER;}
1791 ;
1792
1793 class_instance_creation_expression:
1794         NEW_TK class_type OP_TK argument_list CP_TK
1795                 { $$ = build_new_invocation ($2, $4); }
1796 |       NEW_TK class_type OP_TK CP_TK
1797                 { $$ = build_new_invocation ($2, NULL_TREE); }
1798         /* Added, JDK1.1 inner classes but modified to use
1799            'class_type' instead of 'TypeName' (type_name) mentionned
1800            in the documentation but doesn't exist. */
1801 |       NEW_TK class_type OP_TK argument_list CP_TK class_body
1802                 { $$ = parse_jdk1_1_error ("inner class instance creation"); }
1803 |       NEW_TK class_type OP_TK CP_TK class_body         
1804                 { $$ = parse_jdk1_1_error ("inner class instance creation"); }
1805         /* Added, JDK1.1 inner classes, modified to use name or
1806            primary instead of primary solely which couldn't work in
1807            all situations.  */
1808 |       something_dot_new identifier OP_TK CP_TK
1809 |       something_dot_new identifier OP_TK CP_TK class_body
1810 |       something_dot_new identifier OP_TK argument_list CP_TK
1811 |       something_dot_new identifier OP_TK argument_list CP_TK class_body
1812 |       NEW_TK error SC_TK 
1813                 {yyerror ("'(' expected"); DRECOVER(new_1);}
1814 |       NEW_TK class_type error
1815                 {yyerror ("'(' expected"); RECOVER;}
1816 |       NEW_TK class_type OP_TK error
1817                 {yyerror ("')' or term expected"); RECOVER;}
1818 |       NEW_TK class_type OP_TK argument_list error
1819                 {yyerror ("')' expected"); RECOVER;}
1820 |       something_dot_new error
1821                 {YYERROR_NOW; yyerror ("Identifier expected"); RECOVER;}
1822 |       something_dot_new identifier error
1823                 {yyerror ("'(' expected"); RECOVER;}
1824 ;
1825
1826 something_dot_new:              /* Added, not part of the specs. */
1827         name DOT_TK NEW_TK
1828 |       primary DOT_TK NEW_TK
1829 ;
1830
1831 argument_list:
1832         expression
1833                 { 
1834                   $$ = tree_cons (NULL_TREE, $1, NULL_TREE);
1835                   ctxp->formal_parameter_number = 1; 
1836                 }
1837 |       argument_list C_TK expression
1838                 {
1839                   ctxp->formal_parameter_number += 1;
1840                   $$ = tree_cons (NULL_TREE, $3, $1);
1841                 }
1842 |       argument_list C_TK error
1843                 {yyerror ("Missing term"); RECOVER;}
1844 ;
1845
1846 array_creation_expression:
1847         NEW_TK primitive_type dim_exprs
1848                 { $$ = build_newarray_node ($2, $3, 0); }
1849 |       NEW_TK class_or_interface_type dim_exprs
1850                 { $$ = build_newarray_node ($2, $3, 0); }
1851 |       NEW_TK primitive_type dim_exprs dims
1852                 { $$ = build_newarray_node ($2, $3, CURRENT_OSB (ctxp));}
1853 |       NEW_TK class_or_interface_type dim_exprs dims
1854                 { $$ = build_newarray_node ($2, $3, CURRENT_OSB (ctxp));}
1855         /* Added, JDK1.1 anonymous array. Initial documentation rule
1856            modified */
1857 |       NEW_TK class_or_interface_type dims array_initializer
1858                 { $$ = parse_jdk1_1_error ("anonymous array"); }
1859 |       NEW_TK primitive_type dims array_initializer
1860                 { $$ = parse_jdk1_1_error ("anonymous array"); }
1861 |       NEW_TK error CSB_TK
1862                 {yyerror ("'[' expected"); DRECOVER ("]");}
1863 |       NEW_TK error OSB_TK
1864                 {yyerror ("']' expected"); RECOVER;}
1865 ;
1866
1867 dim_exprs:
1868         dim_expr
1869                 { $$ = build_tree_list (NULL_TREE, $1); }
1870 |       dim_exprs dim_expr
1871                 { $$ = tree_cons (NULL_TREE, $2, $$); }
1872 ;
1873
1874 dim_expr:
1875         OSB_TK expression CSB_TK
1876                 { 
1877                   EXPR_WFL_LINECOL ($2) = $1.location;
1878                   $$ = $2;
1879                 }
1880 |       OSB_TK expression error
1881                 {yyerror ("']' expected"); RECOVER;}
1882 |       OSB_TK error
1883                 {
1884                   yyerror ("Missing term");
1885                   yyerror ("']' expected");
1886                   RECOVER;
1887                 }
1888 ;
1889
1890 dims:                           
1891         OSB_TK CSB_TK
1892                 { 
1893                   int allocate = 0;
1894                   /* If not initialized, allocate memory for the osb
1895                      numbers stack */
1896                   if (!ctxp->osb_limit)
1897                     {
1898                       allocate = ctxp->osb_limit = 32;
1899                       ctxp->osb_depth = -1;
1900                     }
1901                   /* If capacity overflown, reallocate a bigger chuck */
1902                   else if (ctxp->osb_depth+1 == ctxp->osb_limit)
1903                     allocate = ctxp->osb_limit << 1;
1904                   
1905                   if (allocate)
1906                     {
1907                       allocate *= sizeof (int);
1908                       if (ctxp->osb_number)
1909                         ctxp->osb_number = (int *)xrealloc (ctxp->osb_number,
1910                                                             allocate);
1911                       else
1912                         ctxp->osb_number = (int *)xmalloc (allocate);
1913                     }
1914                   ctxp->osb_depth++;
1915                   CURRENT_OSB (ctxp) = 1;
1916                 }
1917 |       dims OSB_TK CSB_TK
1918                 { CURRENT_OSB (ctxp)++; }
1919 |       dims OSB_TK error
1920                 { yyerror ("']' expected"); RECOVER;}
1921 ;
1922
1923 field_access:
1924         primary DOT_TK identifier
1925                 { $$ = make_qualified_primary ($1, $3, $2.location); }
1926                 /*  FIXME - REWRITE TO: 
1927                 { $$ = build_binop (COMPONENT_REF, $2.location, $1, $3); } */
1928 |       SUPER_TK DOT_TK identifier
1929                 {
1930                   tree super_wfl = 
1931                     build_wfl_node (super_identifier_node);
1932                   EXPR_WFL_LINECOL (super_wfl) = $1.location;
1933                   $$ = make_qualified_name (super_wfl, $3, $2.location);
1934                 }
1935 |       SUPER_TK error
1936                 {yyerror ("Field expected"); DRECOVER (super_field_acces);}
1937 ;
1938
1939 method_invocation:
1940         name OP_TK CP_TK
1941                 { $$ = build_method_invocation ($1, NULL_TREE); }
1942 |       name OP_TK argument_list CP_TK
1943                 { $$ = build_method_invocation ($1, $3); }
1944 |       primary DOT_TK identifier OP_TK CP_TK
1945                 { 
1946                   if (TREE_CODE ($1) == THIS_EXPR)
1947                     $$ = build_this_super_qualified_invocation 
1948                       (1, $3, NULL_TREE, 0, $2.location);
1949                   else
1950                     {
1951                       tree invok = build_method_invocation ($3, NULL_TREE);
1952                       $$ = make_qualified_primary ($1, invok, $2.location);
1953                     }
1954                 }
1955 |       primary DOT_TK identifier OP_TK argument_list CP_TK
1956                 { 
1957                   if (TREE_CODE ($1) == THIS_EXPR)
1958                     $$ = build_this_super_qualified_invocation 
1959                       (1, $3, $5, 0, $2.location);
1960                   else
1961                     {
1962                       tree invok = build_method_invocation ($3, $5);
1963                       $$ = make_qualified_primary ($1, invok, $2.location);
1964                     }
1965                 }
1966 |       SUPER_TK DOT_TK identifier OP_TK CP_TK
1967                 { 
1968                   $$ = build_this_super_qualified_invocation 
1969                     (0, $3, NULL_TREE, $1.location, $2.location);
1970                 }
1971 |       SUPER_TK DOT_TK identifier OP_TK argument_list CP_TK
1972                 {
1973                   $$ = build_this_super_qualified_invocation 
1974                     (0, $3, $5, $1.location, $2.location);
1975                 }
1976         /* Screws up thing. I let it here until I'm convinced it can
1977            be removed. FIXME
1978 |       primary DOT_TK error
1979                 {yyerror ("'(' expected"); DRECOVER(bad);} */
1980 |       SUPER_TK DOT_TK error CP_TK
1981                 { yyerror ("'(' expected"); DRECOVER (method_invocation); }
1982 |       SUPER_TK DOT_TK error DOT_TK
1983                 { yyerror ("'(' expected"); DRECOVER (method_invocation); }
1984 ;
1985
1986 array_access:
1987         name OSB_TK expression CSB_TK
1988                 { $$ = build_array_ref ($2.location, $1, $3); }
1989 |       primary_no_new_array OSB_TK expression CSB_TK
1990                 { $$ = build_array_ref ($2.location, $1, $3); }
1991 |       name OSB_TK error
1992                 {
1993                   yyerror ("Missing term and ']' expected");
1994                   DRECOVER(array_access);
1995                 }
1996 |       name OSB_TK expression error
1997                 {
1998                   yyerror ("']' expected");
1999                   DRECOVER(array_access);
2000                 }
2001 |       primary_no_new_array OSB_TK error
2002                 {
2003                   yyerror ("Missing term and ']' expected");
2004                   DRECOVER(array_access);
2005                 }
2006 |       primary_no_new_array OSB_TK expression error
2007                 {
2008                   yyerror ("']' expected");
2009                   DRECOVER(array_access);
2010                 }
2011 ;
2012
2013 postfix_expression:
2014         primary
2015 |       name
2016 |       post_increment_expression
2017 |       post_decrement_expression
2018 ;
2019
2020 post_increment_expression:
2021         postfix_expression INCR_TK
2022                 { $$ = build_incdec ($2.token, $2.location, $1, 1); }
2023 ;
2024
2025 post_decrement_expression:
2026         postfix_expression DECR_TK
2027                 { $$ = build_incdec ($2.token, $2.location, $1, 1); }
2028 ;
2029
2030 unary_expression:
2031         pre_increment_expression
2032 |       pre_decrement_expression
2033 |       PLUS_TK unary_expression
2034                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2035 |       MINUS_TK unary_expression
2036                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2037 |       unary_expression_not_plus_minus
2038 |       PLUS_TK error
2039                 {yyerror ("Missing term"); RECOVER}
2040 |       MINUS_TK error
2041                 {yyerror ("Missing term"); RECOVER}
2042 ;
2043
2044 pre_increment_expression:
2045         INCR_TK unary_expression
2046                 {$$ = build_incdec ($1.token, $1.location, $2, 0); }
2047 |       INCR_TK error
2048                 {yyerror ("Missing term"); RECOVER}
2049 ;
2050
2051 pre_decrement_expression:
2052         DECR_TK unary_expression
2053                 {$$ = build_incdec ($1.token, $1.location, $2, 0); }
2054 |       DECR_TK error
2055                 {yyerror ("Missing term"); RECOVER}
2056 ;
2057
2058 unary_expression_not_plus_minus:
2059         postfix_expression
2060 |       NOT_TK unary_expression
2061                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2062 |       NEG_TK unary_expression
2063                 {$$ = build_unaryop ($1.token, $1.location, $2); }
2064 |       cast_expression
2065 |       NOT_TK error
2066                 {yyerror ("Missing term"); RECOVER}
2067 |       NEG_TK error
2068                 {yyerror ("Missing term"); RECOVER}
2069 ;
2070
2071 cast_expression:                /* Error handling here is potentially weak */
2072         OP_TK primitive_type dims CP_TK unary_expression
2073                 { 
2074                   tree type = $2;
2075                   while (CURRENT_OSB (ctxp)--)
2076                     type = build_java_array_type (type, -1);
2077                   ctxp->osb_depth--;
2078                   $$ = build_cast ($1.location, type, $5); 
2079                 }
2080 |       OP_TK primitive_type CP_TK unary_expression
2081                 { $$ = build_cast ($1.location, $2, $4); }
2082 |       OP_TK expression CP_TK unary_expression_not_plus_minus
2083                 { $$ = build_cast ($1.location, $2, $4); }
2084 |       OP_TK name dims CP_TK unary_expression_not_plus_minus
2085                 { 
2086                   const char *ptr;
2087                   while (CURRENT_OSB (ctxp)--)
2088                     obstack_1grow (&temporary_obstack, '[');
2089                   ctxp->osb_depth--;
2090                   obstack_grow0 (&temporary_obstack, 
2091                                  IDENTIFIER_POINTER (EXPR_WFL_NODE ($2)),
2092                                  IDENTIFIER_LENGTH (EXPR_WFL_NODE ($2)));
2093                   ptr = obstack_finish (&temporary_obstack);
2094                   EXPR_WFL_NODE ($2) = get_identifier (ptr);
2095                   $$ = build_cast ($1.location, $2, $5);
2096                 }
2097 |       OP_TK primitive_type OSB_TK error
2098                 {yyerror ("']' expected, invalid type expression");}
2099 |       OP_TK error
2100                 {
2101                   if (ctxp->prevent_ese != lineno)
2102                     yyerror ("Invalid type expression"); RECOVER;
2103                   RECOVER;
2104                 }
2105 |       OP_TK primitive_type dims CP_TK error
2106                 {yyerror ("Missing term"); RECOVER;}
2107 |       OP_TK primitive_type CP_TK error
2108                 {yyerror ("Missing term"); RECOVER;}
2109 |       OP_TK name dims CP_TK error
2110                 {yyerror ("Missing term"); RECOVER;}
2111 ;
2112
2113 multiplicative_expression:
2114         unary_expression
2115 |       multiplicative_expression MULT_TK unary_expression
2116                 { 
2117                   $$ = build_binop (BINOP_LOOKUP ($2.token), 
2118                                     $2.location, $1, $3);
2119                 }
2120 |       multiplicative_expression DIV_TK unary_expression
2121                 {
2122                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2123                                     $1, $3); 
2124                 }
2125 |       multiplicative_expression REM_TK unary_expression
2126                 {
2127                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2128                                     $1, $3); 
2129                 }
2130 |       multiplicative_expression MULT_TK error
2131                 {yyerror ("Missing term"); RECOVER;}
2132 |       multiplicative_expression DIV_TK error
2133                 {yyerror ("Missing term"); RECOVER;}
2134 |       multiplicative_expression REM_TK error
2135                 {yyerror ("Missing term"); RECOVER;}
2136 ;
2137
2138 additive_expression:
2139         multiplicative_expression
2140 |       additive_expression PLUS_TK multiplicative_expression
2141                 {
2142                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2143                                     $1, $3); 
2144                 }
2145 |       additive_expression MINUS_TK multiplicative_expression
2146                 {
2147                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2148                                     $1, $3); 
2149                 }
2150 |       additive_expression PLUS_TK error
2151                 {yyerror ("Missing term"); RECOVER;}
2152 |       additive_expression MINUS_TK error
2153                 {yyerror ("Missing term"); RECOVER;}
2154 ;
2155
2156 shift_expression:
2157         additive_expression
2158 |       shift_expression LS_TK additive_expression
2159                 {
2160                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2161                                     $1, $3); 
2162                 }
2163 |       shift_expression SRS_TK additive_expression
2164                 {
2165                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2166                                     $1, $3); 
2167                 }
2168 |       shift_expression ZRS_TK additive_expression
2169                 {
2170                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2171                                     $1, $3); 
2172                 }
2173 |       shift_expression LS_TK error
2174                 {yyerror ("Missing term"); RECOVER;}
2175 |       shift_expression SRS_TK error
2176                 {yyerror ("Missing term"); RECOVER;}
2177 |       shift_expression ZRS_TK error
2178                 {yyerror ("Missing term"); RECOVER;}
2179 ;
2180
2181 relational_expression:
2182         shift_expression
2183 |       relational_expression LT_TK shift_expression
2184                 {
2185                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2186                                     $1, $3); 
2187                 }
2188 |       relational_expression GT_TK shift_expression
2189                 {
2190                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2191                                     $1, $3); 
2192                 }
2193 |       relational_expression LTE_TK shift_expression
2194                 {
2195                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2196                                     $1, $3); 
2197                 }
2198 |       relational_expression GTE_TK shift_expression
2199                 {
2200                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2201                                     $1, $3); 
2202                 }
2203 |       relational_expression INSTANCEOF_TK reference_type
2204                 { $$ = build_binop (INSTANCEOF_EXPR, $2.location, $1, $3); }
2205 |       relational_expression LT_TK error
2206                 {yyerror ("Missing term"); RECOVER;}
2207 |       relational_expression GT_TK error
2208                 {yyerror ("Missing term"); RECOVER;}
2209 |       relational_expression LTE_TK error
2210                 {yyerror ("Missing term"); RECOVER;}
2211 |       relational_expression GTE_TK error
2212                 {yyerror ("Missing term"); RECOVER;}
2213 |       relational_expression INSTANCEOF_TK error
2214                 {yyerror ("Invalid reference type"); RECOVER;}
2215 ;
2216
2217 equality_expression:
2218         relational_expression
2219 |       equality_expression EQ_TK relational_expression
2220                 {
2221                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2222                                     $1, $3); 
2223                 }
2224 |       equality_expression NEQ_TK relational_expression
2225                 {
2226                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2227                                     $1, $3); 
2228                 }
2229 |       equality_expression EQ_TK error
2230                 {yyerror ("Missing term"); RECOVER;}
2231 |       equality_expression NEQ_TK error
2232                 {yyerror ("Missing term"); RECOVER;}
2233 ;
2234
2235 and_expression:
2236         equality_expression
2237 |       and_expression AND_TK equality_expression
2238                 {
2239                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2240                                     $1, $3); 
2241                 }
2242 |       and_expression AND_TK error
2243                 {yyerror ("Missing term"); RECOVER;}
2244 ;
2245
2246 exclusive_or_expression:
2247         and_expression
2248 |       exclusive_or_expression XOR_TK and_expression
2249                 {
2250                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2251                                     $1, $3); 
2252                 }
2253 |       exclusive_or_expression XOR_TK error
2254                 {yyerror ("Missing term"); RECOVER;}
2255 ;
2256
2257 inclusive_or_expression:
2258         exclusive_or_expression
2259 |       inclusive_or_expression OR_TK exclusive_or_expression
2260                 {
2261                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2262                                     $1, $3); 
2263                 }
2264 |       inclusive_or_expression OR_TK error
2265                 {yyerror ("Missing term"); RECOVER;}
2266 ;
2267
2268 conditional_and_expression:
2269         inclusive_or_expression
2270 |       conditional_and_expression BOOL_AND_TK inclusive_or_expression
2271                 {
2272                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2273                                     $1, $3); 
2274                 }
2275 |       conditional_and_expression BOOL_AND_TK error
2276                 {yyerror ("Missing term"); RECOVER;}
2277 ;
2278
2279 conditional_or_expression:
2280         conditional_and_expression
2281 |       conditional_or_expression BOOL_OR_TK conditional_and_expression
2282                 {
2283                   $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2284                                     $1, $3); 
2285                 }
2286 |       conditional_or_expression BOOL_OR_TK error
2287                 {yyerror ("Missing term"); RECOVER;}
2288 ;
2289
2290 conditional_expression:         /* Error handling here is weak */
2291         conditional_or_expression
2292 |       conditional_or_expression REL_QM_TK expression REL_CL_TK conditional_expression
2293                 {
2294                   $$ = build (CONDITIONAL_EXPR, NULL_TREE, $1, $3, $5);
2295                   EXPR_WFL_LINECOL ($$) = $2.location;
2296                 }
2297 |       conditional_or_expression REL_QM_TK REL_CL_TK error
2298                 {
2299                   YYERROR_NOW;
2300                   yyerror ("Missing term");
2301                   DRECOVER (1);
2302                 }
2303 |       conditional_or_expression REL_QM_TK error
2304                 {yyerror ("Missing term"); DRECOVER (2);}
2305 |       conditional_or_expression REL_QM_TK expression REL_CL_TK error
2306                 {yyerror ("Missing term"); DRECOVER (3);}
2307 ;
2308
2309 assignment_expression:
2310         conditional_expression
2311 |       assignment
2312 ;
2313
2314 assignment:
2315         left_hand_side assignment_operator assignment_expression
2316                 { $$ = build_assignment ($2.token, $2.location, $1, $3); }
2317 |       left_hand_side assignment_operator error
2318                 {
2319                   if (ctxp->prevent_ese != lineno)
2320                     yyerror ("Missing term");
2321                   DRECOVER (assign);
2322                 }
2323 ;
2324
2325 left_hand_side:
2326         name
2327 |       field_access
2328 |       array_access
2329 ;
2330
2331 assignment_operator:
2332         ASSIGN_ANY_TK
2333 |       ASSIGN_TK
2334 ;
2335
2336 expression:
2337         assignment_expression
2338 ;
2339
2340 constant_expression:
2341         expression
2342 ;
2343
2344 %%
2345 \f
2346
2347 /* Flag for the error report routine to issue the error the first time
2348    it's called (overriding the default behavior which is to drop the
2349    first invocation and honor the second one, taking advantage of a
2350    richer context.  */
2351 static int force_error = 0;
2352
2353 /* Create a new parser context and make it the current one. */
2354
2355 void
2356 java_push_parser_context ()
2357 {
2358   struct parser_ctxt *new = 
2359     (struct parser_ctxt *)xmalloc(sizeof (struct parser_ctxt));
2360
2361   bzero ((PTR) new, sizeof (struct parser_ctxt));
2362   new->next = ctxp;
2363   ctxp = new;
2364   if (ctxp->next)
2365     {
2366       ctxp->incomplete_class = ctxp->next->incomplete_class;
2367       ctxp->gclass_list = ctxp->next->gclass_list;
2368     }
2369 }  
2370
2371 /* If the first file of a file list was a class file, no context
2372    exists for a source file to be parsed. This boolean remembers that
2373    java_parser_context_save_global might have created a dummy one, so
2374    that java_parser_context_restore_global can pop it.  */
2375 static int extra_ctxp_pushed_p = 0;
2376
2377 void
2378 java_parser_context_save_global ()
2379 {
2380   if (!ctxp)
2381     {
2382       java_push_parser_context ();
2383       extra_ctxp_pushed_p = 1;
2384     }
2385   ctxp->finput = finput;
2386   ctxp->lineno = lineno;
2387   ctxp->current_class = current_class;
2388   ctxp->filename = input_filename;
2389   ctxp->current_function_decl = current_function_decl;
2390 }
2391
2392 void
2393 java_parser_context_restore_global ()
2394 {
2395   finput = ctxp->finput;
2396   lineno = ctxp->lineno;
2397   current_class = ctxp->current_class;
2398   input_filename = ctxp->filename;
2399   current_function_decl = ctxp->current_function_decl;
2400   if (!ctxp->next && extra_ctxp_pushed_p)
2401     {
2402       java_pop_parser_context (0);
2403       extra_ctxp_pushed_p = 0;
2404     }
2405 }
2406
2407 void 
2408 java_pop_parser_context (generate)
2409      int generate;
2410 {
2411   tree current;
2412   struct parser_ctxt *toFree, *next;
2413
2414   if (!ctxp)
2415     return;
2416
2417   toFree = ctxp;
2418   next = ctxp->next;
2419   if (next)
2420     {
2421       next->incomplete_class = ctxp->incomplete_class;
2422       next->gclass_list = ctxp->gclass_list;
2423       lineno = ctxp->lineno;
2424       finput = ctxp->finput;
2425       current_class = ctxp->current_class;
2426     }
2427
2428   /* Set the single import class file flag to 0 for the current list
2429      of imported things */
2430   for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
2431     IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_PURPOSE (current)) = 0;
2432
2433   /* And restore those of the previous context */
2434   if ((ctxp = next))            /* Assignment is really meant here */
2435     for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
2436       IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_PURPOSE (current)) = 1;
2437
2438   if (generate)
2439     {
2440       toFree->next = ctxp_for_generation;
2441       ctxp_for_generation = toFree;
2442     }
2443   else
2444     free (toFree);
2445 }
2446
2447 /* Reporting an constructor invocation error.  */
2448 static void
2449 parse_ctor_invocation_error ()
2450 {
2451   if (DECL_CONSTRUCTOR_P (current_function_decl))
2452     yyerror ("Constructor invocation must be first thing in a constructor"); 
2453   else
2454     yyerror ("Only constructors can invoke constructors");
2455 }
2456
2457 /* Reporting JDK1.1 features not implemented.  */
2458
2459 static tree
2460 parse_jdk1_1_error (msg)
2461     const char *msg;
2462 {
2463   sorry (": `%s' JDK1.1(TM) feature", msg);
2464   java_error_count++;
2465   return empty_stmt_node;
2466 }
2467
2468 static int do_warning = 0;
2469
2470 void
2471 yyerror (msg)
2472      const char *msg;
2473 {
2474   static java_lc elc;
2475   static int  prev_lineno;
2476   static const char *prev_msg;
2477
2478   int save_lineno;
2479   char *remainder, *code_from_source;
2480   extern struct obstack temporary_obstack;
2481   
2482   if (!force_error && prev_lineno == lineno)
2483     return;
2484
2485   /* Save current error location but report latter, when the context is
2486      richer.  */
2487   if (ctxp->java_error_flag == 0)
2488     {
2489       ctxp->java_error_flag = 1;
2490       elc = ctxp->elc;
2491       /* Do something to use the previous line if we're reaching the
2492          end of the file... */
2493 #ifdef VERBOSE_SKELETON
2494       printf ("* Error detected (%s)\n", (msg ? msg : "(null)"));
2495 #endif
2496       return;
2497     }
2498
2499   /* Ignore duplicate message on the same line. BTW, this is dubious. FIXME */
2500   if (!force_error && msg == prev_msg && prev_lineno == elc.line)
2501     return;
2502
2503   ctxp->java_error_flag = 0;
2504   if (do_warning)
2505     java_warning_count++;
2506   else
2507     java_error_count++;
2508   
2509   if (elc.col == 0 && msg[1] == ';')
2510     {
2511       elc.col  = ctxp->p_line->char_col-1;
2512       elc.line = ctxp->p_line->lineno;
2513     }
2514
2515   save_lineno = lineno;
2516   prev_lineno = lineno = elc.line;
2517   prev_msg = msg;
2518
2519   code_from_source = java_get_line_col (ctxp->filename, elc.line, elc.col);
2520   obstack_grow0 (&temporary_obstack, 
2521                  code_from_source, strlen (code_from_source));
2522   remainder = obstack_finish (&temporary_obstack);
2523   if (do_warning)
2524     warning ("%s.\n%s", msg, remainder);
2525   else
2526     error ("%s.\n%s", msg, remainder);
2527
2528   /* This allow us to cheaply avoid an extra 'Invalid expression
2529      statement' error report when errors have been already reported on
2530      the same line. This occurs when we report an error but don't have
2531      a synchronization point other than ';', which
2532      expression_statement is the only one to take care of.  */
2533   ctxp->prevent_ese = lineno = save_lineno;
2534 }
2535
2536 static void
2537 issue_warning_error_from_context (cl, msg, ap)
2538      tree cl;
2539      const char *msg;
2540      va_list ap;
2541 {
2542   char *saved, *saved_input_filename;
2543   char buffer [4096];
2544   vsprintf (buffer, msg, ap);
2545   force_error = 1;
2546
2547   ctxp->elc.line = EXPR_WFL_LINENO (cl);
2548   ctxp->elc.col  = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 : 
2549                     (EXPR_WFL_COLNO (cl) == 0xffe ? -2 : EXPR_WFL_COLNO (cl)));
2550
2551   /* We have a CL, that's a good reason for using it if it contains data */
2552   saved = ctxp->filename;
2553   if (TREE_CODE (cl) == EXPR_WITH_FILE_LOCATION && EXPR_WFL_FILENAME_NODE (cl))
2554     ctxp->filename = EXPR_WFL_FILENAME (cl);
2555   saved_input_filename = input_filename;
2556   input_filename = ctxp->filename;
2557   java_error (NULL);
2558   java_error (buffer);
2559   ctxp->filename = saved;
2560   input_filename = saved_input_filename;
2561   force_error = 0;
2562 }
2563
2564 /* Issue an error message at a current source line CL */
2565
2566 void
2567 parse_error_context VPROTO ((tree cl, const char *msg, ...))
2568 {
2569 #ifndef ANSI_PROTOTYPES
2570   tree cl;
2571   const char *msg;
2572 #endif
2573   va_list ap;
2574
2575   VA_START (ap, msg);
2576 #ifndef ANSI_PROTOTYPES
2577   cl = va_arg (ap, tree);
2578   msg = va_arg (ap, const char *);
2579 #endif
2580   issue_warning_error_from_context (cl, msg, ap);
2581   va_end (ap);
2582 }
2583
2584 /* Issue a warning at a current source line CL */
2585
2586 static void
2587 parse_warning_context VPROTO ((tree cl, const char *msg, ...))
2588 {
2589 #ifndef ANSI_PROTOTYPES
2590   tree cl;
2591   const char *msg;
2592 #endif
2593   va_list ap;
2594
2595   VA_START (ap, msg);
2596 #ifndef ANSI_PROTOTYPES
2597   cl = va_arg (ap, tree);
2598   msg = va_arg (ap, const char *);
2599 #endif
2600
2601   force_error = do_warning = 1;
2602   issue_warning_error_from_context (cl, msg, ap);
2603   do_warning = force_error = 0;
2604   va_end (ap);
2605 }
2606
2607 static tree
2608 find_expr_with_wfl (node)
2609      tree node;
2610 {
2611   while (node)
2612     {
2613       char code;
2614       tree to_return;
2615
2616       switch (TREE_CODE (node))
2617         {
2618         case BLOCK:
2619           node = BLOCK_EXPR_BODY (node);
2620           continue;
2621
2622         case COMPOUND_EXPR:
2623           to_return = find_expr_with_wfl (TREE_OPERAND (node, 0));
2624           if (to_return)
2625             return to_return;
2626           node = TREE_OPERAND (node, 1);
2627           continue;
2628
2629         case LOOP_EXPR:
2630           node = TREE_OPERAND (node, 0);
2631           continue;
2632           
2633         case LABELED_BLOCK_EXPR:
2634           node = TREE_OPERAND (node, 1);
2635           continue;
2636
2637         default:
2638           code = TREE_CODE_CLASS (TREE_CODE (node));
2639           if (((code == '1') || (code == '2') || (code == 'e'))
2640               && EXPR_WFL_LINECOL (node))
2641             return node;
2642           return NULL_TREE;
2643         }
2644     }
2645   return NULL_TREE;
2646 }
2647
2648 /* Issue a missing return statement error. Uses METHOD to figure the
2649    last line of the method the error occurs in.  */
2650
2651 static void
2652 missing_return_error (method)
2653      tree method;
2654 {
2655   EXPR_WFL_SET_LINECOL (wfl_operator, DECL_SOURCE_LINE_LAST (method), -2);
2656   parse_error_context (wfl_operator, "Missing return statement");
2657 }
2658
2659 /* Issue an unreachable statement error. From NODE, find the next
2660    statement to report appropriately.  */
2661 static void
2662 unreachable_stmt_error (node)
2663      tree node;
2664 {
2665   /* Browse node to find the next expression node that has a WFL. Use
2666      the location to report the error */
2667   if (TREE_CODE (node) == COMPOUND_EXPR)
2668     node = find_expr_with_wfl (TREE_OPERAND (node, 1));
2669   else
2670     node = find_expr_with_wfl (node);
2671
2672   if (node)
2673     {
2674       EXPR_WFL_SET_LINECOL (wfl_operator, EXPR_WFL_LINENO (node), -2);
2675       parse_error_context (wfl_operator, "Unreachable statement");
2676     }
2677   else
2678     fatal ("Can't get valid statement - unreachable_stmt_error");
2679 }
2680
2681 int
2682 java_report_errors ()
2683 {
2684   if (java_error_count)
2685     fprintf (stderr, "%d error%s", 
2686              java_error_count, (java_error_count == 1 ? "" : "s"));
2687   if (java_warning_count)
2688     fprintf (stderr, "%s%d warning%s", (java_error_count ? ", " : ""),
2689              java_warning_count, (java_warning_count == 1 ? "" : "s"));
2690   if (java_error_count || java_warning_count)
2691     putc ('\n', stderr);
2692   return java_error_count;
2693 }
2694
2695 static char *
2696 java_accstring_lookup (flags)
2697      int flags;
2698 {
2699   static char buffer [80];
2700 #define COPY_RETURN(S) {strcpy (buffer, S); return buffer;}
2701
2702   /* Access modifier looked-up first for easier report on forbidden
2703      access. */
2704   if (flags & ACC_PUBLIC) COPY_RETURN ("public");
2705   if (flags & ACC_PRIVATE) COPY_RETURN ("private");
2706   if (flags & ACC_PROTECTED) COPY_RETURN ("protected");
2707   if (flags & ACC_STATIC) COPY_RETURN ("static");
2708   if (flags & ACC_FINAL) COPY_RETURN ("final");
2709   if (flags & ACC_SYNCHRONIZED) COPY_RETURN ("synchronized");
2710   if (flags & ACC_VOLATILE) COPY_RETURN ("volatile");
2711   if (flags & ACC_TRANSIENT) COPY_RETURN ("transient");
2712   if (flags & ACC_NATIVE) COPY_RETURN ("native");
2713   if (flags & ACC_INTERFACE) COPY_RETURN ("interface");
2714   if (flags & ACC_ABSTRACT) COPY_RETURN ("abstract");
2715
2716   buffer [0] = '\0';
2717   return buffer;
2718 #undef COPY_RETURN
2719 }
2720
2721 /* Issuing error messages upon redefinition of classes, interfaces or
2722    variables. */
2723
2724 static void
2725 classitf_redefinition_error (context, id, decl, cl)
2726      const char *context;
2727      tree id, decl, cl;
2728 {
2729   parse_error_context (cl, "%s `%s' already defined in %s:%d", 
2730                        context, IDENTIFIER_POINTER (id), 
2731                        DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
2732   /* Here we should point out where its redefined. It's a unicode. FIXME */
2733 }
2734
2735 static void
2736 variable_redefinition_error (context, name, type, line)
2737      tree context, name, type;
2738      int line;
2739 {
2740   const char *type_name;
2741
2742   /* Figure a proper name for type. We might haven't resolved it */
2743   if (TREE_CODE (type) == POINTER_TYPE && !TREE_TYPE (type))
2744     type_name = IDENTIFIER_POINTER (TYPE_NAME (type));
2745   else
2746     type_name = lang_printable_name (type, 0);
2747
2748   parse_error_context (context,
2749                        "Variable `%s' is already defined in this method and "
2750                        "was declared `%s %s' at line %d", 
2751                        IDENTIFIER_POINTER (name),
2752                        type_name, IDENTIFIER_POINTER (name), line);
2753 }
2754
2755 static tree
2756 build_array_from_name (type, type_wfl, name, ret_name)
2757      tree type, type_wfl, name, *ret_name;
2758 {
2759   int more_dims = 0;
2760   const char *string;
2761
2762   /* Eventually get more dims */
2763   string = IDENTIFIER_POINTER (name);
2764   while (string [more_dims] == '[')
2765     more_dims++;
2766   
2767   /* If we have, then craft a new type for this variable */
2768   if (more_dims)
2769     {
2770       name = get_identifier (&string [more_dims]);
2771
2772       /* If we have a pointer, use its type */
2773       if (TREE_CODE (type) == POINTER_TYPE)
2774         type = TREE_TYPE (type);
2775
2776       /* Building the first dimension of a primitive type uses this
2777          function */
2778       if (JPRIMITIVE_TYPE_P (type))
2779         {
2780           type = build_java_array_type (type, -1);
2781           CLASS_LOADED_P (type) = 1;
2782           more_dims--;
2783         }
2784       /* Otherwise, if we have a WFL for this type, use it (the type
2785          is already an array on an unresolved type, and we just keep
2786          on adding dimensions) */
2787       else if (type_wfl)
2788         type = type_wfl;
2789
2790       /* Add all the dimensions */
2791       while (more_dims--)
2792         type = build_unresolved_array_type (type);
2793
2794       /* The type may have been incomplete in the first place */
2795       if (type_wfl)
2796         type = obtain_incomplete_type (type);
2797     }
2798
2799   *ret_name = name;
2800   return type;
2801 }
2802
2803 /* Build something that the type identifier resolver will identify as
2804    being an array to an unresolved type. TYPE_WFL is a WFL on a
2805    identifier. */
2806
2807 static tree
2808 build_unresolved_array_type (type_or_wfl)
2809      tree type_or_wfl;
2810 {
2811   const char *ptr;
2812
2813   /* TYPE_OR_WFL might be an array on a resolved type. In this case,
2814      just create a array type */
2815   if (TREE_CODE (type_or_wfl) == RECORD_TYPE)
2816     {
2817       tree type = build_java_array_type (type_or_wfl, -1);
2818       CLASS_LOADED_P (type) = CLASS_LOADED_P (type_or_wfl);
2819       return type;
2820     }
2821
2822   obstack_1grow (&temporary_obstack, '[');
2823   obstack_grow0 (&temporary_obstack,
2824                  IDENTIFIER_POINTER (EXPR_WFL_NODE (type_or_wfl)),
2825                  IDENTIFIER_LENGTH (EXPR_WFL_NODE (type_or_wfl)));
2826   ptr = obstack_finish (&temporary_obstack);
2827   return build_expr_wfl (get_identifier (ptr),
2828                          EXPR_WFL_FILENAME (type_or_wfl),
2829                          EXPR_WFL_LINENO (type_or_wfl),
2830                          EXPR_WFL_COLNO (type_or_wfl));
2831 }
2832
2833 /* Check modifiers. If one doesn't fit, retrieve it in its declaration line
2834   and point it out.  */
2835
2836 static void
2837 check_modifiers (message, value, mask)
2838      const char *message;
2839      int value;
2840      int mask;
2841 {
2842   /* Should point out the one that don't fit. ASCII/unicode,
2843      going backward. FIXME */
2844   if (value & ~mask)
2845     {
2846       int i, remainder = value & ~mask;
2847       for (i = 0; i <= 10; i++)
2848         if ((1 << i) & remainder)
2849           parse_error_context (ctxp->modifier_ctx [i], message, 
2850                                java_accstring_lookup (1 << i));
2851     }
2852 }
2853
2854 static void
2855 parser_add_interface (class_decl, interface_decl, wfl)
2856      tree class_decl, interface_decl, wfl;
2857 {
2858   if (maybe_add_interface (TREE_TYPE (class_decl), TREE_TYPE (interface_decl)))
2859     parse_error_context (wfl, "Interface `%s' repeated",
2860                          IDENTIFIER_POINTER (DECL_NAME (interface_decl)));
2861 }
2862
2863 /* Bulk of common class/interface checks. Return 1 if an error was
2864    encountered. TAG is 0 for a class, 1 for an interface.  */
2865
2866 static int
2867 check_class_interface_creation (is_interface, flags, raw_name, qualified_name, decl, cl)
2868      int is_interface, flags;
2869      tree raw_name, qualified_name, decl, cl;
2870 {
2871   tree node;
2872
2873   if (!quiet_flag)
2874     fprintf (stderr, " %s %s", (is_interface ? "interface" : "class"), 
2875              IDENTIFIER_POINTER (qualified_name));
2876
2877   /* Scope of an interface/class type name:
2878        - Can't be imported by a single type import
2879        - Can't already exists in the package */
2880   if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (raw_name)
2881       && (node = find_name_in_single_imports (raw_name)))
2882     {
2883       parse_error_context 
2884         (cl, "%s name `%s' clashes with imported type `%s'",
2885          (is_interface ? "Interface" : "Class"),
2886          IDENTIFIER_POINTER (raw_name), IDENTIFIER_POINTER (node));
2887       return 1;
2888     }
2889   if (decl && CLASS_COMPLETE_P (decl))
2890     {
2891       classitf_redefinition_error ((is_interface ? "Interface" : "Class"), 
2892                                    qualified_name, decl, cl);
2893       return 1;
2894     }
2895
2896   /* If public, file name should match class/interface name */
2897   if (flags & ACC_PUBLIC)
2898     {
2899       const char *f;
2900
2901       /* Contains OS dependent assumption on path separator. FIXME */
2902       for (f = &input_filename [strlen (input_filename)]; 
2903            f != input_filename && f[0] != '/' && f[0] != DIR_SEPARATOR;
2904            f--)
2905         ;
2906       if (f[0] == '/' || f[0] == DIR_SEPARATOR)
2907         f++;
2908       if (strncmp (IDENTIFIER_POINTER (raw_name), 
2909                    f , IDENTIFIER_LENGTH (raw_name)) ||
2910           f [IDENTIFIER_LENGTH (raw_name)] != '.')
2911         parse_error_context (cl, "Public %s `%s' must be defined in a file "
2912                              "called `%s.java'", 
2913                              (is_interface ? "interface" : "class"),
2914                              IDENTIFIER_POINTER (qualified_name),
2915                              IDENTIFIER_POINTER (raw_name));
2916     }
2917
2918   check_modifiers ((is_interface ? 
2919                     "Illegal modifier `%s' for interface declaration" :
2920                     "Illegal modifier `%s' for class declaration"), flags,
2921                    (is_interface ? INTERFACE_MODIFIERS : CLASS_MODIFIERS));
2922   return 0;
2923 }
2924
2925 /* If DECL is NULL, create and push a new DECL, record the current
2926    line CL and do other maintenance things.  */
2927
2928 static tree
2929 maybe_create_class_interface_decl (decl, qualified_name, cl)
2930      tree decl, qualified_name, cl;
2931 {
2932   if (!decl)
2933     decl = push_class (make_class (), qualified_name);
2934   
2935   /* Take care of the file and line business */
2936   DECL_SOURCE_FILE (decl) = EXPR_WFL_FILENAME (cl);
2937   /* If we're emiting xrefs, store the line/col number information */
2938   if (flag_emit_xref)
2939     DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (cl);
2940   else
2941     DECL_SOURCE_LINE (decl) = EXPR_WFL_LINENO (cl);
2942   CLASS_FROM_SOURCE_P (TREE_TYPE (decl)) = 1;
2943   CLASS_FROM_CURRENTLY_COMPILED_SOURCE_P (TREE_TYPE (decl)) =
2944     IS_A_COMMAND_LINE_FILENAME_P (EXPR_WFL_FILENAME_NODE (cl));
2945
2946   ctxp->current_parsed_class = decl;
2947   
2948   /* Link the declaration to the already seen ones */
2949   TREE_CHAIN (decl) = ctxp->class_list;
2950   ctxp->class_list = decl;
2951
2952   /* Create a new nodes in the global lists */
2953   ctxp->gclass_list = tree_cons (NULL_TREE, decl, ctxp->gclass_list);
2954   all_class_list = tree_cons (NULL_TREE, decl, all_class_list);
2955
2956   /* Install a new dependency list element */
2957   create_jdep_list (ctxp);
2958
2959   SOURCE_FRONTEND_DEBUG (("Defining class/interface %s", 
2960                           IDENTIFIER_POINTER (qualified_name)));
2961   return decl;
2962 }
2963
2964 static void
2965 add_superinterfaces (decl, interface_list)
2966      tree decl, interface_list;
2967 {
2968   tree node;
2969   /* Superinterface(s): if present and defined, parser_check_super_interface ()
2970      takes care of ensuring that:
2971        - This is an accessible interface type,
2972        - Circularity detection.
2973    parser_add_interface is then called. If present but not defined,
2974    the check operation is delayed until the super interface gets
2975    defined.  */
2976   for (node = interface_list; node; node = TREE_CHAIN (node))
2977     {
2978       tree current = TREE_PURPOSE (node);
2979       tree idecl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (current));
2980       if (idecl && CLASS_LOADED_P (TREE_TYPE (idecl)))
2981         {
2982           if (!parser_check_super_interface (idecl, decl, current))
2983             parser_add_interface (decl, idecl, current);
2984         }
2985       else
2986         register_incomplete_type (JDEP_INTERFACE,
2987                                   current, decl, NULL_TREE);
2988     }
2989 }
2990
2991 /* Create an interface in pass1 and return its decl. Return the
2992    interface's decl in pass 2.  */
2993
2994 static tree
2995 create_interface (flags, id, super)
2996      int flags;
2997      tree id, super;
2998 {
2999   tree raw_name = EXPR_WFL_NODE (id);
3000   tree q_name = parser_qualified_classname (id);
3001   tree decl = IDENTIFIER_CLASS_VALUE (q_name);
3002
3003   EXPR_WFL_NODE (id) = q_name;  /* Keep source location, even if refined. */
3004
3005   /* Basic checks: scope, redefinition, modifiers */ 
3006   if (check_class_interface_creation (1, flags, raw_name, q_name, decl, id))
3007     return NULL_TREE;
3008
3009   /* Interface modifiers check
3010        - public/abstract allowed (already done at that point)
3011        - abstract is obsolete (comes first, it's a warning, or should be)
3012        - Can't use twice the same (checked in the modifier rule) */
3013   if ((flags & ACC_ABSTRACT) && flag_redundant)
3014     parse_warning_context 
3015       (MODIFIER_WFL (ABSTRACT_TK),
3016        "Redundant use of `abstract' modifier. Interface `%s' is implicitely "
3017        "abstract", IDENTIFIER_POINTER (raw_name));
3018
3019   /* Create a new decl if DECL is NULL, otherwise fix it */
3020   decl = maybe_create_class_interface_decl (decl, q_name, id);
3021
3022   /* Set super info and mark the class a complete */
3023   set_super_info (ACC_INTERFACE | flags, TREE_TYPE (decl), 
3024                   object_type_node, ctxp->interface_number);
3025   ctxp->interface_number = 0;
3026   CLASS_COMPLETE_P (decl) = 1;
3027   add_superinterfaces (decl, super);
3028
3029   return decl;
3030 }
3031
3032 /* Create an class in pass1 and return its decl. Return class
3033    interface's decl in pass 2.  */
3034
3035 static tree
3036 create_class (flags, id, super, interfaces)
3037      int flags;
3038      tree id, super, interfaces;
3039 {
3040   tree raw_name = EXPR_WFL_NODE (id);
3041   tree class_id, decl;
3042   tree super_decl_type;
3043
3044   class_id = parser_qualified_classname (id);
3045   decl = IDENTIFIER_CLASS_VALUE (class_id);
3046   ctxp->current_parsed_class_un = EXPR_WFL_NODE (id);
3047   EXPR_WFL_NODE (id) = class_id;
3048
3049   /* Basic check: scope, redefinition, modifiers */
3050   if (check_class_interface_creation (0, flags, raw_name, class_id, decl, id))
3051     return NULL_TREE;
3052
3053   /* Class modifier check: 
3054        - Allowed modifier (already done at that point)
3055        - abstract AND final forbidden 
3056        - Public classes defined in the correct file */
3057   if ((flags & ACC_ABSTRACT) && (flags & ACC_FINAL))
3058     parse_error_context (id, "Class `%s' can't be declared both abstract "
3059                          "and final", IDENTIFIER_POINTER (raw_name));
3060
3061   /* Create a new decl if DECL is NULL, otherwise fix it */
3062   decl = maybe_create_class_interface_decl (decl, class_id, id);
3063
3064   /* If SUPER exists, use it, otherwise use Object */
3065   if (super)
3066     {
3067       /* Can't extend java.lang.Object */
3068       if (TREE_TYPE (IDENTIFIER_CLASS_VALUE (class_id)) == object_type_node)
3069         {
3070           parse_error_context (id, "Can't extend `java.lang.Object'");
3071           return NULL_TREE;
3072         }
3073
3074       super_decl_type = 
3075         register_incomplete_type (JDEP_SUPER, super, decl, NULL_TREE);
3076     }
3077   else if (TREE_TYPE (decl) != object_type_node)
3078     super_decl_type = object_type_node;
3079   /* We're defining java.lang.Object */
3080   else
3081     super_decl_type = NULL_TREE;
3082
3083   /* Set super info and mark the class a complete */
3084   set_super_info (flags, TREE_TYPE (decl), super_decl_type, 
3085                   ctxp->interface_number);
3086   ctxp->interface_number = 0;
3087   CLASS_COMPLETE_P (decl) = 1;
3088   add_superinterfaces (decl, interfaces);
3089
3090   /* If doing xref, store the location at which the inherited class
3091      (if any) was seen. */
3092   if (flag_emit_xref && super)
3093     DECL_INHERITED_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (super);
3094
3095   /* Eventually sets the @deprecated tag flag */
3096   CHECK_DEPRECATED (decl);
3097
3098   return decl;
3099 }
3100
3101 /* Can't use lookup_field () since we don't want to load the class and
3102    can't set the CLASS_LOADED_P flag */
3103
3104 static tree
3105 find_field (class, name)
3106      tree class;
3107      tree name;
3108 {
3109   tree decl;
3110   for (decl = TYPE_FIELDS (class); decl; decl = TREE_CHAIN (decl))
3111     {
3112       if (DECL_NAME (decl) == name)
3113         return decl;
3114     }
3115   return NULL_TREE;
3116 }
3117
3118 /* Wrap around lookup_field that doesn't potentially upset the value
3119    of CLASS */
3120
3121 static tree
3122 lookup_field_wrapper (class, name)
3123      tree class, name;
3124 {
3125   tree type = class;
3126   tree decl;
3127   java_parser_context_save_global ();
3128   decl = lookup_field (&type, name);
3129   java_parser_context_restore_global ();
3130   return decl == error_mark_node ? NULL : decl;
3131 }
3132
3133 /* Find duplicate field within the same class declarations and report
3134    the error. Returns 1 if a duplicated field was found, 0
3135    otherwise.  */
3136
3137 static int
3138 duplicate_declaration_error_p (new_field_name, new_type, cl)
3139      tree new_field_name, new_type, cl;
3140 {
3141   /* This might be modified to work with method decl as well */
3142   tree decl = find_field (TREE_TYPE (ctxp->current_parsed_class), 
3143                           new_field_name);
3144   if (decl)
3145     {
3146       char *t1 = xstrdup (purify_type_name
3147                          ((TREE_CODE (new_type) == POINTER_TYPE 
3148                            && TREE_TYPE (new_type) == NULL_TREE) ?
3149                           IDENTIFIER_POINTER (TYPE_NAME (new_type)) :
3150                           lang_printable_name (new_type, 1)));
3151       /* The type may not have been completed by the time we report
3152          the error */
3153       char *t2 = xstrdup (purify_type_name
3154                          ((TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE 
3155                            && TREE_TYPE (TREE_TYPE (decl)) == NULL_TREE) ?
3156                           IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl))) :
3157                           lang_printable_name (TREE_TYPE (decl), 1)));
3158       parse_error_context 
3159         (cl , "Duplicate variable declaration: `%s %s' was `%s %s' (%s:%d)", 
3160          t1, IDENTIFIER_POINTER (new_field_name),
3161          t2, IDENTIFIER_POINTER (DECL_NAME (decl)),
3162          DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
3163       free (t1);
3164       free (t2);
3165       return 1;
3166     }
3167   return 0;
3168 }
3169
3170 /* Field registration routine. If TYPE doesn't exist, field
3171    declarations are linked to the undefined TYPE dependency list, to
3172    be later resolved in java_complete_class () */
3173
3174 static void
3175 register_fields (flags, type, variable_list)
3176      int flags;
3177      tree type, variable_list;
3178 {
3179   tree current, saved_type;
3180   tree class_type = TREE_TYPE (ctxp->current_parsed_class);
3181   int saved_lineno = lineno;
3182   int must_chain = 0;
3183   tree wfl = NULL_TREE;
3184
3185   /* If we're adding fields to interfaces, those fields are public,
3186      static, final */
3187   if (CLASS_INTERFACE (TYPE_NAME (class_type)))
3188     {
3189       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (PUBLIC_TK),
3190                                  flags, ACC_PUBLIC, 
3191                                  "%s", "interface field(s)");
3192       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (STATIC_TK),
3193                                  flags, ACC_STATIC, 
3194                                  "%s", "interface field(s)");
3195       OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (FINAL_TK),
3196                                  flags, ACC_FINAL, "%s", "interface field(s)");
3197       check_modifiers ("Illegal interface member modifier `%s'", flags,
3198                        INTERFACE_FIELD_MODIFIERS);
3199       flags |= (ACC_PUBLIC | ACC_STATIC | ACC_FINAL);
3200     }
3201
3202   /* Obtain a suitable type for resolution, if necessary */
3203   SET_TYPE_FOR_RESOLUTION (type, wfl, must_chain);
3204
3205   /* If TYPE is fully resolved and we don't have a reference, make one */
3206   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
3207
3208   for (current = variable_list, saved_type = type; current; 
3209        current = TREE_CHAIN (current), type = saved_type)
3210     {
3211       tree real_type;
3212       tree field_decl;
3213       tree cl = TREE_PURPOSE (current);
3214       tree init = TREE_VALUE (current);
3215       tree current_name = EXPR_WFL_NODE (cl);
3216
3217       /* Process NAME, as it may specify extra dimension(s) for it */
3218       type = build_array_from_name (type, wfl, current_name, &current_name);
3219
3220       /* Type adjustment. We may have just readjusted TYPE because
3221          the variable specified more dimensions. Make sure we have
3222          a reference if we can and don't have one already. Also
3223          change the name if we have an init. */
3224       if (type != saved_type)
3225         {
3226           PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
3227           if (init)
3228             EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = current_name;
3229         }
3230
3231       real_type = GET_REAL_TYPE (type);
3232       /* Check for redeclarations */
3233       if (duplicate_declaration_error_p (current_name, real_type, cl))
3234         continue;
3235
3236       /* Set lineno to the line the field was found and create a
3237          declaration for it. Eventually sets the @deprecated tag flag. */
3238       if (flag_emit_xref)
3239         lineno = EXPR_WFL_LINECOL (cl);
3240       else
3241         lineno = EXPR_WFL_LINENO (cl);
3242       field_decl = add_field (class_type, current_name, real_type, flags);
3243       CHECK_DEPRECATED (field_decl);
3244       
3245       /* Check if we must chain. */
3246       if (must_chain)
3247         register_incomplete_type (JDEP_FIELD, wfl, field_decl, type);
3248           
3249       /* If we have an initialization value tied to the field */
3250       if (init)
3251         {
3252           /* The field is declared static */
3253           if (flags & ACC_STATIC)
3254             {
3255               /* We include the field and its initialization part into
3256                  a list used to generate <clinit>. After <clinit> is
3257                  walked, field initializations will be processed and
3258                  fields initialized with known constants will be taken
3259                  out of <clinit> and have their DECL_INITIAL set
3260                  appropriately. */
3261               TREE_CHAIN (init) = ctxp->static_initialized;
3262               ctxp->static_initialized = init;
3263               if (TREE_OPERAND (init, 1) 
3264                   && TREE_CODE (TREE_OPERAND (init, 1)) == NEW_ARRAY_INIT)
3265                 TREE_STATIC (TREE_OPERAND (init, 1)) = 1;
3266             }
3267           /* A non-static field declared with an immediate initialization is
3268              to be initialized in <init>, if any.  This field is remembered
3269              to be processed at the time of the generation of <init>. */
3270           else
3271             {
3272               TREE_CHAIN (init) = ctxp->non_static_initialized;
3273               ctxp->non_static_initialized = init;
3274             }
3275           MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
3276           DECL_INITIAL (field_decl) = TREE_OPERAND (init, 1);
3277         }
3278     }
3279   lineno = saved_lineno;
3280 }
3281
3282 /* Generate the method $finit$ that initializes fields initialized
3283    upon declaration.  */
3284
3285 static void
3286 maybe_generate_finit ()
3287 {
3288   tree mdecl, current;
3289   
3290   if (!ctxp->non_static_initialized || java_error_count)
3291     return;
3292
3293   mdecl = create_artificial_method (TREE_TYPE (ctxp->current_parsed_class),
3294                                     ACC_PRIVATE, void_type_node,
3295                                     finit_identifier_node, end_params_node);
3296   start_artificial_method_body (mdecl);
3297
3298   ctxp->non_static_initialized = nreverse (ctxp->non_static_initialized);
3299   for (current = ctxp->non_static_initialized; current;
3300        current = TREE_CHAIN (current))
3301     java_method_add_stmt (mdecl, 
3302                           build_debugable_stmt (EXPR_WFL_LINECOL (current), 
3303                                                 current));
3304
3305   end_artificial_method_body (mdecl);
3306   CLASS_HAS_FINIT_P (TREE_TYPE (ctxp->current_parsed_class)) = 1;
3307   ctxp->non_static_initialized = NULL_TREE;
3308 }
3309
3310 /* Check whether it is necessary to generate a <clinit> for the class
3311    we just parsed. */
3312
3313 static void
3314 maybe_generate_clinit ()
3315 {
3316   tree mdecl, c;
3317
3318   if (!ctxp->static_initialized || java_error_count)
3319     return;
3320
3321   mdecl = create_artificial_method (TREE_TYPE (ctxp->current_parsed_class),
3322                                     ACC_STATIC, void_type_node,
3323                                     clinit_identifier_node, end_params_node);
3324   start_artificial_method_body (mdecl);
3325
3326   /* Keep initialization in order to enforce 8.5 */
3327   ctxp->static_initialized = nreverse (ctxp->static_initialized);
3328
3329   /* We process the list of assignment we produced as the result of
3330      the declaration of initialized static field and add them as
3331      statement to the <clinit> method. */
3332   for (c = ctxp->static_initialized; c; c = TREE_CHAIN (c))
3333     {
3334       /* We build the assignment expression that will initialize the
3335          field to its value. There are strict rules on static
3336          initializers (8.5). FIXME */
3337       java_method_add_stmt (mdecl, 
3338                             build_debugable_stmt (EXPR_WFL_LINECOL (c), c));
3339     }
3340
3341   end_artificial_method_body (mdecl);
3342   ctxp->static_initialized = NULL_TREE;
3343 }
3344
3345 /* Shared accros method_declarator and method_header to remember the
3346    patch stage that was reached during the declaration of the method.
3347    A method DECL is built differently is there is no patch
3348    (JDEP_NO_PATCH) or a patch (JDEP_METHOD or JDEP_METHOD_RETURN)
3349    pending on the currently defined method.  */
3350
3351 static int patch_stage;
3352
3353 /* Check the method declaration and add the method to its current
3354    class.  If the argument list is known to contain incomplete types,
3355    the method is partially added and the registration will be resume
3356    once the method arguments resolved. If TYPE is NULL, we're dealing
3357    with a constructor.  */
3358
3359 static tree
3360 method_header (flags, type, mdecl, throws)
3361      int flags;
3362      tree type, mdecl, throws;
3363 {
3364   tree meth = TREE_VALUE (mdecl);
3365   tree id = TREE_PURPOSE (mdecl);
3366   tree type_wfl = NULL_TREE;
3367   tree meth_name = NULL_TREE;
3368   tree current, orig_arg, this_class;
3369   int saved_lineno;
3370   int constructor_ok = 0, must_chain;
3371   
3372   check_modifiers_consistency (flags);
3373
3374   if (ctxp->current_parsed_class)
3375     this_class = TREE_TYPE (ctxp->current_parsed_class);
3376   else
3377     return NULL_TREE;
3378   
3379   /* There are some forbidden modifiers for an abstract method and its
3380      class must be abstract as well.  */
3381   if (type && (flags & ACC_ABSTRACT))
3382     {
3383       ABSTRACT_CHECK (flags, ACC_PRIVATE, id, "Private");
3384       ABSTRACT_CHECK (flags, ACC_STATIC, id, "Static");
3385       ABSTRACT_CHECK (flags, ACC_FINAL, id, "Final");
3386       ABSTRACT_CHECK (flags, ACC_NATIVE, id, "Native");
3387       ABSTRACT_CHECK (flags, ACC_SYNCHRONIZED,id, "Synchronized");
3388       if (!CLASS_ABSTRACT (TYPE_NAME (this_class))
3389           && !CLASS_INTERFACE (TYPE_NAME (this_class)))
3390         parse_error_context 
3391           (id, "Class `%s' must be declared abstract to define abstract "
3392            "method `%s'", 
3393            IDENTIFIER_POINTER (DECL_NAME (ctxp->current_parsed_class)),
3394            IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
3395     }
3396   /* Things to be checked when declaring a constructor */
3397   if (!type)
3398     {
3399       int ec = java_error_count;
3400       /* 8.6: Constructor declarations: we might be trying to define a
3401          method without specifying a return type. */
3402       if (EXPR_WFL_NODE (id) != ctxp->current_parsed_class_un)
3403         parse_error_context 
3404           (id, "Invalid method declaration, return type required");
3405       /* 8.6.3: Constructor modifiers */
3406       else
3407         {
3408           JCONSTRUCTOR_CHECK (flags, ACC_ABSTRACT, id, "abstract");
3409           JCONSTRUCTOR_CHECK (flags, ACC_STATIC, id, "static");
3410           JCONSTRUCTOR_CHECK (flags, ACC_FINAL, id, "final");
3411           JCONSTRUCTOR_CHECK (flags, ACC_NATIVE, id, "native");
3412           JCONSTRUCTOR_CHECK (flags, ACC_SYNCHRONIZED, id, "synchronized");
3413         }
3414       /* If we found error here, we don't consider it's OK to tread
3415          the method definition as a constructor, for the rest of this
3416          function */
3417       if (ec == java_error_count)
3418         constructor_ok = 1;
3419     }
3420
3421   /* Method declared within the scope of an interface are implicitly
3422      abstract and public. Conflicts with other erroneously provided
3423      modifiers are checked right after. */
3424
3425   if (CLASS_INTERFACE (TYPE_NAME (this_class)))
3426     {
3427       /* If FLAGS isn't set because of a modifier, turn the
3428          corresponding modifier WFL to NULL so we issue a warning on
3429          the obsolete use of the modifier */
3430       if (!(flags & ACC_PUBLIC))
3431         MODIFIER_WFL (PUBLIC_TK) = NULL;
3432       if (!(flags & ACC_ABSTRACT))
3433         MODIFIER_WFL (ABSTRACT_TK) = NULL;
3434       flags |= ACC_PUBLIC;
3435       flags |= ACC_ABSTRACT;
3436     }
3437
3438   /* Modifiers context reset moved up, so abstract method declaration
3439      modifiers can be later checked.  */
3440
3441   /* Set constructor returned type to void and method name to <init>,
3442      unless we found an error identifier the constructor (in which
3443      case we retain the original name) */
3444   if (!type)
3445     {
3446       type = void_type_node;
3447       if (constructor_ok)
3448         meth_name = init_identifier_node;
3449     }
3450   else
3451     meth_name = EXPR_WFL_NODE (id);
3452
3453   /* Do the returned type resolution and registration if necessary */
3454   SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
3455
3456   if (meth_name)
3457     type = build_array_from_name (type, type_wfl, meth_name, &meth_name);
3458   EXPR_WFL_NODE (id) = meth_name;
3459   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
3460
3461   if (must_chain)
3462     {
3463       patch_stage = JDEP_METHOD_RETURN;
3464       register_incomplete_type (patch_stage, type_wfl, id, type);
3465       TREE_TYPE (meth) = GET_REAL_TYPE (type);
3466     }
3467   else
3468     TREE_TYPE (meth) = type;
3469
3470   saved_lineno = lineno;
3471   /* When defining an abstract or interface method, the curly
3472      bracket at level 1 doesn't exist because there is no function
3473      body */
3474   lineno = (ctxp->first_ccb_indent1 ? ctxp->first_ccb_indent1 : 
3475             EXPR_WFL_LINENO (id));
3476
3477   /* Remember the original argument list */
3478   orig_arg = TYPE_ARG_TYPES (meth);
3479
3480   if (patch_stage)              /* includes ret type and/or all args */
3481     {
3482       jdep *jdep;
3483       meth = add_method_1 (this_class, flags, meth_name, meth);
3484       /* Patch for the return type */
3485       if (patch_stage == JDEP_METHOD_RETURN)
3486         {
3487           jdep = CLASSD_LAST (ctxp->classd_list);
3488           JDEP_GET_PATCH (jdep) = &TREE_TYPE (TREE_TYPE (meth));
3489         }
3490       /* This is the stop JDEP. METH allows the function's signature
3491          to be computed. */
3492       register_incomplete_type (JDEP_METHOD_END, NULL_TREE, meth, NULL_TREE);
3493     }
3494   else
3495     meth = add_method (this_class, flags, meth_name, 
3496                        build_java_signature (meth));
3497
3498   /* Fix the method argument list so we have the argument name
3499      information */
3500   fix_method_argument_names (orig_arg, meth);
3501
3502   /* Register the parameter number and re-install the current line
3503      number */
3504   DECL_MAX_LOCALS (meth) = ctxp->formal_parameter_number+1;
3505   lineno = saved_lineno;
3506
3507   /* Register exception specified by the `throws' keyword for
3508      resolution and set the method decl appropriate field to the list.
3509      Note: the grammar ensures that what we get here are class
3510      types. */
3511   if (throws)
3512     {
3513       throws = nreverse (throws);
3514       for (current = throws; current; current = TREE_CHAIN (current))
3515         {
3516           register_incomplete_type (JDEP_EXCEPTION, TREE_VALUE (current),
3517                                     NULL_TREE, NULL_TREE);
3518           JDEP_GET_PATCH (CLASSD_LAST (ctxp->classd_list)) = 
3519             &TREE_VALUE (current);
3520         }
3521       DECL_FUNCTION_THROWS (meth) = throws;
3522     }
3523
3524   /* We set the DECL_NAME to ID so we can track the location where
3525      the function was declared. This allow us to report
3526      redefinition error accurately. When method are verified,
3527      DECL_NAME is reinstalled properly (using the content of the
3528      WFL node ID) (see check_method_redefinition). We don't do that
3529      when Object is being defined. Constructor <init> names will be
3530      reinstalled the same way. */
3531   if (TREE_TYPE (ctxp->current_parsed_class) != object_type_node)
3532     DECL_NAME (meth) = id;
3533
3534   /* Set the flag if we correctly processed a constructor */
3535   if (constructor_ok)
3536     DECL_CONSTRUCTOR_P (meth) = 1;
3537
3538   /* Eventually set the @deprecated tag flag */
3539   CHECK_DEPRECATED (meth);
3540
3541   /* If doing xref, store column and line number information instead
3542      of the line number only. */
3543   if (flag_emit_xref)
3544     DECL_SOURCE_LINE (meth) = EXPR_WFL_LINECOL (id);
3545
3546   return meth;
3547 }
3548
3549 static void
3550 fix_method_argument_names (orig_arg, meth)
3551     tree orig_arg, meth;
3552 {
3553   tree arg = TYPE_ARG_TYPES (TREE_TYPE (meth));
3554   if (TREE_CODE (TREE_TYPE (meth)) == METHOD_TYPE)
3555     {
3556       TREE_PURPOSE (arg) = this_identifier_node;
3557       arg = TREE_CHAIN (arg);
3558     }
3559   while (orig_arg != end_params_node)
3560     {
3561       TREE_PURPOSE (arg) = TREE_PURPOSE (orig_arg);
3562       orig_arg = TREE_CHAIN (orig_arg);
3563       arg = TREE_CHAIN (arg);
3564     }
3565 }
3566
3567 /* Complete the method declaration with METHOD_BODY.  */
3568
3569 static void
3570 finish_method_declaration (method_body)
3571      tree method_body;
3572 {
3573   int flags;
3574
3575   if (!current_function_decl)
3576     return;
3577
3578   flags = get_access_flags_from_decl (current_function_decl);
3579
3580   /* 8.4.5 Method Body */
3581   if ((flags & ACC_ABSTRACT || flags & ACC_NATIVE) && method_body)
3582     {
3583       tree wfl = DECL_NAME (current_function_decl);
3584       parse_error_context (wfl, 
3585                            "%s method `%s' can't have a body defined",
3586                            (METHOD_NATIVE (current_function_decl) ?
3587                             "Native" : "Abstract"),
3588                            IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
3589       method_body = NULL_TREE;
3590     }
3591   else if (!(flags & ACC_ABSTRACT) && !(flags & ACC_NATIVE) && !method_body)
3592     {
3593       tree wfl = DECL_NAME (current_function_decl);
3594       parse_error_context (wfl, 
3595                            "Non native and non abstract method `%s' must "
3596                            "have a body defined",
3597                            IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
3598       method_body = NULL_TREE;
3599     }
3600
3601   if (flag_emit_class_files && method_body 
3602       && TREE_CODE (method_body) == NOP_EXPR 
3603       && TREE_TYPE (current_function_decl) 
3604       && TREE_TYPE (TREE_TYPE (current_function_decl)) == void_type_node)
3605     method_body = build1 (RETURN_EXPR, void_type_node, NULL);
3606     
3607   BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (current_function_decl)) = method_body;
3608   maybe_absorb_scoping_blocks ();
3609   /* Exit function's body */
3610   exit_block ();
3611   /* Merge last line of the function with first line, directly in the
3612      function decl. It will be used to emit correct debug info. */
3613   if (!flag_emit_xref)
3614     DECL_SOURCE_LINE_MERGE (current_function_decl, ctxp->last_ccb_indent1);
3615   /* So we don't have an irrelevant function declaration context for
3616      the next static block we'll see. */
3617   current_function_decl = NULL_TREE;
3618 }
3619
3620 /* Build a an error message for constructor circularity errors.  */
3621
3622 static char *
3623 constructor_circularity_msg (from, to)
3624      tree from, to;
3625 {
3626   static char string [4096];
3627   char *t = xstrdup (lang_printable_name (from, 0));
3628   sprintf (string, "`%s' invokes `%s'", t, lang_printable_name (to, 0));
3629   free (t);
3630   return string;
3631 }
3632
3633 /* Verify a circular call to METH. Return 1 if an error is found, 0
3634    otherwise.  */
3635
3636 static int
3637 verify_constructor_circularity (meth, current)
3638      tree meth, current;
3639 {
3640   static tree list = NULL_TREE;
3641   tree c;
3642   for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
3643     {
3644       if (TREE_VALUE (c) == meth)
3645         {
3646           char *t;
3647           if (list)
3648             {
3649               tree liste;
3650               list = nreverse (list);
3651               for (liste = list; liste; liste = TREE_CHAIN (liste))
3652                 {
3653                   parse_error_context 
3654                     (TREE_PURPOSE (TREE_PURPOSE (liste)),
3655                      constructor_circularity_msg
3656                       (TREE_VALUE (liste), TREE_VALUE (TREE_PURPOSE (liste)))); 
3657                   java_error_count--;
3658                 }
3659             }
3660           t = xstrdup (lang_printable_name (meth, 0));
3661           parse_error_context (TREE_PURPOSE (c), 
3662                                "%s: recursive invocation of constructor `%s'",
3663                                constructor_circularity_msg (current, meth), t);
3664           free (t);
3665           list = NULL_TREE;
3666           return 1;
3667         }
3668     }
3669   for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
3670     {
3671       list = tree_cons (c, current, list);
3672       if (verify_constructor_circularity (meth, TREE_VALUE (c)))
3673         return 1;
3674       list = TREE_CHAIN (list);
3675     }
3676   return 0;
3677 }
3678
3679 /* Check modifiers that can be declared but exclusively */
3680
3681 static void
3682 check_modifiers_consistency (flags)
3683      int flags;
3684 {
3685   int acc_count = 0;
3686   tree cl = NULL_TREE;
3687
3688   THIS_MODIFIER_ONLY (flags, ACC_PUBLIC, 0, acc_count, cl);
3689   THIS_MODIFIER_ONLY (flags, ACC_PRIVATE, 1, acc_count, cl);
3690   THIS_MODIFIER_ONLY (flags, ACC_PROTECTED, 2, acc_count, cl);
3691   if (acc_count > 1)
3692     parse_error_context
3693       (cl, "Inconsistent member declaration. At most one of `public', "
3694        "`private', or `protected' may be specified");
3695 }
3696
3697 /* Check the methode header METH for abstract specifics features */
3698
3699 static void
3700 check_abstract_method_header (meth)
3701      tree meth;
3702 {
3703   int flags = get_access_flags_from_decl (meth);
3704   /* DECL_NAME might still be a WFL node */
3705   tree name = GET_METHOD_NAME (meth);
3706
3707   OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (ABSTRACT_TK), flags,
3708                              ACC_ABSTRACT, "abstract method `%s'",
3709                              IDENTIFIER_POINTER (name));
3710   OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (PUBLIC_TK), flags, 
3711                              ACC_PUBLIC, "abstract method `%s'",
3712                              IDENTIFIER_POINTER (name));
3713
3714   check_modifiers ("Illegal modifier `%s' for interface method",
3715                   flags, INTERFACE_METHOD_MODIFIERS);
3716 }
3717
3718 /* Create a FUNCTION_TYPE node and start augmenting it with the
3719    declared function arguments. Arguments type that can't be resolved
3720    are left as they are, but the returned node is marked as containing
3721    incomplete types.  */
3722
3723 static tree
3724 method_declarator (id, list)
3725      tree id, list;
3726 {
3727   tree arg_types = NULL_TREE, current, node;
3728   tree meth = make_node (FUNCTION_TYPE);
3729   jdep *jdep;
3730
3731   patch_stage = JDEP_NO_PATCH;
3732   
3733   for (current = list; current; current = TREE_CHAIN (current))
3734     {
3735       int must_chain = 0;
3736       tree wfl_name = TREE_PURPOSE (current);
3737       tree type = TREE_VALUE (current);
3738       tree name = EXPR_WFL_NODE (wfl_name);
3739       tree already, arg_node;
3740       tree type_wfl = NULL_TREE;
3741       tree real_type;
3742
3743       /* Obtain a suitable type for resolution, if necessary */
3744       SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
3745
3746       /* Process NAME, as it may specify extra dimension(s) for it */
3747       type = build_array_from_name (type, type_wfl, name, &name);
3748       EXPR_WFL_NODE (wfl_name) = name;
3749
3750       real_type = GET_REAL_TYPE (type);
3751       if (TREE_CODE (real_type) == RECORD_TYPE)
3752         {
3753           real_type = promote_type (real_type);
3754           if (TREE_CODE (type) == TREE_LIST)
3755             TREE_PURPOSE (type) = real_type;
3756         }
3757
3758       /* Check redefinition */
3759       for (already = arg_types; already; already = TREE_CHAIN (already))
3760         if (TREE_PURPOSE (already) == name)
3761           {
3762             parse_error_context 
3763               (wfl_name, "Variable `%s' is used more than once in the "
3764                "argument list of method `%s'", IDENTIFIER_POINTER (name),
3765                IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
3766             break;
3767           }
3768
3769       /* If we've an incomplete argument type, we know there is a location
3770          to patch when the type get resolved, later.  */
3771       jdep = NULL;
3772       if (must_chain)
3773         {
3774           patch_stage = JDEP_METHOD;
3775           type = register_incomplete_type (patch_stage, 
3776                                            type_wfl, wfl_name, type);
3777           jdep = CLASSD_LAST (ctxp->classd_list);
3778           JDEP_MISC (jdep) = id;
3779         }
3780
3781       /* The argument node: a name and a (possibly) incomplete type */
3782       arg_node = build_tree_list (name, real_type);
3783       if (jdep)
3784         JDEP_GET_PATCH (jdep) = &TREE_VALUE (arg_node);
3785       TREE_CHAIN (arg_node) = arg_types;
3786       arg_types = arg_node;
3787     }
3788   TYPE_ARG_TYPES (meth) = chainon (nreverse (arg_types), end_params_node);
3789   node = build_tree_list (id, meth);
3790   return node;
3791 }
3792
3793 static int
3794 unresolved_type_p (wfl, returned)
3795      tree wfl;
3796      tree *returned;
3797      
3798 {
3799   if (TREE_CODE (wfl) == EXPR_WITH_FILE_LOCATION)
3800     {
3801       tree decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (wfl));
3802       if (returned)
3803         *returned = (decl ? TREE_TYPE (decl) : NULL_TREE);
3804       return 1;
3805     }
3806   if (returned)
3807     *returned = wfl;
3808   return 0;
3809 }
3810
3811 /* From NAME, build a qualified identifier node using the
3812    qualification from the current package definition. */
3813
3814 static tree
3815 parser_qualified_classname (name)
3816      tree name;
3817 {
3818   if (ctxp->package)
3819     return merge_qualified_name (ctxp->package, EXPR_WFL_NODE (name));
3820   else 
3821     return EXPR_WFL_NODE (name);
3822 }
3823
3824 /* Called once the type a interface extends is resolved. Returns 0 if
3825    everything is OK.  */
3826
3827 static int
3828 parser_check_super_interface (super_decl, this_decl, this_wfl)
3829      tree super_decl, this_decl, this_wfl;
3830 {
3831   tree super_type = TREE_TYPE (super_decl);
3832
3833   /* Has to be an interface */
3834   if (!CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (super_decl))))
3835     {
3836       parse_error_context 
3837         (this_wfl, "Can't use %s `%s' to implement/extend %s `%s'",
3838          (TYPE_ARRAY_P (super_type) ? "array" : "class"),
3839          IDENTIFIER_POINTER (DECL_NAME (super_decl)),
3840          (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (this_decl))) ? 
3841           "interface" : "class"),
3842          IDENTIFIER_POINTER (DECL_NAME (this_decl)));
3843       return 1;
3844     }
3845
3846   /* Check scope: same package OK, other package: OK if public */
3847   if (check_pkg_class_access (DECL_NAME (super_decl), lookup_cl (this_decl)))
3848     return 1;
3849
3850   SOURCE_FRONTEND_DEBUG (("Completing interface %s with %s",
3851                           IDENTIFIER_POINTER (DECL_NAME (this_decl)),
3852                           IDENTIFIER_POINTER (DECL_NAME (super_decl))));
3853   return 0;
3854 }
3855
3856 /* Makes sure that SUPER_DECL is suitable to extend THIS_DECL. Returns
3857    0 if everthing is OK.  */
3858
3859 static int
3860 parser_check_super (super_decl, this_decl, wfl)
3861      tree super_decl, this_decl, wfl;
3862 {
3863   tree super_type = TREE_TYPE (super_decl);
3864
3865   /* SUPER should be a CLASS (neither an array nor an interface) */
3866   if (TYPE_ARRAY_P (super_type) || CLASS_INTERFACE (TYPE_NAME (super_type)))
3867     {
3868       parse_error_context 
3869         (wfl, "Class `%s' can't subclass %s `%s'",
3870          IDENTIFIER_POINTER (DECL_NAME (this_decl)),
3871          (CLASS_INTERFACE (TYPE_NAME (super_type)) ? "interface" : "array"),
3872          IDENTIFIER_POINTER (DECL_NAME (super_decl)));
3873       return 1;
3874     }
3875
3876   if (CLASS_FINAL (TYPE_NAME (super_type)))
3877     {
3878       parse_error_context (wfl, "Can't subclass final classes: %s",
3879                            IDENTIFIER_POINTER (DECL_NAME (super_decl)));
3880       return 1;
3881     }
3882
3883   /* Check scope: same package OK, other package: OK if public */
3884   if (check_pkg_class_access (DECL_NAME (super_decl), wfl))
3885     return 1;
3886   
3887   SOURCE_FRONTEND_DEBUG (("Completing class %s with %s",
3888                           IDENTIFIER_POINTER (DECL_NAME (this_decl)),
3889                           IDENTIFIER_POINTER (DECL_NAME (super_decl))));
3890   return 0;
3891 }
3892
3893 /* Create a new dependency list and link it (in a LIFO manner) to the
3894    CTXP list of type dependency list.  */
3895
3896 static void
3897 create_jdep_list (ctxp)
3898      struct parser_ctxt *ctxp;
3899 {
3900   jdeplist *new = (jdeplist *)xmalloc (sizeof (jdeplist));      
3901   new->first = new->last = NULL;
3902   new->next = ctxp->classd_list;
3903   ctxp->classd_list = new;
3904 }
3905
3906 static jdeplist *
3907 reverse_jdep_list (ctxp)
3908      struct parser_ctxt *ctxp;
3909 {
3910   register jdeplist *prev = NULL, *current, *next;
3911   for (current = ctxp->classd_list; current; current = next)
3912     {
3913       next = current->next;
3914       current->next = prev;
3915       prev = current;
3916     }
3917   return prev;
3918 }
3919
3920 /* Create a fake pointer based on the ID stored in
3921    TYPE_NAME. TYPE_NAME can be a WFL or a incomplete type asking to be
3922    registered again. */
3923
3924 static tree
3925 obtain_incomplete_type (type_name)
3926      tree type_name;
3927 {
3928   tree ptr, name;
3929
3930   if (TREE_CODE (type_name) == EXPR_WITH_FILE_LOCATION)
3931     name = EXPR_WFL_NODE (type_name);
3932   else if (INCOMPLETE_TYPE_P (type_name))
3933     name = TYPE_NAME (type_name);
3934   else
3935     fatal ("invalid type name - obtain_incomplete_type");
3936
3937   for (ptr = ctxp->incomplete_class; ptr; ptr = TREE_CHAIN (ptr))
3938     if (TYPE_NAME (ptr) == name)
3939       break;
3940
3941   if (!ptr)
3942     {
3943       push_obstacks (&permanent_obstack, &permanent_obstack);
3944       BUILD_PTR_FROM_NAME (ptr, name);
3945       layout_type (ptr);
3946       pop_obstacks ();
3947       TREE_CHAIN (ptr) = ctxp->incomplete_class;
3948       ctxp->incomplete_class = ptr;
3949     }
3950
3951   return ptr;
3952 }
3953
3954 /* Register a incomplete type whose name is WFL. Reuse PTR if PTR is
3955    non NULL instead of computing a new fake type based on WFL. The new
3956    dependency is inserted in the current type dependency list, in FIFO
3957    manner.  */
3958
3959 static tree
3960 register_incomplete_type (kind, wfl, decl, ptr)
3961      int kind;
3962      tree wfl, decl, ptr;
3963 {
3964   jdep *new = (jdep *)xmalloc (sizeof (jdep));
3965
3966   if (!ptr && kind != JDEP_METHOD_END) /* JDEP_METHOD_END is a mere marker */
3967     ptr = obtain_incomplete_type (wfl);
3968
3969   JDEP_KIND (new) = kind;
3970   JDEP_DECL (new) = decl;
3971   JDEP_SOLV (new) = ptr;
3972   JDEP_WFL (new) = wfl;
3973   JDEP_CHAIN (new) = NULL;
3974   JDEP_MISC (new) = NULL_TREE;
3975   JDEP_GET_PATCH (new) = (tree *)NULL;
3976
3977   JDEP_INSERT (ctxp->classd_list, new);
3978
3979   return ptr;
3980 }
3981
3982 void
3983 java_check_circular_reference ()
3984 {
3985   tree current;
3986   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
3987     {
3988       tree type = TREE_TYPE (current);
3989       if (CLASS_INTERFACE (current))
3990         {
3991           /* Check all interfaces this class extends */
3992           tree basetype_vec = TYPE_BINFO_BASETYPES (type);
3993           int n, i;
3994
3995           if (!basetype_vec)
3996             return;
3997           n = TREE_VEC_LENGTH (basetype_vec);
3998           for (i = 0; i < n; i++)
3999             {
4000               tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
4001               if (vec_elt && BINFO_TYPE (vec_elt) != object_type_node 
4002                   && interface_of_p (type, BINFO_TYPE (vec_elt)))
4003                 parse_error_context (lookup_cl (current),
4004                                      "Cyclic interface inheritance");
4005             }
4006         }
4007       else
4008         if (inherits_from_p (CLASSTYPE_SUPER (type), type))
4009           parse_error_context (lookup_cl (current), 
4010                                "Cyclic class inheritance");
4011     }
4012 }
4013
4014 /* Fix the constructors. This will be called right after circular
4015    references have been checked. It is necessary to fix constructors
4016    early even if no code generation will take place for that class:
4017    some generated constructor might be required by the class whose
4018    compilation triggered this one to be simply loaded.  */
4019
4020 void
4021 java_fix_constructors ()
4022 {
4023   tree current;
4024
4025   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
4026     {
4027       tree decl;
4028       tree class_type = TREE_TYPE (current);
4029       int saw_ctor = 0;
4030
4031       for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
4032         {
4033           if (DECL_CONSTRUCTOR_P (decl))
4034             {
4035               fix_constructors (decl);
4036               saw_ctor = 1;
4037             }
4038         }
4039
4040       if (!saw_ctor)
4041         {
4042           int flags = (get_access_flags_from_decl (current) & ACC_PUBLIC ?
4043                        ACC_PUBLIC : 0);
4044           decl = create_artificial_method (class_type, flags, void_type_node, 
4045                                            init_identifier_node, 
4046                                            end_params_node);
4047           DECL_CONSTRUCTOR_P (decl) = 1;
4048         }
4049     }
4050 }
4051
4052 /* safe_layout_class just makes sure that we can load a class without
4053    disrupting the current_class, input_file, lineno, etc, information
4054    about the class processed currently.  */
4055
4056 void
4057 safe_layout_class (class)
4058      tree class;
4059 {
4060   tree save_current_class = current_class;
4061   char *save_input_filename = input_filename;
4062   int save_lineno = lineno;
4063
4064   push_obstacks (&permanent_obstack, &permanent_obstack);
4065
4066   layout_class (class);
4067   pop_obstacks ();
4068
4069   current_class = save_current_class;
4070   input_filename = save_input_filename;
4071   lineno = save_lineno;
4072   CLASS_LOADED_P (class) = 1;
4073 }
4074
4075 static tree
4076 jdep_resolve_class (dep)
4077      jdep *dep;
4078 {
4079   tree decl;
4080
4081   if (JDEP_RESOLVED_P (dep))
4082     decl = JDEP_RESOLVED_DECL (dep);
4083   else
4084     {
4085       decl = resolve_class (JDEP_TO_RESOLVE (dep), 
4086                             JDEP_DECL (dep), JDEP_WFL (dep));
4087       JDEP_RESOLVED (dep, decl);
4088     }
4089     
4090   if (!decl)
4091     complete_class_report_errors (dep);
4092
4093   return decl;
4094 }
4095
4096 /* Complete unsatisfied class declaration and their dependencies */
4097
4098 void
4099 java_complete_class ()
4100 {
4101   tree cclass;
4102   jdeplist *cclassd;
4103   int error_found;
4104   tree type;
4105
4106   push_obstacks (&permanent_obstack, &permanent_obstack);
4107
4108   /* Process imports and reverse the import on demand list */
4109   process_imports ();
4110   if (ctxp->import_demand_list)
4111     ctxp->import_demand_list = nreverse (ctxp->import_demand_list);
4112
4113   /* Rever things so we have the right order */
4114   ctxp->class_list = nreverse (ctxp->class_list);
4115   ctxp->classd_list = reverse_jdep_list (ctxp);
4116
4117   for (cclassd = ctxp->classd_list, cclass = ctxp->class_list; 
4118        cclass && cclassd; 
4119        cclass = TREE_CHAIN (cclass), cclassd = CLASSD_CHAIN (cclassd))
4120     {
4121       jdep *dep;
4122       for (dep = CLASSD_FIRST (cclassd); dep; dep = JDEP_CHAIN (dep))
4123         {
4124           tree decl;
4125           if (!(decl = jdep_resolve_class (dep)))
4126             continue;
4127
4128           /* Now it's time to patch */
4129           switch (JDEP_KIND (dep))
4130             {
4131             case JDEP_SUPER:
4132               /* Simply patch super */
4133               if (parser_check_super (decl, JDEP_DECL (dep), JDEP_WFL (dep)))
4134                 continue;
4135               BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO 
4136                 (TREE_TYPE (JDEP_DECL (dep)))), 0)) = TREE_TYPE (decl);
4137               break;
4138
4139             case JDEP_FIELD:
4140               {
4141                 /* We do part of the job done in add_field */
4142                 tree field_decl = JDEP_DECL (dep);
4143                 tree field_type = TREE_TYPE (decl);
4144                 push_obstacks (&permanent_obstack, &permanent_obstack);
4145                 if (TREE_CODE (field_type) == RECORD_TYPE)
4146                   field_type = promote_type (field_type);
4147                 pop_obstacks ();
4148                 TREE_TYPE (field_decl) = field_type;
4149                 DECL_ALIGN (field_decl) = 0;
4150                 layout_decl (field_decl, 0);
4151                 SOURCE_FRONTEND_DEBUG 
4152                   (("Completed field/var decl `%s' with `%s'",
4153                     IDENTIFIER_POINTER (DECL_NAME (field_decl)),
4154                     IDENTIFIER_POINTER (DECL_NAME (decl))));
4155                 break;
4156               }
4157             case JDEP_METHOD:   /* We start patching a method */
4158             case JDEP_METHOD_RETURN:
4159               error_found = 0;
4160               while (1)
4161                 {
4162                   if (decl)
4163                     {
4164                       type = TREE_TYPE(decl);
4165                       if (TREE_CODE (type) == RECORD_TYPE)
4166                         type = promote_type (type);
4167                       JDEP_APPLY_PATCH (dep, type);
4168                       SOURCE_FRONTEND_DEBUG 
4169                         (((JDEP_KIND (dep) == JDEP_METHOD_RETURN ?
4170                            "Completing fct `%s' with ret type `%s'":
4171                            "Completing arg `%s' with type `%s'"),
4172                           IDENTIFIER_POINTER (EXPR_WFL_NODE 
4173                                               (JDEP_DECL_WFL (dep))),
4174                           IDENTIFIER_POINTER (DECL_NAME (decl))));
4175                     }
4176                   else
4177                     error_found = 1;
4178                   dep = JDEP_CHAIN (dep);
4179                   if (JDEP_KIND (dep) == JDEP_METHOD_END)
4180                     break;
4181                   else
4182                     decl = jdep_resolve_class (dep);
4183                 }
4184               if (!error_found)
4185                 {
4186                   tree mdecl = JDEP_DECL (dep), signature;
4187                   push_obstacks (&permanent_obstack, &permanent_obstack);
4188                   /* Recompute and reset the signature */
4189                   signature = build_java_signature (TREE_TYPE (mdecl));
4190                   set_java_signature (TREE_TYPE (mdecl), signature);
4191                   pop_obstacks ();
4192                 }
4193               else
4194                 continue;
4195               break;
4196
4197             case JDEP_INTERFACE:
4198               if (parser_check_super_interface (decl, JDEP_DECL (dep),
4199                                                 JDEP_WFL (dep)))
4200                 continue;
4201               parser_add_interface (JDEP_DECL (dep), decl, JDEP_WFL (dep));
4202               break;
4203
4204             case JDEP_PARM:
4205             case JDEP_VARIABLE:
4206               type = TREE_TYPE(decl);
4207               if (TREE_CODE (type) == RECORD_TYPE)
4208                 type = promote_type (type);
4209               JDEP_APPLY_PATCH (dep, type);
4210               break;
4211
4212             case JDEP_TYPE:
4213               JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
4214               SOURCE_FRONTEND_DEBUG 
4215                 (("Completing a random type dependency on a '%s' node",
4216                   tree_code_name [TREE_CODE (JDEP_DECL (dep))]));
4217               break;
4218
4219             case JDEP_EXCEPTION:
4220               JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
4221               SOURCE_FRONTEND_DEBUG 
4222                 (("Completing `%s' `throws' argument node",
4223                   IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)))));
4224               break;
4225
4226             default:
4227               fatal ("Can't handle patch code %d - java_complete_class",
4228                      JDEP_KIND (dep));
4229             }
4230         }
4231     }
4232   pop_obstacks ();
4233   return;
4234 }
4235
4236 /* Resolve class CLASS_TYPE. Handle the case of trying to resolve an
4237    array.  */
4238
4239 static tree
4240 resolve_class (class_type, decl, cl)
4241      tree class_type, decl, cl;
4242 {
4243   const char *name = IDENTIFIER_POINTER (TYPE_NAME (class_type));
4244   const char *base = name;
4245   tree resolved_type = TREE_TYPE (class_type);
4246   tree resolved_type_decl;
4247   
4248   if (resolved_type != NULL_TREE)
4249     {
4250       tree resolved_type_decl = TYPE_NAME (resolved_type);
4251       if (resolved_type_decl == NULL_TREE
4252           || TREE_CODE (resolved_type_decl) == IDENTIFIER_NODE)
4253         {
4254           resolved_type_decl = build_decl (TYPE_DECL,
4255                                            TYPE_NAME (class_type),
4256                                            resolved_type);
4257         }
4258       return resolved_type_decl;
4259     }
4260
4261   /* 1- Check to see if we have an array. If true, find what we really
4262      want to resolve  */
4263   while (name[0] == '[')
4264     name++;
4265   if (base != name)
4266     TYPE_NAME (class_type) = get_identifier (name);
4267
4268   /* 2- Resolve the bare type */
4269   if (!(resolved_type_decl = do_resolve_class (class_type, decl, cl)))
4270     return NULL_TREE;
4271   resolved_type = TREE_TYPE (resolved_type_decl);
4272
4273   /* 3- If we have and array, reconstruct the array down to its nesting */
4274   if (base != name)
4275     {
4276       while (base != name)
4277         {
4278           if (TREE_CODE (resolved_type) == RECORD_TYPE)
4279             resolved_type  = promote_type (resolved_type);
4280           resolved_type = build_java_array_type (resolved_type, -1);
4281           CLASS_LOADED_P (resolved_type) = 1;
4282           name--;
4283         }
4284       /* Build a fake decl for this, since this is what is expected to
4285          be returned.  */
4286       resolved_type_decl =
4287         build_decl (TYPE_DECL, TYPE_NAME (resolved_type), resolved_type);
4288       /* Figure how those two things are important for error report. FIXME */
4289       DECL_SOURCE_LINE (resolved_type_decl) = 0;
4290       DECL_SOURCE_FILE (resolved_type_decl) = input_filename;
4291       TYPE_NAME (class_type) = TYPE_NAME (resolved_type);
4292     }
4293   TREE_TYPE (class_type) = resolved_type;
4294   return resolved_type_decl;
4295 }
4296
4297 /* Effectively perform the resolution of class CLASS_TYPE. DECL or CL
4298    are used to report error messages.  */
4299
4300 tree
4301 do_resolve_class (class_type, decl, cl)
4302      tree class_type;
4303      tree decl;
4304      tree cl;
4305 {
4306   tree new_class_decl;
4307   tree original_name = NULL_TREE;
4308
4309   /* Do not try to replace TYPE_NAME (class_type) by a variable, since
4310      its is changed by find_in_imports{_on_demand} */
4311
4312   /* 1- Check for the type in single imports */
4313   if (find_in_imports (class_type))
4314     return NULL_TREE;
4315
4316   /* 2- And check for the type in the current compilation unit. If it fails,
4317      try with a name qualified with the package name if appropriate. */
4318   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
4319     {
4320       if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
4321           !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
4322         load_class (TYPE_NAME (class_type), 0);
4323       return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
4324     }
4325
4326   original_name = TYPE_NAME (class_type);
4327   if (!QUALIFIED_P (TYPE_NAME (class_type)) && ctxp->package)
4328     TYPE_NAME (class_type) = merge_qualified_name (ctxp->package, 
4329                                                    TYPE_NAME (class_type));
4330 #if 1
4331   if (!(new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
4332     load_class (TYPE_NAME (class_type), 0);
4333   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
4334     {
4335       if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
4336           !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
4337         load_class (TYPE_NAME (class_type), 0);
4338       return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
4339     }
4340 #else
4341   new_name = TYPE_NAME (class_type);
4342   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (new_name)) != NULL_TREE)
4343     {
4344       if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
4345           !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
4346         load_class (new_name, 0);
4347       return IDENTIFIER_CLASS_VALUE (new_name);
4348     }
4349   else
4350     {
4351       tree class = read_class (new_name);
4352       if (class != NULL_TREE)
4353         {
4354           tree decl = IDENTIFIER_CLASS_VALUE (new_name);
4355           if (decl == NULL_TREE)
4356             decl = push_class (class, new_name);
4357           return decl;
4358         }
4359     }
4360 #endif
4361   TYPE_NAME (class_type) = original_name;
4362
4363   /* 3- Check an other compilation unit that bears the name of type */
4364   load_class (TYPE_NAME (class_type), 0);
4365   if (check_pkg_class_access (TYPE_NAME (class_type), 
4366                               (cl ? cl : lookup_cl (decl))))
4367     return NULL_TREE;
4368
4369   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
4370     return new_class_decl;
4371
4372   /* 4- Check the import on demands. Don't allow bar.baz to be
4373      imported from foo.* */
4374   if (!QUALIFIED_P (TYPE_NAME (class_type)))
4375     if (find_in_imports_on_demand (class_type))
4376       return NULL_TREE;
4377
4378   /* 5- Last call for a resolution */
4379   return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
4380 }
4381
4382 /* Resolve NAME and lay it out (if not done and if not the current
4383    parsed class). Return a decl node. This function is meant to be
4384    called when type resolution is necessary during the walk pass.  */
4385
4386 static tree
4387 resolve_and_layout (something, cl)
4388      tree something;
4389      tree cl;
4390 {
4391   tree decl;
4392
4393   /* Don't do that on the current class */
4394   if (something == current_class)
4395     return TYPE_NAME (current_class);
4396
4397   /* Don't do anything for void and other primitive types */
4398   if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
4399     return NULL_TREE;
4400
4401   /* Pointer types can be reall pointer types or fake pointers. When
4402      finding a real pointer, recheck for primitive types */
4403   if (TREE_CODE (something) == POINTER_TYPE)
4404     {
4405       if (TREE_TYPE (something))
4406         {
4407           something = TREE_TYPE (something);
4408           if (JPRIMITIVE_TYPE_P (something) || something == void_type_node)
4409             return NULL_TREE;
4410         }
4411       else
4412         something = TYPE_NAME (something);
4413     }
4414
4415   /* Don't do anything for arrays of primitive types */
4416   if (TREE_CODE (something) == RECORD_TYPE && TYPE_ARRAY_P (something)
4417       && JPRIMITIVE_TYPE_P (TYPE_ARRAY_ELEMENT (something)))
4418     return NULL_TREE;
4419
4420   /* If something is not and IDENTIFIER_NODE, it can be a a TYPE_DECL
4421      or a real TYPE */
4422   if (TREE_CODE (something) != IDENTIFIER_NODE)
4423     something = (TREE_CODE (TYPE_NAME (something)) == TYPE_DECL ?
4424             DECL_NAME (TYPE_NAME (something)) : TYPE_NAME (something));
4425
4426   if (!(decl = resolve_no_layout (something, cl)))
4427     return NULL_TREE;
4428
4429   /* Resolve and layout if necessary */
4430   layout_class_methods (TREE_TYPE (decl));
4431   /* Check methods, but only once */
4432   if (CLASS_FROM_SOURCE_P (TREE_TYPE (decl)) 
4433       && !CLASS_LOADED_P (TREE_TYPE (decl)))
4434     CHECK_METHODS (decl);
4435   if (TREE_TYPE (decl) != current_class && !CLASS_LOADED_P (TREE_TYPE (decl)))
4436     safe_layout_class (TREE_TYPE (decl));
4437
4438   return decl;
4439 }
4440
4441 /* Resolve a class, returns its decl but doesn't perform any
4442    layout. The current parsing context is saved and restored */
4443
4444 static tree
4445 resolve_no_layout (name, cl)
4446      tree name, cl;
4447 {
4448   tree ptr, decl;
4449   BUILD_PTR_FROM_NAME (ptr, name);
4450   java_parser_context_save_global ();
4451   decl = resolve_class (ptr, NULL_TREE, cl);
4452   java_parser_context_restore_global ();
4453   
4454   return decl;
4455 }
4456
4457 /* Called when reporting errors. Skip leader '[' in a complex array
4458    type description that failed to be resolved.  */
4459
4460 static const char *
4461 purify_type_name (name)
4462      const char *name;
4463 {
4464   while (*name && *name == '[')
4465     name++;
4466   return name;
4467 }
4468
4469 /* The type CURRENT refers to can't be found. We print error messages.  */
4470
4471 static void
4472 complete_class_report_errors (dep)
4473      jdep *dep;
4474 {
4475   const char *name;
4476
4477   if (!JDEP_WFL (dep))
4478     return;
4479
4480   name = IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)));
4481   switch (JDEP_KIND (dep))
4482     {
4483     case JDEP_SUPER:
4484       parse_error_context  
4485         (JDEP_WFL (dep), "Superclass `%s' of class `%s' not found",
4486          purify_type_name (name),
4487          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
4488       break;
4489     case JDEP_FIELD:
4490       parse_error_context
4491         (JDEP_WFL (dep), "Type `%s' not found in declaration of field `%s'",
4492          purify_type_name (name),
4493          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
4494       break;
4495     case JDEP_METHOD:           /* Covers arguments */
4496       parse_error_context
4497         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the "
4498          "argument `%s' of method `%s'",
4499          purify_type_name (name),
4500          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))),
4501          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_MISC (dep))));
4502       break;
4503     case JDEP_METHOD_RETURN:    /* Covers return type */
4504       parse_error_context
4505         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the "
4506          "return type of method `%s'", 
4507          purify_type_name (name),
4508          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))));
4509       break;
4510     case JDEP_INTERFACE:
4511       parse_error_context
4512         (JDEP_WFL (dep), "Superinterface `%s' of %s `%s' not found",
4513          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))),
4514          (CLASS_OR_INTERFACE (JDEP_DECL (dep), "class", "interface")),
4515          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
4516       break;
4517     case JDEP_VARIABLE:
4518       parse_error_context
4519         (JDEP_WFL (dep), "Type `%s' not found in the declaration of the "
4520          "local variable `%s'", 
4521          purify_type_name (IDENTIFIER_POINTER 
4522                            (EXPR_WFL_NODE (JDEP_WFL (dep)))),
4523          IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
4524       break;
4525     case JDEP_EXCEPTION:        /* As specified by `throws' */
4526       parse_error_context 
4527           (JDEP_WFL (dep), "Class `%s' not found in `throws'",
4528          IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))));
4529       break;
4530     default:
4531       /* Fix for -Wall. Just break doing nothing. The error will be
4532          caught later */
4533       break;
4534     }
4535 }
4536
4537 /* Check uninitialized final.  */
4538
4539 void
4540 java_check_final ()
4541 {
4542 }
4543
4544 /* Return a static string containing the DECL prototype string. If
4545    DECL is a constructor, use the class name instead of the form
4546    <init> */
4547
4548 static const char *
4549 get_printable_method_name (decl)
4550      tree decl;
4551 {
4552   const char *to_return;
4553   tree name = NULL_TREE;
4554
4555   if (DECL_CONSTRUCTOR_P (decl))
4556     {
4557       name = DECL_NAME (decl);
4558       DECL_NAME (decl) = DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)));
4559     }
4560       
4561   to_return = lang_printable_name (decl, 0);
4562   if (DECL_CONSTRUCTOR_P (decl))
4563     DECL_NAME (decl) = name;
4564   
4565   return to_return;
4566 }
4567
4568 /* Reinstall the proper DECL_NAME on METHOD. Return 0 if the method
4569    nevertheless needs to be verfied, 1 otherwise.  */
4570
4571 static int
4572 reset_method_name (method)
4573      tree method;
4574 {
4575   if (!IS_CLINIT (method) && DECL_NAME (method) != finit_identifier_node)
4576     {
4577       /* NAME is just the plain name when Object is being defined */
4578       if (DECL_CONTEXT (method) != object_type_node)
4579         DECL_NAME (method) = (DECL_CONSTRUCTOR_P (method) ? 
4580                               init_identifier_node : GET_METHOD_NAME (method));
4581       return 0;
4582     }
4583   else 
4584     return 1;
4585 }
4586
4587 /* Return the name of METHOD_DECL, when DECL_NAME is a WFL */
4588
4589 tree
4590 java_get_real_method_name (method_decl)
4591      tree method_decl;
4592 {
4593   tree method_name = DECL_NAME (method_decl);
4594   if (DECL_CONSTRUCTOR_P (method_decl))
4595     return init_identifier_node;
4596
4597   /* Explain here why METHOD_DECL doesn't have the DECL_CONSTRUCTUR_P
4598      and still can be a constructor. FIXME */
4599
4600   /* Don't confuse method only bearing the name of their class as
4601      constructors */
4602   else if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (method_decl))
4603            && ctxp
4604            && ctxp->current_parsed_class_un == EXPR_WFL_NODE (method_name)
4605            && get_access_flags_from_decl (method_decl) <= ACC_PROTECTED
4606            && TREE_TYPE (TREE_TYPE (method_decl)) == void_type_node)
4607     return init_identifier_node;
4608   else
4609     return EXPR_WFL_NODE (method_name);
4610 }
4611
4612 /* Track method being redefined inside the same class. As a side
4613    effect, set DECL_NAME to an IDENTIFIER (prior entering this
4614    function it's a FWL, so we can track errors more accurately.)  */
4615
4616 static int
4617 check_method_redefinition (class, method)
4618      tree class, method;
4619 {
4620   tree redef, name;
4621   tree cl = DECL_NAME (method);
4622   tree sig = TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (method));
4623   /* decl name of artificial <clinit> and $finit$ doesn't need to be
4624      fixed and checked */
4625
4626   /* Reset the method name before running the check. If it returns 1,
4627      the method doesn't need to be verified with respect to method
4628      redeclaration and we return 0 */
4629   if (reset_method_name (method))
4630     return 0;
4631
4632   name = DECL_NAME (method);
4633   for (redef = TYPE_METHODS (class); redef; redef = TREE_CHAIN (redef))
4634     {
4635       if (redef == method)
4636         break;
4637       if (DECL_NAME (redef) == name 
4638           && sig == TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (redef)))
4639         {
4640           parse_error_context 
4641             (cl, "Duplicate %s declaration `%s'",
4642              (DECL_CONSTRUCTOR_P (redef) ? "constructor" : "method"),
4643              get_printable_method_name (redef));
4644           return 1;
4645         }
4646     }
4647   return 0;
4648 }
4649
4650 static void
4651 check_abstract_method_definitions (do_interface, class_decl, type)
4652      int do_interface;
4653      tree class_decl, type;
4654 {
4655   tree class = TREE_TYPE (class_decl);
4656   tree method, end_type;
4657
4658   end_type = (do_interface ? object_type_node : type);
4659   for (method = TYPE_METHODS (type); method; method = TREE_CHAIN (method))
4660     {
4661       tree other_super, other_method, method_sig, method_name;
4662       int found = 0;
4663       
4664       if (!METHOD_ABSTRACT (method) || METHOD_FINAL (method))
4665         continue;
4666       
4667       /* Now verify that somewhere in between TYPE and CLASS,
4668          abstract method METHOD gets a non abstract definition
4669          that is inherited by CLASS.  */
4670       
4671       method_sig = build_java_signature (TREE_TYPE (method));
4672       method_name = DECL_NAME (method);
4673       if (TREE_CODE (method_name) == EXPR_WITH_FILE_LOCATION)
4674         method_name = EXPR_WFL_NODE (method_name);
4675
4676       for (other_super = class; other_super != end_type; 
4677            other_super = CLASSTYPE_SUPER (other_super))
4678         {
4679           for (other_method = TYPE_METHODS (other_super); other_method;
4680                other_method = TREE_CHAIN (other_method))
4681             {
4682               tree s = build_java_signature (TREE_TYPE (other_method));
4683               tree other_name = DECL_NAME (other_method);
4684
4685               if (TREE_CODE (other_name) == EXPR_WITH_FILE_LOCATION)
4686                 other_name = EXPR_WFL_NODE (other_name);
4687               if (!IS_CLINIT (other_method)
4688                   && !DECL_CONSTRUCTOR_P (other_method)
4689                   && method_name == other_name && method_sig == s)
4690                 {
4691                   found = 1;
4692                   break;
4693                 }
4694             }
4695         }
4696       
4697       /* Report that abstract METHOD didn't find an implementation
4698          that CLASS can use. */
4699       if (!found)
4700         {
4701           char *t = xstrdup (lang_printable_name 
4702                             (TREE_TYPE (TREE_TYPE (method)), 0));
4703           tree ccn = DECL_NAME (TYPE_NAME (DECL_CONTEXT (method)));
4704           tree saved_wfl = NULL_TREE;
4705           
4706           if (TREE_CODE (DECL_NAME (method)) == EXPR_WITH_FILE_LOCATION)
4707             {
4708               saved_wfl = DECL_NAME (method);
4709               DECL_NAME (method) = EXPR_WFL_NODE (DECL_NAME (method));
4710             }
4711           
4712           parse_error_context 
4713             (lookup_cl (class_decl),
4714              "Class `%s' doesn't define the abstract method `%s %s' from "
4715              "%s `%s'. This method must be defined or %s `%s' must be "
4716              "declared abstract",
4717              IDENTIFIER_POINTER (DECL_NAME (class_decl)),
4718              t, lang_printable_name (method, 0), 
4719              (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))) ? 
4720               "interface" : "class"),
4721              IDENTIFIER_POINTER (ccn),
4722              (CLASS_INTERFACE (class_decl) ? "interface" : "class"),
4723              IDENTIFIER_POINTER (DECL_NAME (class_decl)));
4724           
4725           free (t);
4726           
4727           if (saved_wfl)
4728             DECL_NAME (method) = saved_wfl;
4729         }
4730     }
4731 }
4732
4733 /* Check that CLASS_DECL somehoow implements all inherited abstract
4734    methods.  */
4735
4736 static void
4737 java_check_abstract_method_definitions (class_decl)
4738      tree class_decl;
4739 {
4740   tree class = TREE_TYPE (class_decl);
4741   tree super, vector;
4742   int i;
4743
4744   if (CLASS_ABSTRACT (class_decl))
4745     return;
4746
4747   /* Check for inherited types */
4748   for (super = CLASSTYPE_SUPER (class); super != object_type_node; 
4749        super = CLASSTYPE_SUPER (super))
4750     {
4751       if (!CLASS_ABSTRACT (TYPE_NAME (super)))
4752         continue;
4753
4754       check_abstract_method_definitions (0, class_decl, super);
4755     }
4756
4757   /* Check for implemented interfaces. */
4758   vector = TYPE_BINFO_BASETYPES (class);
4759   for (i = 1; i < TREE_VEC_LENGTH (vector); i++)
4760     {
4761       super = BINFO_TYPE (TREE_VEC_ELT (vector, i));
4762       check_abstract_method_definitions (1, class_decl, super);
4763     }
4764 }
4765
4766 /* Check all the methods of CLASS_DECL. Methods are first completed
4767    then checked according to regular method existance rules.  If no
4768    constructor for CLASS_DECL were encountered, then build its
4769    declaration.  */
4770
4771 static void
4772 java_check_regular_methods (class_decl)
4773      tree class_decl;
4774 {
4775   int saw_constructor = 0;
4776   tree method;
4777   tree class = CLASS_TO_HANDLE_TYPE (TREE_TYPE (class_decl));
4778   tree super_class = CLASSTYPE_SUPER (class);
4779   tree saved_found_wfl = NULL_TREE, found = NULL_TREE;
4780   tree mthrows;
4781
4782   /* It is not necessary to check methods defined in java.lang.Object */
4783   if (class == object_type_node)
4784     return;
4785
4786   if (!TYPE_NVIRTUALS (class))
4787     TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
4788
4789   /* Should take interfaces into account. FIXME */
4790   for (method = TYPE_METHODS (class); method; method = TREE_CHAIN (method))
4791     {
4792       tree sig;
4793       tree method_wfl = DECL_NAME (method);
4794       int aflags;
4795
4796       /* If we previously found something and its name was saved,
4797          reinstall it now */
4798       if (found && saved_found_wfl)
4799         {
4800           DECL_NAME (found) = saved_found_wfl;
4801           saved_found_wfl = NULL_TREE;
4802         }
4803
4804       /* Check for redefinitions */
4805       if (check_method_redefinition (class, method))
4806         continue;
4807
4808       /* If we see one constructor a mark so we don't generate the
4809          default one. Also skip other verifications: constructors
4810          can't be inherited hence hiden or overriden */
4811      if (DECL_CONSTRUCTOR_P (method))
4812        {
4813          saw_constructor = 1;
4814          continue;
4815        }
4816
4817       /* We verify things thrown by the method. They must inherits from
4818          java.lang.Throwable */
4819       for (mthrows = DECL_FUNCTION_THROWS (method);
4820            mthrows; mthrows = TREE_CHAIN (mthrows))
4821         {
4822           if (!inherits_from_p (TREE_VALUE (mthrows), throwable_type_node))
4823             parse_error_context 
4824               (TREE_PURPOSE (mthrows), "Class `%s' in `throws' clause must be "
4825                "a subclass of class `java.lang.Throwable'",
4826                IDENTIFIER_POINTER 
4827                  (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))));
4828         }
4829
4830       sig = build_java_argument_signature (TREE_TYPE (method));
4831       found = lookup_argument_method (super_class, DECL_NAME (method), sig);
4832
4833       /* Nothing overrides or it's a private method. */
4834       if (!found)
4835         continue;
4836       if (METHOD_PRIVATE (found))
4837         {
4838           found = NULL_TREE;
4839           continue;
4840         }
4841
4842       /* If found wasn't verified, it's DECL_NAME won't be set properly. 
4843          We set it temporarily for the sake of the error report. */
4844       saved_found_wfl = DECL_NAME (found);
4845       reset_method_name (found);
4846
4847       /* Can't override a method with the same name and different return
4848          types. */
4849       if (TREE_TYPE (TREE_TYPE (found)) != TREE_TYPE (TREE_TYPE (method)))
4850         {
4851           char *t = xstrdup (lang_printable_name (TREE_TYPE (TREE_TYPE (found)),
4852                                                  0));
4853           parse_error_context 
4854             (method_wfl,
4855              "Method `%s' was defined with return type `%s' in class `%s'", 
4856              lang_printable_name (found, 0), t,
4857              IDENTIFIER_POINTER 
4858                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
4859           free (t);
4860         }
4861
4862       aflags = get_access_flags_from_decl (found);
4863       /* If the method has default, access in an other package, then
4864          issue a warning that the current method doesn't override the
4865          one that was found elsewhere. Do not issue this warning when
4866          the match was found in java.lang.Object.  */
4867       if (DECL_CONTEXT (found) != object_type_node
4868           && ((aflags & 0x7) == 0)
4869           && !class_in_current_package (DECL_CONTEXT (found))
4870           && DECL_NAME (found) != clinit_identifier_node
4871           && flag_not_overriding)
4872         {
4873           parse_warning_context 
4874             (method_wfl, "Method `%s' in class `%s' does not "
4875              "override the corresponding method in class `%s', which is "
4876              "private to a different package",
4877              lang_printable_name (found, 0),
4878              IDENTIFIER_POINTER (DECL_NAME (class_decl)),
4879              IDENTIFIER_POINTER (DECL_NAME 
4880                                  (TYPE_NAME (DECL_CONTEXT (found)))));
4881           continue;
4882         }
4883
4884       /* Can't override final. Can't override static. */
4885       if (METHOD_FINAL (found) || METHOD_STATIC (found))
4886         {
4887           /* Static *can* override static */
4888           if (METHOD_STATIC (found) && METHOD_STATIC (method))
4889             continue;
4890           parse_error_context 
4891             (method_wfl,
4892              "%s methods can't be overriden. Method `%s' is %s in class `%s'",
4893              (METHOD_FINAL (found) ? "Final" : "Static"),
4894              lang_printable_name (found, 0),
4895              (METHOD_FINAL (found) ? "final" : "static"),
4896              IDENTIFIER_POINTER
4897                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
4898           continue;
4899         }
4900
4901       /* Static method can't override instance method. */
4902       if (METHOD_STATIC (method))
4903         {
4904           parse_error_context 
4905             (method_wfl,
4906              "Instance methods can't be overriden by a static method. Method "
4907              "`%s' is an instance method in class `%s'",
4908              lang_printable_name (found, 0),
4909              IDENTIFIER_POINTER
4910                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
4911           continue;
4912         }
4913
4914       /* - Overriding/hiding public must be public
4915          - Overriding/hiding protected must be protected or public
4916          - If the overriden or hidden method has default (package)
4917            access, then the overriding or hiding method must not be
4918            private; otherwise, a compile-time error occurs */
4919       if ((METHOD_PUBLIC (found) && !METHOD_PUBLIC (method)) 
4920           || (METHOD_PROTECTED (found) 
4921               && !(METHOD_PUBLIC (method) || METHOD_PROTECTED (method)))
4922           || (!(aflags & (ACC_PUBLIC | ACC_PRIVATE | ACC_STATIC))
4923               && METHOD_PRIVATE (method)))
4924         {
4925           parse_error_context 
4926             (method_wfl,
4927              "Methods can't be overridden to be more private. Method `%s' is "
4928              "not %s in class `%s'", lang_printable_name (method, 0),
4929              (METHOD_PUBLIC (method) ? "public" : 
4930               (METHOD_PRIVATE (method) ? "private" : "protected")),
4931              IDENTIFIER_POINTER (DECL_NAME 
4932                                  (TYPE_NAME (DECL_CONTEXT (found)))));
4933           continue;
4934         }
4935
4936       /* Overriding methods must have compatible `throws' clauses on checked
4937          exceptions, if any */
4938       check_throws_clauses (method, method_wfl, found);
4939
4940       /* Inheriting multiple methods with the same signature. FIXME */
4941     }
4942   
4943   /* Don't forget eventual pending found and saved_found_wfl. Take
4944      into account that we might have exited because we saw an
4945      artificial method as the last entry. */
4946
4947   if (found && !DECL_ARTIFICIAL (found) && saved_found_wfl)
4948     DECL_NAME (found) = saved_found_wfl;
4949
4950   if (!TYPE_NVIRTUALS (class))
4951     TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
4952
4953   /* Search for inherited abstract method not yet implemented in this
4954      class.  */
4955   java_check_abstract_method_definitions (class_decl);
4956
4957   if (!saw_constructor)
4958     fatal ("No constructor found");
4959 }
4960
4961 /* Return a non zero value if the `throws' clause of METHOD (if any)
4962    is incompatible with the `throws' clause of FOUND (if any).  */
4963
4964 static void
4965 check_throws_clauses (method, method_wfl, found)
4966      tree method, method_wfl, found;
4967 {
4968   tree mthrows, fthrows;
4969
4970   /* Can't check these things with class loaded from bytecode. FIXME */
4971   if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (found)))
4972     return;
4973
4974   for (mthrows = DECL_FUNCTION_THROWS (method);
4975        mthrows; mthrows = TREE_CHAIN (mthrows))
4976     {
4977       /* We don't verify unchecked expressions */
4978       if (IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (mthrows)))
4979         continue;
4980       /* Checked expression must be compatible */
4981       for (fthrows = DECL_FUNCTION_THROWS (found); 
4982            fthrows; fthrows = TREE_CHAIN (fthrows))
4983         if (inherits_from_p (TREE_VALUE (mthrows), TREE_VALUE (fthrows)))
4984           break;
4985       if (!fthrows)
4986         {
4987           parse_error_context 
4988             (method_wfl, "Invalid checked exception class `%s' in "
4989              "`throws' clause. The exception must be a subclass of an "
4990              "exception thrown by `%s' from class `%s'",
4991              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))),
4992              lang_printable_name (found, 0),
4993              IDENTIFIER_POINTER 
4994                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
4995         }
4996     }
4997 }
4998
4999 /* Check abstract method of interface INTERFACE */
5000
5001 static void
5002 java_check_abstract_methods (interface_decl)
5003      tree interface_decl;
5004 {
5005   int i, n;
5006   tree method, basetype_vec, found;
5007   tree interface = TREE_TYPE (interface_decl);
5008
5009   for (method = TYPE_METHODS (interface); method; method = TREE_CHAIN (method))
5010     {
5011       tree method_wfl = DECL_NAME (method);
5012
5013       /* 2- Check for double definition inside the defining interface */
5014       if (check_method_redefinition (interface, method))
5015         continue;
5016
5017       /* 3- Overriding is OK as far as we preserve the return type and
5018          the thrown exceptions (FIXME) */
5019       found = lookup_java_interface_method2 (interface, method);
5020       if (found)
5021         {
5022           char *t;
5023           tree saved_found_wfl = DECL_NAME (found);
5024           reset_method_name (found);
5025           t = xstrdup (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
5026           parse_error_context 
5027             (method_wfl,
5028              "Method `%s' was defined with return type `%s' in class `%s'",
5029              lang_printable_name (found, 0), t,
5030              IDENTIFIER_POINTER 
5031                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
5032           free (t);
5033           continue;
5034           
5035           DECL_NAME (found) = saved_found_wfl;
5036         }
5037     }
5038
5039   /* 4- Inherited methods can't differ by their returned types */
5040   if (!(basetype_vec = TYPE_BINFO_BASETYPES (interface)))
5041     return;
5042   n = TREE_VEC_LENGTH (basetype_vec);
5043   for (i = 0; i < n; i++)
5044     {
5045       tree sub_interface_method, sub_interface;
5046       tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
5047       if (!vec_elt)
5048         continue;
5049       sub_interface = BINFO_TYPE (vec_elt);
5050       for (sub_interface_method = TYPE_METHODS (sub_interface); 
5051            sub_interface_method;
5052            sub_interface_method = TREE_CHAIN (sub_interface_method))
5053         {
5054           found = lookup_java_interface_method2 (interface, 
5055                                                  sub_interface_method);
5056           if (found && (found != sub_interface_method))
5057             {
5058               tree saved_found_wfl = DECL_NAME (found);
5059               reset_method_name (found);
5060               parse_error_context 
5061                 (lookup_cl (sub_interface_method),
5062                  "Interface `%s' inherits method `%s' from interface `%s'. "
5063                  "This method is redefined with a different return type in "
5064                  "interface `%s'",
5065                  IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (interface))),
5066                  lang_printable_name (found, 0),
5067                  IDENTIFIER_POINTER 
5068                    (DECL_NAME (TYPE_NAME 
5069                                (DECL_CONTEXT (sub_interface_method)))),
5070                  IDENTIFIER_POINTER 
5071                    (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
5072               DECL_NAME (found) = saved_found_wfl;
5073             }
5074         }
5075     }
5076 }
5077
5078 /* Lookup methods in interfaces using their name and partial
5079    signature. Return a matching method only if their types differ.  */
5080
5081 static tree
5082 lookup_java_interface_method2 (class, method_decl)
5083      tree class, method_decl;
5084 {
5085   int i, n;
5086   tree basetype_vec = TYPE_BINFO_BASETYPES (class), to_return;
5087
5088   if (!basetype_vec)
5089     return NULL_TREE;
5090
5091   n = TREE_VEC_LENGTH (basetype_vec);
5092   for (i = 0; i < n; i++)
5093     {
5094       tree vec_elt = TREE_VEC_ELT (basetype_vec, i), to_return;
5095       if ((BINFO_TYPE (vec_elt) != object_type_node)
5096           && (to_return = 
5097               lookup_java_method2 (BINFO_TYPE (vec_elt), method_decl, 1)))
5098         return to_return;
5099     }
5100   for (i = 0; i < n; i++)
5101     {
5102       to_return = lookup_java_interface_method2 
5103         (BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i)), method_decl);
5104       if (to_return)
5105         return to_return;
5106     }
5107
5108   return NULL_TREE;
5109 }
5110
5111 /* Lookup method using their name and partial signature. Return a
5112    matching method only if their types differ.  */
5113
5114 static tree
5115 lookup_java_method2 (clas, method_decl, do_interface)
5116      tree clas, method_decl;
5117      int do_interface;
5118 {
5119   tree method, method_signature, method_name, method_type, name;
5120
5121   method_signature = build_java_argument_signature (TREE_TYPE (method_decl));
5122   name = DECL_NAME (method_decl);
5123   method_name = (TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ? 
5124                  EXPR_WFL_NODE (name) : name);
5125   method_type = TREE_TYPE (TREE_TYPE (method_decl));
5126
5127   while (clas != NULL_TREE)
5128     {
5129       for (method = TYPE_METHODS (clas);
5130            method != NULL_TREE;  method = TREE_CHAIN (method))
5131         {
5132           tree method_sig = build_java_argument_signature (TREE_TYPE (method));
5133           tree name = DECL_NAME (method);
5134           if ((TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
5135                EXPR_WFL_NODE (name) : name) == method_name
5136               && method_sig == method_signature 
5137               && TREE_TYPE (TREE_TYPE (method)) != method_type)
5138             return method;
5139         }
5140       clas = (do_interface ? NULL_TREE : CLASSTYPE_SUPER (clas));
5141     }
5142   return NULL_TREE;
5143 }
5144
5145 /* Return the line that matches DECL line number, and try its best to
5146    position the column number. Used during error reports.  */
5147
5148 static tree
5149 lookup_cl (decl)
5150      tree decl;
5151 {
5152   static tree cl = NULL_TREE;
5153   char *line, *found;
5154   
5155   if (!decl)
5156     return NULL_TREE;
5157
5158   if (cl == NULL_TREE)
5159     cl = build_expr_wfl (NULL_TREE, NULL, 0, 0);
5160
5161   EXPR_WFL_FILENAME_NODE (cl) = get_identifier (DECL_SOURCE_FILE (decl));
5162   EXPR_WFL_SET_LINECOL (cl, DECL_SOURCE_LINE_FIRST (decl), -1);
5163
5164   line = java_get_line_col (IDENTIFIER_POINTER (EXPR_WFL_FILENAME_NODE (cl)),
5165                             EXPR_WFL_LINENO (cl), EXPR_WFL_COLNO (cl));
5166
5167   found = strstr ((const char *)line, 
5168                   (const char *)IDENTIFIER_POINTER (DECL_NAME (decl)));
5169   if (found)
5170     EXPR_WFL_SET_LINECOL (cl, EXPR_WFL_LINENO (cl), found - line);
5171
5172   return cl;
5173 }
5174
5175 /* Look for a simple name in the single-type import list */
5176
5177 static tree
5178 find_name_in_single_imports (name)
5179      tree name;
5180 {
5181   tree node;
5182
5183   for (node = ctxp->import_list; node; node = TREE_CHAIN (node))
5184     if (TREE_VALUE (node) == name)
5185       return (EXPR_WFL_NODE (TREE_PURPOSE (node)));
5186
5187   return NULL_TREE;
5188 }
5189
5190 /* Process all single-type import. */
5191
5192 static int
5193 process_imports ()
5194 {
5195   tree import;
5196   int error_found;
5197
5198   for (import = ctxp->import_list; import; import = TREE_CHAIN (import))
5199     {
5200       tree to_be_found = EXPR_WFL_NODE (TREE_PURPOSE (import));
5201
5202       /* Don't load twice something already defined. */
5203       if (IDENTIFIER_CLASS_VALUE (to_be_found))
5204         continue;
5205       QUALIFIED_P (to_be_found) = 1;
5206       load_class (to_be_found, 0);
5207       error_found =
5208         check_pkg_class_access (to_be_found, TREE_PURPOSE (import));
5209       if (!IDENTIFIER_CLASS_VALUE (to_be_found))
5210         {
5211           parse_error_context (TREE_PURPOSE (import),
5212                                "Class or interface `%s' not found in import",
5213                                IDENTIFIER_POINTER (to_be_found));
5214           return 1;
5215         }
5216       if (error_found)
5217         return 1;
5218     }
5219   return 0;
5220 }
5221
5222 /* Possibly find a class imported by a single-type import statement. Return
5223    1 if an error occured, 0 otherwise. */
5224
5225 static int
5226 find_in_imports (class_type)
5227      tree class_type;
5228 {
5229   tree import;
5230
5231   for (import = ctxp->import_list; import; import = TREE_CHAIN (import))
5232     if (TREE_VALUE (import) == TYPE_NAME (class_type))
5233       {
5234         TYPE_NAME (class_type) = EXPR_WFL_NODE (TREE_PURPOSE (import));
5235         QUALIFIED_P (TYPE_NAME (class_type)) = 1;
5236       }
5237   return 0;
5238 }
5239
5240 static int
5241 note_possible_classname (name, len)
5242      const char *name;
5243      int len;
5244 {
5245   tree node;
5246   if (len > 5 && strncmp (&name [len-5], ".java", 5) == 0)
5247     len = len - 5;
5248   else if (len > 6 && strncmp (&name [len-6], ".class", 6) == 0)
5249     len = len - 6;
5250   else
5251     return 0;
5252   node = ident_subst (name, len, "", '/', '.', "");
5253   IS_A_CLASSFILE_NAME (node) = 1; /* Or soon to be */
5254   QUALIFIED_P (node) = strchr (name, '/') ? 1 : 0;
5255   return 1;
5256 }
5257
5258 /* Read a import directory, gathering potential match for further type
5259    references. Indifferently reads a filesystem or a ZIP archive
5260    directory.  */
5261
5262 static void
5263 read_import_dir (wfl)
5264      tree wfl;
5265 {
5266   tree package_id = EXPR_WFL_NODE (wfl);
5267   const char *package_name = IDENTIFIER_POINTER (package_id);
5268   int package_length = IDENTIFIER_LENGTH (package_id);
5269   DIR *dirp = NULL;
5270   JCF *saved_jcf = current_jcf;
5271
5272   int found = 0;
5273   int k;
5274   void *entry;
5275   struct buffer filename[1];
5276
5277
5278   if (IS_AN_IMPORT_ON_DEMAND_P (package_id))
5279     return;
5280   IS_AN_IMPORT_ON_DEMAND_P (package_id) = 1;
5281
5282   BUFFER_INIT (filename);
5283   buffer_grow (filename, package_length + 100);
5284
5285   for (entry = jcf_path_start (); entry != NULL; entry = jcf_path_next (entry))
5286     {
5287       const char *entry_name = jcf_path_name (entry);
5288       int entry_length = strlen (entry_name);
5289       if (jcf_path_is_zipfile (entry))
5290         {
5291           ZipFile *zipf;
5292           buffer_grow (filename, entry_length);
5293           memcpy (filename->data, entry_name, entry_length - 1);
5294           filename->data[entry_length-1] = '\0';
5295           zipf = opendir_in_zip (filename->data, jcf_path_is_system (entry));
5296           if (zipf == NULL)
5297             error ("malformed .zip archive in CLASSPATH: %s", entry_name);
5298           else
5299             {
5300               ZipDirectory *zipd = (ZipDirectory *) zipf->central_directory;
5301               BUFFER_RESET (filename);
5302               for (k = 0; k < package_length; k++)
5303                 {
5304                   char ch = package_name[k];
5305                   *filename->ptr++ = ch == '.' ? '/' : ch;
5306                 }
5307               *filename->ptr++ = '/';
5308
5309               for (k = 0; k < zipf->count;  k++, zipd = ZIPDIR_NEXT (zipd))
5310                 {
5311                   const char *current_entry = ZIPDIR_FILENAME (zipd);
5312                   int current_entry_len = zipd->filename_length;
5313
5314                   if (current_entry_len >= BUFFER_LENGTH (filename)
5315                       && strncmp (filename->data, current_entry, 
5316                                   BUFFER_LENGTH (filename)) != 0)
5317                     continue;
5318                   found |= note_possible_classname (current_entry,
5319                                                     current_entry_len);
5320                 }
5321             }
5322         }
5323       else
5324         {
5325           BUFFER_RESET (filename);
5326           buffer_grow (filename, entry_length + package_length + 4);
5327           strcpy (filename->data, entry_name);
5328           filename->ptr = filename->data + entry_length;
5329           for (k = 0; k < package_length; k++)
5330             {
5331               char ch = package_name[k];
5332               *filename->ptr++ = ch == '.' ? '/' : ch;
5333             }
5334           *filename->ptr = '\0';
5335
5336           dirp = opendir (filename->data);
5337           if (dirp == NULL)
5338             continue;
5339           *filename->ptr++ = '/';
5340           for (;;)
5341             {
5342               int len; 
5343               const char *d_name;
5344               struct dirent *direntp = readdir (dirp);
5345               if (!direntp)
5346                 break;
5347               d_name = direntp->d_name;
5348               len = strlen (direntp->d_name);
5349               buffer_grow (filename, len+1);
5350               strcpy (filename->ptr, d_name);
5351               found |= note_possible_classname (filename->data + entry_length,
5352                                                 package_length+len+1);
5353             }
5354           if (dirp)
5355             closedir (dirp);
5356         }
5357     }
5358
5359   free (filename->data);
5360
5361   /* Here we should have a unified way of retrieving an entry, to be
5362      indexed. */
5363   if (!found)
5364     {
5365       static int first = 1;
5366       if (first)
5367         {
5368           error ("Can't find default package `%s'. Check "
5369                  "the CLASSPATH environment variable and the access to the "
5370                  "archives.", package_name);
5371           java_error_count++;
5372           first = 0;
5373         }
5374       else
5375         parse_error_context (wfl, "Package `%s' not found in import",
5376                              package_name);
5377       current_jcf = saved_jcf;
5378       return;
5379     }
5380   current_jcf = saved_jcf;
5381 }
5382
5383 /* Possibly find a type in the import on demands specified
5384    types. Returns 1 if an error occured, 0 otherwise. Run throught the
5385    entire list, to detected potential double definitions.  */
5386                  
5387 static int
5388 find_in_imports_on_demand (class_type)
5389      tree class_type;
5390 {
5391   tree node, import, node_to_use = NULL_TREE;
5392   int seen_once = -1;
5393   tree cl = NULL_TREE;
5394
5395   for (import = ctxp->import_demand_list; import; import = TREE_CHAIN (import))
5396     {
5397       const char *id_name;
5398       obstack_grow (&temporary_obstack, 
5399                     IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))),
5400                     IDENTIFIER_LENGTH (EXPR_WFL_NODE (TREE_PURPOSE (import))));
5401       obstack_1grow (&temporary_obstack, '.');
5402       obstack_grow0 (&temporary_obstack, 
5403                      IDENTIFIER_POINTER (TYPE_NAME (class_type)),
5404                      IDENTIFIER_LENGTH (TYPE_NAME (class_type)));
5405       id_name = obstack_finish (&temporary_obstack);
5406               
5407       node = maybe_get_identifier (id_name);
5408       if (node && IS_A_CLASSFILE_NAME (node))
5409         {
5410           if (seen_once < 0)
5411             {
5412               cl = TREE_PURPOSE (import);
5413               seen_once = 1;
5414               node_to_use = node;
5415             }
5416           else
5417             {
5418               seen_once++;
5419               parse_error_context 
5420                 (import, "Type `%s' also potentially defined in package `%s'",
5421                  IDENTIFIER_POINTER (TYPE_NAME (class_type)),
5422                  IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))));
5423             }
5424         }
5425     }
5426
5427   if (seen_once == 1)
5428     {
5429       /* Setup lineno so that it refers to the line of the import (in
5430          case we parse a class file and encounter errors */
5431       tree decl;
5432       int saved_lineno = lineno;
5433       lineno = EXPR_WFL_LINENO (cl);
5434       TYPE_NAME (class_type) = node_to_use;
5435       QUALIFIED_P (TYPE_NAME (class_type)) = 1;
5436       decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
5437       /* If there is no DECL set for the class or if the class isn't
5438          loaded and not seen in source yet, the load */
5439       if (!decl || (!CLASS_LOADED_P (TREE_TYPE (decl))
5440                     && !CLASS_FROM_SOURCE_P (TREE_TYPE (decl))))
5441         load_class (node_to_use, 0);
5442       lineno = saved_lineno;
5443       return check_pkg_class_access (TYPE_NAME (class_type), cl);
5444     }
5445   else
5446     return (seen_once < 0 ? 0 : seen_once); /* It's ok not to have found */
5447 }
5448
5449 static tree
5450 resolve_package (pkg, next)
5451      tree pkg, *next;
5452 {
5453   tree current;
5454   tree type_name = NULL_TREE;
5455   const char *name = IDENTIFIER_POINTER (EXPR_WFL_NODE (pkg));
5456
5457   /* The trick is to determine when the package name stops and were
5458      the name of something contained in the package starts. Then we
5459      return a fully qualified name of what we want to get. */
5460
5461   /* Do a quick search on well known package names */
5462   if (!strncmp (name, "java.lang.reflect", 17))
5463     {
5464       *next = 
5465         TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg))));
5466       type_name = lookup_package_type (name, 17);
5467     }
5468   else if (!strncmp (name, "java.lang", 9))
5469     {
5470       *next = TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg)));
5471       type_name = lookup_package_type (name, 9);
5472     }
5473
5474   /* If we found something here, return */
5475   if (type_name)
5476     return type_name; 
5477
5478   *next = EXPR_WFL_QUALIFICATION (pkg);
5479
5480   /* Try the current package. */
5481   if (ctxp->package && !strncmp (name, IDENTIFIER_POINTER (ctxp->package),  
5482                                  IDENTIFIER_LENGTH (ctxp->package)))
5483     {
5484       type_name = 
5485         lookup_package_type_and_set_next (name, 
5486                                           IDENTIFIER_LENGTH (ctxp->package), 
5487                                           next );
5488       if (type_name)
5489         return type_name;
5490     }
5491
5492   /* Search in imported package */
5493   for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
5494     {
5495       tree current_pkg_name = EXPR_WFL_NODE (TREE_PURPOSE (current));
5496       int len = IDENTIFIER_LENGTH (current_pkg_name);
5497       if (!strncmp (name, IDENTIFIER_POINTER (current_pkg_name), len))
5498         {
5499           tree left, dummy;
5500           
5501           breakdown_qualified (&left, &dummy, current_pkg_name);
5502           len = IDENTIFIER_LENGTH (left);
5503           type_name = lookup_package_type_and_set_next (name, len, next);
5504           if (type_name)
5505             break;
5506         }
5507     }
5508
5509   return type_name;
5510 }
5511
5512 static tree
5513 lookup_package_type_and_set_next (name, len, next)
5514      const char *name;
5515      int len;
5516      tree *next;
5517 {
5518   const char *ptr;
5519   tree type_name = lookup_package_type (name, len);
5520
5521   if (!type_name)
5522     return NULL;
5523   
5524   ptr = IDENTIFIER_POINTER (type_name);
5525   while (ptr && (ptr = strchr (ptr, '.'))) 
5526     {
5527       *next = TREE_CHAIN (*next);
5528       ptr++;
5529     }
5530   return type_name;
5531 }
5532
5533 static tree
5534 lookup_package_type (name, from)
5535      const char *name;
5536      int from;
5537 {
5538   char subname [128];
5539   const char *sub = &name[from+1];
5540   while (*sub != '.' && *sub)
5541     sub++;
5542   strncpy (subname, name, sub-name);
5543   subname [sub-name] = '\0';
5544   return get_identifier (subname);
5545 }
5546
5547 /* Check that CLASS_NAME refers to a PUBLIC class. Return 0 if no
5548    access violations were found, 1 otherwise.  */
5549
5550 static int
5551 check_pkg_class_access (class_name, cl)
5552      tree class_name;
5553      tree cl;
5554 {
5555   tree type;
5556
5557   if (!QUALIFIED_P (class_name) || !IDENTIFIER_CLASS_VALUE (class_name))
5558     return 0;
5559
5560   if (!(type = TREE_TYPE (IDENTIFIER_CLASS_VALUE (class_name))))
5561     return 0;
5562
5563   if (!CLASS_PUBLIC (TYPE_NAME (type)))
5564     {
5565       /* Access to a private class within the same package is
5566          allowed. */
5567       tree l, r;
5568       breakdown_qualified (&l, &r, class_name);
5569       if (l == ctxp->package)
5570         return 0;
5571
5572       parse_error_context 
5573         (cl, "Can't access %s `%s'. Only public classes and interfaces in "
5574          "other packages can be accessed",
5575          (CLASS_INTERFACE (TYPE_NAME (type)) ? "interface" : "class"),
5576          IDENTIFIER_POINTER (class_name));
5577       return 1;
5578     }
5579   return 0;
5580 }
5581
5582 /* Local variable declaration. */
5583
5584 static void
5585 declare_local_variables (modifier, type, vlist)
5586      int modifier;
5587      tree type;
5588      tree vlist;
5589 {
5590   tree decl, current, saved_type;
5591   tree type_wfl = NULL_TREE;
5592   int must_chain = 0;
5593
5594   /* Push a new block if statements were seen between the last time we
5595      pushed a block and now. Keep a cound of block to close */
5596   if (BLOCK_EXPR_BODY (GET_CURRENT_BLOCK (current_function_decl)))
5597     {
5598       tree body = GET_CURRENT_BLOCK (current_function_decl);
5599       tree b = enter_block ();
5600       BLOCK_EXPR_ORIGIN (b) = body;
5601     }
5602
5603   if (modifier)
5604     {
5605       int i;
5606       for (i = 0; i <= 10; i++) if (1 << i & modifier) break;
5607       if (modifier == ACC_FINAL)
5608         {
5609           if (flag_static_local_jdk1_1)
5610             parse_warning_context (ctxp->modifier_ctx [i], 
5611                                    "Unsupported JDK1.1 `final' local variable "
5612                                    "(treated as non final)");
5613         }
5614       else 
5615         {
5616           parse_error_context 
5617             (ctxp->modifier_ctx [i], 
5618              "Only `final' is allowed as a local variables modifier");
5619           return;
5620         }
5621     }
5622
5623   /* Obtain an incomplete type if TYPE is not complete. TYPE_WFL will
5624      hold the TYPE value if a new incomplete has to be created (as
5625      opposed to being found already existing and reused). */
5626   SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
5627
5628   /* If TYPE is fully resolved and we don't have a reference, make one */
5629   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
5630
5631   /* Go through all the declared variables */
5632   for (current = vlist, saved_type = type; current;
5633        current = TREE_CHAIN (current), type = saved_type)
5634     {
5635       tree other, real_type;
5636       tree wfl  = TREE_PURPOSE (current);
5637       tree name = EXPR_WFL_NODE (wfl);
5638       tree init = TREE_VALUE (current);
5639
5640       /* Process NAME, as it may specify extra dimension(s) for it */
5641       type = build_array_from_name (type, type_wfl, name, &name);
5642
5643       /* Variable redefinition check */
5644       if ((other = lookup_name_in_blocks (name)))
5645         {
5646           variable_redefinition_error (wfl, name, TREE_TYPE (other),
5647                                        DECL_SOURCE_LINE (other));
5648           continue;
5649         }
5650
5651       /* Type adjustment. We may have just readjusted TYPE because
5652          the variable specified more dimensions. Make sure we have
5653          a reference if we can and don't have one already. */
5654       PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
5655
5656       real_type = GET_REAL_TYPE (type);
5657       /* Never layout this decl. This will be done when its scope
5658          will be entered */
5659       decl = build_decl (VAR_DECL, name, real_type);
5660       BLOCK_CHAIN_DECL (decl);
5661       
5662       /* If doing xreferencing, replace the line number with the WFL
5663          compound value */
5664       if (flag_emit_xref)
5665         DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (wfl);
5666       
5667       /* Don't try to use an INIT statement when an error was found */
5668       if (init && java_error_count)
5669         init = NULL_TREE;
5670       
5671       /* Add the initialization function to the current function's code */
5672       if (init)
5673         {
5674           /* Name might have been readjusted */
5675           EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = name;
5676           MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
5677           java_method_add_stmt (current_function_decl,
5678                                 build_debugable_stmt (EXPR_WFL_LINECOL (init),
5679                                                       init));
5680         }
5681     
5682       /* Setup dependency the type of the decl */
5683       if (must_chain)
5684         {
5685           jdep *dep;
5686           register_incomplete_type (JDEP_VARIABLE, type_wfl, decl, type);
5687           dep = CLASSD_LAST (ctxp->classd_list);
5688           JDEP_GET_PATCH (dep) = &TREE_TYPE (decl);
5689         }
5690     }
5691   SOURCE_FRONTEND_DEBUG (("Defined locals"));
5692 }
5693
5694 /* Called during parsing. Build decls from argument list.  */
5695
5696 static void
5697 source_start_java_method (fndecl)
5698      tree fndecl;
5699 {
5700   tree tem;
5701   tree parm_decl;
5702   int i;
5703
5704   if (!fndecl)
5705     return;
5706
5707   current_function_decl = fndecl;
5708
5709   /* New scope for the function */
5710   enter_block ();
5711   for (tem = TYPE_ARG_TYPES (TREE_TYPE (fndecl)), i = 0;
5712        tem != end_params_node; tem = TREE_CHAIN (tem), i++)
5713     {
5714       tree type = TREE_VALUE (tem);
5715       tree name = TREE_PURPOSE (tem);
5716       
5717       /* If type is incomplete. Create an incomplete decl and ask for
5718          the decl to be patched later */
5719       if (INCOMPLETE_TYPE_P (type))
5720         {
5721           jdep *jdep;
5722           tree real_type = GET_REAL_TYPE (type);
5723           parm_decl = build_decl (PARM_DECL, name, real_type);
5724           type = obtain_incomplete_type (type);
5725           register_incomplete_type (JDEP_PARM, NULL_TREE, NULL_TREE, type);
5726           jdep = CLASSD_LAST (ctxp->classd_list);
5727           JDEP_MISC (jdep) = name;
5728           JDEP_GET_PATCH (jdep) = &TREE_TYPE (parm_decl);
5729         }
5730       else
5731         parm_decl = build_decl (PARM_DECL, name, type);
5732
5733       BLOCK_CHAIN_DECL (parm_decl);
5734     }
5735   tem = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
5736   BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl)) =
5737     nreverse (tem);
5738   DECL_ARG_SLOT_COUNT (current_function_decl) = i;
5739 }
5740
5741 /* Called during parsing. Creates an artificial method declaration.  */
5742
5743 static tree
5744 create_artificial_method (class, flags, type, name, args)
5745      tree class;
5746      int flags;
5747      tree type, name, args;
5748 {
5749   int saved_lineno = lineno;                                        
5750   tree mdecl;
5751
5752   lineno = 0;                                                               
5753   mdecl = make_node (FUNCTION_TYPE);                                
5754   TREE_TYPE (mdecl) = type;
5755   TYPE_ARG_TYPES (mdecl) = args;
5756   mdecl = add_method (class, flags, name, build_java_signature (mdecl)); 
5757   lineno = saved_lineno;                                                    
5758   DECL_ARTIFICIAL (mdecl) = 1;                                      
5759   return mdecl;
5760 }
5761
5762 /* Starts the body if an artifical method.  */
5763
5764 static void
5765 start_artificial_method_body (mdecl)
5766      tree mdecl;
5767 {
5768   DECL_SOURCE_LINE (mdecl) = 1;
5769   DECL_SOURCE_LINE_MERGE (mdecl, 1);
5770   source_start_java_method (mdecl);
5771   enter_block ();
5772 }
5773
5774 static void
5775 end_artificial_method_body (mdecl)
5776      tree mdecl;
5777 {
5778   BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)) = exit_block ();
5779   exit_block ();
5780 }
5781
5782 /* Called during expansion. Push decls formerly built from argument
5783    list so they're usable during expansion. */
5784
5785 static void
5786 expand_start_java_method (fndecl)
5787      tree fndecl;
5788 {
5789   tree tem, *ptr;
5790
5791   current_function_decl = fndecl;
5792
5793   announce_function (fndecl);
5794   pushlevel (1);                /* Push parameters */
5795   ptr = &DECL_ARGUMENTS (fndecl);
5796   tem  = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
5797   while (tem)
5798     {
5799       tree next = TREE_CHAIN (tem);
5800       tree type = TREE_TYPE (tem);
5801       if (PROMOTE_PROTOTYPES
5802           && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
5803           && INTEGRAL_TYPE_P (type))
5804         type = integer_type_node;
5805       DECL_ARG_TYPE (tem) = type;
5806       layout_decl (tem, 0);
5807       pushdecl (tem);
5808       *ptr = tem;
5809       ptr = &TREE_CHAIN (tem);
5810       tem = next;
5811     }
5812   *ptr = NULL_TREE;
5813   pushdecl_force_head (DECL_ARGUMENTS (fndecl));
5814   lineno = DECL_SOURCE_LINE_FIRST (fndecl);
5815 }
5816
5817 /* Terminate a function and expand its body.  */
5818
5819 static void
5820 source_end_java_method ()
5821 {
5822   tree fndecl = current_function_decl;
5823   int flag_asynchronous_exceptions = asynchronous_exceptions;
5824
5825   if (!fndecl)
5826     return;
5827
5828   java_parser_context_save_global ();
5829   lineno = ctxp->last_ccb_indent1;
5830
5831   /* Set EH language codes */
5832   java_set_exception_lang_code ();
5833
5834   /* Turn function bodies with only a NOP expr null, so they don't get
5835      generated at all and we won't get warnings when using the -W
5836      -Wall flags. */
5837   if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) == empty_stmt_node)
5838     BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) = NULL_TREE;
5839
5840   /* Generate function's code */
5841   if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl))
5842       && ! flag_emit_class_files
5843       && ! flag_emit_xref)
5844     expand_expr_stmt (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)));
5845
5846   /* pop out of its parameters */
5847   pushdecl_force_head (DECL_ARGUMENTS (fndecl));
5848   poplevel (1, 0, 1);
5849   BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
5850
5851   /* Generate rtl for function exit.  */
5852   if (! flag_emit_class_files && ! flag_emit_xref)
5853     {
5854       lineno = DECL_SOURCE_LINE_LAST (fndecl);
5855       /* Emit catch-finally clauses */
5856       emit_handlers ();
5857       expand_function_end (input_filename, lineno, 0);
5858
5859       /* FIXME: If the current method contains any exception handlers,
5860          force asynchronous_exceptions: this is necessary because signal
5861          handlers in libjava may throw exceptions.  This is far from being
5862          a perfect solution, but it's better than doing nothing at all.*/
5863       if (catch_clauses)
5864         asynchronous_exceptions = 1;
5865
5866       /* Run the optimizers and output assembler code for this function. */
5867       rest_of_compilation (fndecl);
5868     }
5869
5870   current_function_decl = NULL_TREE;
5871   permanent_allocation (1);
5872   java_parser_context_restore_global ();
5873   asynchronous_exceptions = flag_asynchronous_exceptions;
5874 }
5875
5876 /* Record EXPR in the current function block. Complements compound
5877    expression second operand if necessary.  */
5878
5879 tree
5880 java_method_add_stmt (fndecl, expr)
5881      tree fndecl, expr;
5882 {
5883   if (!GET_CURRENT_BLOCK (fndecl))
5884     return NULL_TREE;
5885   return add_stmt_to_block (GET_CURRENT_BLOCK (fndecl), NULL_TREE, expr);
5886 }
5887
5888 static tree
5889 add_stmt_to_block (b, type, stmt)
5890      tree b, type, stmt;
5891 {
5892   tree body = BLOCK_EXPR_BODY (b), c;
5893   
5894   if (java_error_count)
5895     return body;
5896     
5897   if ((c = add_stmt_to_compound (body, type, stmt)) == body)
5898     return body;
5899
5900   BLOCK_EXPR_BODY (b) = c;
5901   TREE_SIDE_EFFECTS (c) = 1;
5902   return c;
5903 }
5904
5905 /* Add STMT to EXISTING if possible, otherwise create a new
5906    COMPOUND_EXPR and add STMT to it. */
5907
5908 static tree
5909 add_stmt_to_compound (existing, type, stmt)
5910      tree existing, type, stmt;
5911 {
5912   if (existing)
5913     return build (COMPOUND_EXPR, type, existing, stmt);
5914   else
5915     return stmt;
5916 }
5917
5918 /* Hold THIS for the scope of the current public method decl.  */
5919 static tree current_this;
5920
5921 void java_layout_seen_class_methods ()
5922 {
5923   tree previous_list = all_class_list;
5924   tree end = NULL_TREE;
5925   tree current;
5926
5927   while (1)
5928     {
5929       for (current = previous_list; 
5930            current != end; current = TREE_CHAIN (current))
5931         layout_class_methods (TREE_TYPE (TREE_VALUE (current)));
5932       
5933       if (previous_list != all_class_list)
5934         {
5935           end = previous_list;
5936           previous_list = all_class_list;
5937         }
5938       else
5939         break;
5940     }
5941 }
5942
5943 /* Layout the methods of all classes loaded in one way on an
5944    other. Check methods of source parsed classes. Then reorder the
5945    fields and layout the classes or the type of all source parsed
5946    classes */
5947
5948 void
5949 java_layout_classes ()
5950 {
5951   tree current;
5952   int save_error_count = java_error_count;
5953
5954   /* Layout the methods of all classes seen so far */
5955   java_layout_seen_class_methods ();
5956   java_parse_abort_on_error ();
5957   all_class_list = NULL_TREE;
5958
5959   /* Then check the methods of all parsed classes */
5960   for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
5961     if (CLASS_FROM_SOURCE_P (TREE_TYPE (TREE_VALUE (current))))
5962       CHECK_METHODS (TREE_VALUE (current));
5963   java_parse_abort_on_error ();
5964
5965   for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
5966     {
5967       current_class = TREE_TYPE (TREE_VALUE (current));
5968
5969       /* Reverse the fields, but leave the dummy field in front.
5970          Fields are already ordered for Object and Class */
5971       if (TYPE_FIELDS (current_class) && current_class != object_type_node
5972           && current_class != class_type_node)
5973       {
5974         /* If the dummy field is there, reverse the right fields and
5975            just layout the type for proper fields offset */
5976         if (!DECL_NAME (TYPE_FIELDS (current_class)))
5977           {
5978             tree fields = TYPE_FIELDS (current_class);
5979             TREE_CHAIN (fields) = nreverse (TREE_CHAIN (fields));
5980             TYPE_SIZE (current_class) = NULL_TREE;
5981             layout_type (current_class);
5982           }
5983         /* We don't have a dummy field, we need to layout the class,
5984            after having reversed the fields */
5985         else
5986           {
5987             TYPE_FIELDS (current_class) = 
5988               nreverse (TYPE_FIELDS (current_class));
5989             TYPE_SIZE (current_class) = NULL_TREE;
5990             layout_class (current_class);
5991           }
5992       }
5993       else
5994         layout_class (current_class);
5995
5996       /* From now on, the class is considered completely loaded */
5997       CLASS_LOADED_P (current_class) = 1;
5998
5999       /* Error reported by the caller */
6000       if (java_error_count)
6001         return;
6002     }
6003
6004   /* We might have reloaded classes durign the process of laying out
6005      classes for code generation. We must layout the methods of those
6006      late additions, as constructor checks might use them */
6007   java_layout_seen_class_methods ();
6008   java_parse_abort_on_error ();
6009 }
6010
6011 /* Expand all methods in all registered classes.  */
6012
6013 static void
6014 java_complete_expand_methods ()
6015 {
6016   tree current;
6017
6018   do_not_fold = flag_emit_xref;
6019   
6020   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
6021     {
6022       int is_interface;
6023       tree class_type = CLASS_TO_HANDLE_TYPE (TREE_TYPE (current));
6024       tree decl, prev_decl;
6025
6026       current_class = TREE_TYPE (current);
6027       is_interface = CLASS_INTERFACE (TYPE_NAME (current_class));
6028
6029       /* Initialize a new constant pool */
6030       init_outgoing_cpool ();
6031
6032       /* We want <clinit> (if any) to be processed first. */
6033       for (prev_decl = NULL_TREE, decl = TYPE_METHODS (class_type); 
6034            decl; prev_decl= decl, decl = TREE_CHAIN (decl))
6035         if (IS_CLINIT (decl))
6036           {
6037             if (!java_pre_expand_clinit (decl))
6038               {
6039                 if (prev_decl)
6040                   TREE_CHAIN (prev_decl) = TREE_CHAIN (decl);
6041                 else
6042                   TYPE_METHODS (class_type) = TREE_CHAIN (decl);
6043               }
6044             break;
6045           }
6046
6047       /* Now go on for regular business.  */
6048       for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
6049         {
6050           current_function_decl = decl;
6051           /* Don't generate debug info on line zero when expanding a
6052              generated constructor. */
6053           if (DECL_CONSTRUCTOR_P (decl) && !DECL_FUNCTION_BODY (decl))
6054             {
6055               /* If we found errors, it's too dangerous to try to
6056                  generate and expand a constructor */
6057               if (!java_error_count)
6058                 {
6059                   restore_line_number_status (1);
6060                   java_complete_expand_method (decl);
6061                   restore_line_number_status (0);
6062                   }
6063             }
6064           else if (METHOD_ABSTRACT (decl) || METHOD_NATIVE (decl))
6065             continue;
6066           else 
6067             java_complete_expand_method (decl);
6068         }
6069
6070       /* Now verify constructor circularity (stop after the first one
6071          we find) */
6072       if (!is_interface)
6073         for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
6074           if (DECL_CONSTRUCTOR_P (decl) && 
6075               verify_constructor_circularity (decl, decl))
6076             break;
6077
6078       /* Make the class data, register it and run the rest of decl
6079          compilation on it */
6080       if (!java_error_count)
6081         {
6082           if (flag_emit_class_files)
6083             write_classfile (current_class);
6084           if (flag_emit_xref)
6085             expand_xref (current_class);
6086           else if (! flag_syntax_only)
6087             finish_class ();
6088         }
6089     }
6090 }
6091
6092 /* Hold a list of catch clauses list. The first element of this list is
6093    the list of the catch clauses of the currently analysed try block. */
6094 static tree currently_caught_type_list;
6095
6096 /* Complete and expand <clinit>. Return a non zero value if <clinit>
6097    is worth keeping.  */
6098
6099 static int
6100 java_pre_expand_clinit (decl)
6101      tree decl;
6102 {
6103   tree fbody = DECL_FUNCTION_BODY (decl);
6104   tree list;
6105   int to_return = 1;
6106
6107   if (fbody != NULL_TREE)
6108     {
6109       /* First check if we can ignore empty <clinit> */
6110       tree block_body = BLOCK_EXPR_BODY (fbody);
6111       
6112       current_this = NULL_TREE;
6113       current_function_decl = decl;
6114       if (block_body != NULL_TREE)
6115         {
6116           /* Prevent the use of `this' inside <clinit> */
6117           ctxp->explicit_constructor_p = 1;
6118           block_body = java_complete_tree (block_body);
6119           ctxp->explicit_constructor_p = 0;
6120
6121           BLOCK_EXPR_BODY (fbody) = block_body;
6122           if (block_body != NULL_TREE  && TREE_CODE (block_body) == BLOCK
6123               && BLOCK_EXPR_BODY (block_body) == empty_stmt_node)
6124             to_return = 0;
6125         }
6126     }
6127   return to_return;
6128 }
6129
6130 /* Complete and expand a method.  */
6131
6132 static void
6133 java_complete_expand_method (mdecl)
6134      tree mdecl;
6135 {
6136   /* Fix constructors before expanding them */
6137   if (DECL_CONSTRUCTOR_P (mdecl))
6138     fix_constructors (mdecl);
6139   
6140   /* Expand functions that have a body */
6141   if (DECL_FUNCTION_BODY (mdecl))
6142     {
6143       tree fbody = DECL_FUNCTION_BODY (mdecl);
6144       tree block_body = BLOCK_EXPR_BODY (fbody);
6145       tree exception_copy = NULL_TREE;
6146       expand_start_java_method (mdecl);
6147       build_result_decl (mdecl);
6148
6149       current_this 
6150         = (!METHOD_STATIC (mdecl) ? 
6151            BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl)) : NULL_TREE);
6152
6153       /* Purge the `throws' list of unchecked exceptions. If we're
6154          doing xref, save a copy of the list and re-install it
6155          later. */
6156       if (flag_emit_xref)
6157         exception_copy = copy_list (DECL_FUNCTION_THROWS (mdecl));
6158
6159       purge_unchecked_exceptions (mdecl);
6160
6161       /* Install exceptions thrown with `throws' */
6162       PUSH_EXCEPTIONS (DECL_FUNCTION_THROWS (mdecl));
6163
6164       if (block_body != NULL_TREE)
6165         {
6166           block_body = java_complete_tree (block_body);
6167           if (!flag_emit_xref)
6168             check_for_initialization (block_body);
6169           ctxp->explicit_constructor_p = 0;
6170         }
6171       BLOCK_EXPR_BODY (fbody) = block_body;
6172
6173       if ((block_body == NULL_TREE || CAN_COMPLETE_NORMALLY (block_body))
6174           && TREE_CODE (TREE_TYPE (TREE_TYPE (mdecl))) != VOID_TYPE
6175           && !flag_emit_xref)
6176         missing_return_error (current_function_decl);
6177
6178       complete_start_java_method (mdecl); 
6179
6180       /* Don't go any further if we've found error(s) during the
6181          expansion */
6182       if (!java_error_count)
6183         source_end_java_method ();
6184       else
6185         {
6186           pushdecl_force_head (DECL_ARGUMENTS (mdecl));
6187           poplevel (1, 0, 1);
6188         }
6189
6190       /* Pop the exceptions and sanity check */
6191       POP_EXCEPTIONS();
6192       if (currently_caught_type_list)
6193         fatal ("Exception list non empty - java_complete_expand_method");
6194
6195       if (flag_emit_xref)
6196         DECL_FUNCTION_THROWS (mdecl) = exception_copy;
6197     }
6198 }
6199
6200 /* Craft a body for default constructor. Patch existing constructor
6201    bodies with call to super() and field initialization statements if
6202    necessary.  */
6203
6204 static void
6205 fix_constructors (mdecl)
6206      tree mdecl;
6207 {
6208   tree body = DECL_FUNCTION_BODY (mdecl);
6209
6210   if (!body)
6211     {
6212       /* The constructor body must be crafted by hand. It's the
6213          constructor we defined when we realize we didn't have the
6214          CLASSNAME() constructor */
6215
6216       tree compound;
6217
6218       /* It is an error for the compiler to generate a default
6219          constructor if the superclass doesn't have a constructor that
6220          takes no argument */
6221       if (verify_constructor_super ())
6222         {
6223           tree sclass_decl = TYPE_NAME (CLASSTYPE_SUPER (current_class));
6224           const char *n = IDENTIFIER_POINTER (DECL_NAME (sclass_decl));
6225           parse_error_context (lookup_cl (TYPE_NAME (current_class)), 
6226                                "No constructor matching `%s()' found in "
6227                                "class `%s'", n, n);
6228         }
6229       
6230       start_artificial_method_body (mdecl);
6231       
6232       /* We don't generate a super constructor invocation if we're
6233          compiling java.lang.Object. build_super_invocation takes care
6234          of that. */
6235       compound = java_method_add_stmt (mdecl, build_super_invocation (mdecl));
6236
6237       end_artificial_method_body (mdecl);
6238     }
6239   /* Search for an explicit constructor invocation */
6240   else 
6241     {
6242       int found = 0;
6243       tree main_block = BLOCK_EXPR_BODY (body);
6244       tree compound = NULL_TREE;
6245       
6246       while (body)
6247         switch (TREE_CODE (body))
6248           {
6249           case CALL_EXPR:
6250             found = CALL_EXPLICIT_CONSTRUCTOR_P (body);
6251             body = NULL_TREE;
6252             break;
6253           case COMPOUND_EXPR:
6254           case EXPR_WITH_FILE_LOCATION:
6255             body = TREE_OPERAND (body, 0);
6256             break;
6257           case BLOCK:
6258             body = BLOCK_EXPR_BODY (body);
6259             break;
6260           default:
6261             found = 0;
6262             body = NULL_TREE;
6263           }
6264       /* The constructor is missing an invocation of super() */
6265       if (!found)
6266         compound = add_stmt_to_compound (compound, NULL_TREE,
6267                                          build_super_invocation (mdecl));
6268       
6269       /* Fix the constructor main block if we're adding extra stmts */
6270       if (compound)
6271         {
6272           compound = add_stmt_to_compound (compound, NULL_TREE,
6273                                            BLOCK_EXPR_BODY (main_block));
6274           BLOCK_EXPR_BODY (main_block) = compound;
6275         }
6276     }
6277 }
6278
6279 /* Browse constructors in the super class, searching for a constructor
6280    that doesn't take any argument. Return 0 if one is found, 1
6281    otherwise. */
6282
6283 static int
6284 verify_constructor_super ()
6285 {
6286   tree class = CLASSTYPE_SUPER (current_class);
6287   if (!class)
6288     return 0;
6289
6290   if (class)
6291     {
6292       tree mdecl;
6293       for (mdecl = TYPE_METHODS (class); mdecl; mdecl = TREE_CHAIN (mdecl))
6294         {
6295           if (DECL_CONSTRUCTOR_P (mdecl)
6296               && TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (mdecl))) 
6297                  == end_params_node)
6298             return 0;
6299         }
6300     }
6301   return 1;
6302 }
6303
6304 /* Expand finals.  */
6305
6306 static void
6307 java_expand_finals ()
6308 {
6309 }
6310
6311 /* Generate code for all context remembered for code generation.  */
6312
6313 void
6314 java_expand_classes ()
6315 {
6316   int save_error_count = 0;
6317   java_parse_abort_on_error ();
6318   if (!(ctxp = ctxp_for_generation))
6319     return;
6320   java_layout_classes ();
6321   java_parse_abort_on_error ();
6322
6323   for (; ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
6324     {
6325       ctxp = ctxp_for_generation;
6326       lang_init_source (2);            /* Error msgs have method prototypes */
6327       java_complete_expand_methods (); /* Complete and expand method bodies */
6328       java_parse_abort_on_error ();
6329       java_expand_finals ();          /* Expand and check the finals */
6330       java_parse_abort_on_error ();
6331       java_check_final ();            /* Check unitialized final  */
6332       java_parse_abort_on_error ();
6333     }
6334 }
6335
6336 /* Wrap non WFL PRIMARY around a WFL and set EXPR_WFL_QUALIFICATION to
6337    a tree list node containing RIGHT. Fore coming RIGHTs will be
6338    chained to this hook. LOCATION contains the location of the
6339    separating `.' operator.  */
6340
6341 static tree
6342 make_qualified_primary (primary, right, location)
6343      tree primary, right;
6344      int location;
6345 {
6346   tree wfl;
6347
6348   /* We want to process THIS . xxx symbolicaly, to keep it consistent
6349      with the way we're processing SUPER. A THIS from a primary as a
6350      different form than a SUPER. Turn THIS into something symbolic */
6351   if (TREE_CODE (primary) == THIS_EXPR)
6352     {
6353       wfl = build_wfl_node (this_identifier_node);
6354       EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (primary);
6355       wfl = make_qualified_name (wfl, right, location);
6356       PRIMARY_P (wfl) = 1;
6357       return wfl;
6358     }
6359   /* Other non WFL node are wrapped around a WFL */
6360   else if (TREE_CODE (primary) != EXPR_WITH_FILE_LOCATION)
6361     {
6362       wfl = build_expr_wfl (NULL_TREE, ctxp->filename, 0, 0);
6363       EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (primary);
6364       EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (primary, NULL_TREE);
6365     }
6366   else
6367     {
6368       wfl = primary;
6369       if (!EXPR_WFL_QUALIFICATION (primary))
6370         EXPR_WFL_QUALIFICATION (primary) = 
6371           build_tree_list (primary, NULL_TREE);
6372     }
6373
6374   EXPR_WFL_LINECOL (right) = location;
6375   chainon (EXPR_WFL_QUALIFICATION (wfl), build_tree_list (right, NULL_TREE));
6376   PRIMARY_P (wfl) =  1;
6377   return wfl;
6378 }
6379
6380 /* Simple merge of two name separated by a `.' */
6381
6382 static tree
6383 merge_qualified_name (left, right)
6384      tree left, right;
6385 {
6386   tree node;
6387   obstack_grow (&temporary_obstack, IDENTIFIER_POINTER (left),
6388                 IDENTIFIER_LENGTH (left));
6389   obstack_1grow (&temporary_obstack, '.');
6390   obstack_grow0 (&temporary_obstack, IDENTIFIER_POINTER (right),
6391                  IDENTIFIER_LENGTH (right));
6392   node =  get_identifier (obstack_base (&temporary_obstack));
6393   obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
6394   QUALIFIED_P (node) = 1;
6395   return node;
6396 }
6397
6398 /* Merge the two parts of a qualified name into LEFT.  Set the
6399    location information of the resulting node to LOCATION, usually
6400    inherited from the location information of the `.' operator. */
6401
6402 static tree
6403 make_qualified_name (left, right, location)
6404      tree left, right;
6405      int location;
6406 {
6407 #ifdef USE_COMPONENT_REF
6408   tree node = build (COMPONENT_REF, NULL_TREE, left, right);
6409   EXPR_WFL_LINECOL (node) = location;
6410   return node;
6411 #else
6412   tree left_id = EXPR_WFL_NODE (left);
6413   tree right_id = EXPR_WFL_NODE (right);
6414   tree wfl, merge;
6415
6416   merge = merge_qualified_name (left_id, right_id);
6417
6418   /* Left wasn't qualified and is now qualified */
6419   if (!QUALIFIED_P (left_id))
6420     {
6421       tree wfl = build_expr_wfl (left_id, ctxp->filename, 0, 0);
6422       EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (left);
6423       EXPR_WFL_QUALIFICATION (left) = build_tree_list (wfl, NULL_TREE);
6424     }
6425   
6426   wfl = build_expr_wfl (right_id, ctxp->filename, 0, 0);
6427   EXPR_WFL_LINECOL (wfl) = location;
6428   chainon (EXPR_WFL_QUALIFICATION (left), build_tree_list (wfl, NULL_TREE));
6429
6430   EXPR_WFL_NODE (left) = merge;
6431   return left;
6432 #endif
6433 }
6434
6435 /* Extract the last identifier component of the qualified in WFL. The
6436    last identifier is removed from the linked list */
6437
6438 static tree
6439 cut_identifier_in_qualified (wfl)
6440      tree wfl;
6441 {
6442   tree q;
6443   tree previous = NULL_TREE;
6444   for (q = EXPR_WFL_QUALIFICATION (wfl); ; previous = q, q = TREE_CHAIN (q))
6445     if (!TREE_CHAIN (q))
6446       {
6447         if (!previous)
6448           fatal ("Operating on a non qualified qualified WFL - "
6449                  "cut_identifier_in_qualified");
6450         TREE_CHAIN (previous) = NULL_TREE;
6451         return TREE_PURPOSE (q);
6452       }
6453 }
6454
6455 /* Resolve the expression name NAME. Return its decl.  */
6456
6457 static tree
6458 resolve_expression_name (id, orig)
6459      tree id;
6460      tree *orig;
6461 {
6462   tree name = EXPR_WFL_NODE (id);
6463   tree decl;
6464
6465   /* 6.5.5.1: Simple expression names */
6466   if (!PRIMARY_P (id) && !QUALIFIED_P (name))
6467     {
6468       /* 15.13.1: NAME can appear within the scope of a local variable
6469          declaration */
6470       if ((decl = IDENTIFIER_LOCAL_VALUE (name)))
6471         return decl;
6472
6473       /* 15.13.1: NAME can appear within a class declaration */
6474       else 
6475         {
6476           decl = lookup_field_wrapper (current_class, name);
6477           if (decl)
6478             {
6479               int fs = FIELD_STATIC (decl);
6480               /* Instance variable (8.3.1.1) can't appear within
6481                  static method, static initializer or initializer for
6482                  a static variable. */
6483               if (!fs && METHOD_STATIC (current_function_decl))
6484                 {
6485                   static_ref_err (id, name, current_class);
6486                   return error_mark_node;
6487                 }
6488               /* Instance variables can't appear as an argument of
6489                  an explicit constructor invocation */
6490               if (!fs && ctxp->explicit_constructor_p)
6491                 {
6492                   parse_error_context
6493                     (id, "Can't reference `%s' before the superclass "
6494                      "constructor has been called", IDENTIFIER_POINTER (name));
6495                   return error_mark_node;
6496                 }
6497
6498               /* Otherwise build what it takes to access the field */
6499               decl = build_field_ref ((fs ? NULL_TREE : current_this),
6500                                       DECL_CONTEXT (decl), name);
6501               if (fs && !flag_emit_class_files && !flag_emit_xref)
6502                 decl = build_class_init (DECL_CONTEXT (decl), decl);
6503               /* We may be asked to save the real field access node */
6504               if (orig)
6505                 *orig = decl;
6506               /* And we return what we got */
6507               return decl;
6508             }
6509           /* Fall down to error report on undefined variable */
6510         }
6511     }
6512   /* 6.5.5.2 Qualified Expression Names */
6513   else
6514     {
6515       if (orig)
6516         *orig = NULL_TREE;
6517       qualify_ambiguous_name (id);
6518       /* 15.10.1 Field Access Using a Primary and/or Expression Name */
6519       /* 15.10.2: Accessing Superclass Members using super */
6520       return resolve_field_access (id, NULL, NULL);
6521     }
6522
6523   /* We've got an error here */
6524   parse_error_context (id, "Undefined variable `%s'", 
6525                        IDENTIFIER_POINTER (name));
6526
6527   return error_mark_node;
6528 }
6529
6530 static void
6531 static_ref_err (wfl, field_id, class_type)
6532     tree wfl, field_id, class_type;
6533 {
6534   parse_error_context 
6535     (wfl, 
6536      "Can't make a static reference to nonstatic variable `%s' in class `%s'",
6537      IDENTIFIER_POINTER (field_id), 
6538      IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class_type))));
6539 }
6540
6541 /* 15.10.1 Field Acess Using a Primary and/or Expression Name.
6542    We return something suitable to generate the field access. We also
6543    return the field decl in FIELD_DECL and its type in FIELD_TYPE.  If
6544    recipient's address can be null. */
6545
6546 static tree
6547 resolve_field_access (qual_wfl, field_decl, field_type)
6548      tree qual_wfl;
6549      tree *field_decl, *field_type;
6550 {
6551   int is_static = 0;
6552   tree field_ref;
6553   tree decl, where_found, type_found;
6554
6555   if (resolve_qualified_expression_name (qual_wfl, &decl,
6556                                          &where_found, &type_found))
6557     return error_mark_node;
6558
6559   /* Resolve the LENGTH field of an array here */
6560   if (DECL_NAME (decl) == length_identifier_node && TYPE_ARRAY_P (type_found)
6561       && ! flag_emit_class_files && ! flag_emit_xref)
6562     {
6563       tree length = build_java_array_length_access (where_found);
6564       field_ref =
6565         build_java_arraynull_check (type_found, length, int_type_node);
6566     }
6567   /* We might have been trying to resolve field.method(). In which
6568      case, the resolution is over and decl is the answer */
6569   else if (JDECL_P (decl) && IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)) == decl)
6570     field_ref = decl;
6571   else if (JDECL_P (decl))
6572     {
6573       int static_final_found = 0;
6574       if (!type_found)
6575         type_found = DECL_CONTEXT (decl);
6576       is_static = JDECL_P (decl) && FIELD_STATIC (decl);
6577       if (FIELD_FINAL (decl) 
6578           && JPRIMITIVE_TYPE_P (TREE_TYPE (decl))
6579           && DECL_LANG_SPECIFIC (decl)
6580           && DECL_INITIAL (decl))
6581         {
6582           field_ref = DECL_INITIAL (decl);
6583           static_final_found = 1;
6584         }
6585       else
6586         field_ref = build_field_ref ((is_static && !flag_emit_xref? 
6587                                       NULL_TREE : where_found), 
6588                                      type_found, DECL_NAME (decl));
6589       if (field_ref == error_mark_node)
6590         return error_mark_node;
6591       if (is_static && !static_final_found 
6592           && !flag_emit_class_files && !flag_emit_xref)
6593         {
6594           field_ref = build_class_init (type_found, field_ref);
6595           /* If the static field was identified by an expression that
6596              needs to be generated, make the field access a compound
6597              expression whose first part is the evaluation of the
6598              field selector part. */
6599           if (where_found && TREE_CODE (where_found) != TYPE_DECL 
6600               && TREE_CODE (where_found) != RECORD_TYPE)
6601             {
6602               tree type = QUAL_DECL_TYPE (field_ref);
6603               if (TREE_CODE (type) == RECORD_TYPE)
6604                 type = build_pointer_type (type);
6605               field_ref = build (COMPOUND_EXPR, type, where_found, field_ref);
6606             }
6607         }
6608     }
6609   else
6610     field_ref = decl;
6611
6612   if (field_decl)
6613     *field_decl = decl;
6614   if (field_type)
6615     *field_type = (QUAL_DECL_TYPE (decl) ? 
6616                    QUAL_DECL_TYPE (decl) : TREE_TYPE (decl));
6617   return field_ref;
6618 }
6619
6620 /* If NODE is an access to f static field, strip out the class
6621    initialization part and return the field decl, otherwise, return
6622    NODE. */
6623
6624 static tree
6625 strip_out_static_field_access_decl (node)
6626     tree node;
6627 {
6628   if (TREE_CODE (node) == COMPOUND_EXPR)
6629     {
6630       tree op1 = TREE_OPERAND (node, 1);
6631       if (TREE_CODE (op1) == COMPOUND_EXPR)
6632          {
6633            tree call = TREE_OPERAND (op1, 0);
6634            if (TREE_CODE (call) == CALL_EXPR
6635                && TREE_CODE (TREE_OPERAND (call, 0)) == ADDR_EXPR
6636                && TREE_OPERAND (TREE_OPERAND (call, 0), 0)
6637                == soft_initclass_node)
6638              return TREE_OPERAND (op1, 1);
6639          }
6640       else if (JDECL_P (op1))
6641         return op1;
6642     }
6643   return node;
6644 }
6645
6646 /* 6.5.5.2: Qualified Expression Names */
6647
6648 static int
6649 resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
6650      tree wfl;
6651      tree *found_decl, *type_found, *where_found;
6652 {
6653   int from_type = 0;            /* Field search initiated from a type */
6654   int from_super = 0, from_cast = 0;
6655   int previous_call_static = 0;
6656   int is_static;
6657   tree decl = NULL_TREE, type = NULL_TREE, q;
6658   *type_found = *where_found = NULL_TREE;
6659
6660   for (q = EXPR_WFL_QUALIFICATION (wfl); q; q = TREE_CHAIN (q))
6661     {
6662       tree qual_wfl = QUAL_WFL (q);
6663       tree ret_decl;            /* for EH checking */
6664       int location;             /* for EH checking */
6665
6666       /* 15.10.1 Field Access Using a Primary */
6667       switch (TREE_CODE (qual_wfl))
6668         {
6669         case CALL_EXPR:
6670         case NEW_CLASS_EXPR:
6671           /* If the access to the function call is a non static field,
6672              build the code to access it. */
6673           if (JDECL_P (decl) && !FIELD_STATIC (decl))
6674             {
6675               decl = maybe_access_field (decl, *where_found, 
6676                                          DECL_CONTEXT (decl));
6677               if (decl == error_mark_node)
6678                 return 1;
6679             }
6680           /* And code for the function call */
6681           if (complete_function_arguments (qual_wfl))
6682             return 1;
6683           
6684           if (from_super && TREE_CODE (qual_wfl) == CALL_EXPR)
6685             CALL_USING_SUPER (qual_wfl) = 1;
6686           location = (TREE_CODE (qual_wfl) == CALL_EXPR ?
6687                       EXPR_WFL_LINECOL (TREE_OPERAND (qual_wfl, 0)) : 0);
6688           *where_found = patch_method_invocation (qual_wfl, decl, type, 
6689                                                   &is_static, &ret_decl);
6690           if (*where_found == error_mark_node)
6691             return 1;
6692           *type_found = type = QUAL_DECL_TYPE (*where_found);
6693
6694           /* EH check */
6695           if (location)
6696             check_thrown_exceptions (location, ret_decl);
6697
6698           /* If the previous call was static and this one is too,
6699              build a compound expression to hold the two (because in
6700              that case, previous function calls aren't transported as
6701              forcoming function's argument. */
6702           if (previous_call_static && is_static)
6703             {
6704               decl = build (COMPOUND_EXPR, type, decl, *where_found);
6705               TREE_SIDE_EFFECTS (decl) = 1;
6706             }
6707           else
6708             {
6709               previous_call_static = is_static;
6710               decl = *where_found;
6711             }
6712           continue;
6713
6714         case NEW_ARRAY_EXPR:
6715           *where_found = decl = java_complete_tree (qual_wfl);
6716           if (decl == error_mark_node)
6717             return 1;
6718           *type_found = type = QUAL_DECL_TYPE (decl);
6719           CLASS_LOADED_P (type) = 1;
6720           continue;
6721
6722         case CONVERT_EXPR:
6723           *where_found = decl = java_complete_tree (qual_wfl);
6724           if (decl == error_mark_node)
6725             return 1;
6726           *type_found = type = QUAL_DECL_TYPE (decl);
6727           from_cast = 1;
6728           continue;
6729
6730         case CONDITIONAL_EXPR:
6731         case STRING_CST:
6732         case MODIFY_EXPR:
6733           *where_found = decl = java_complete_tree (qual_wfl);
6734           if (decl == error_mark_node)
6735             return 1;
6736           *type_found = type = QUAL_DECL_TYPE (decl);
6737           continue;
6738
6739         case ARRAY_REF:
6740           /* If the access to the function call is a non static field,
6741              build the code to access it. */
6742           if (JDECL_P (decl) && !FIELD_STATIC (decl))
6743             {
6744               decl = maybe_access_field (decl, *where_found, type);
6745               if (decl == error_mark_node)
6746                 return 1;
6747             }
6748           /* And code for the array reference expression */
6749           decl = java_complete_tree (qual_wfl);
6750           if (decl == error_mark_node)
6751             return 1;
6752           type = QUAL_DECL_TYPE (decl);
6753           continue;
6754
6755         case PLUS_EXPR:
6756           if ((decl = java_complete_tree (qual_wfl)) == error_mark_node)
6757             return 1;
6758           if ((type = patch_string (decl)))
6759             decl = type;
6760           *where_found = QUAL_RESOLUTION (q) = decl;
6761           *type_found = type = TREE_TYPE (decl);
6762           break;
6763
6764         default:
6765           /* Fix for -Wall Just go to the next statement. Don't
6766              continue */
6767           break;
6768         }
6769
6770       /* If we fall here, we weren't processing a (static) function call. */
6771       previous_call_static = 0;
6772
6773       /* It can be the keyword THIS */
6774       if (EXPR_WFL_NODE (qual_wfl) == this_identifier_node)
6775         {
6776           if (!current_this)
6777             {
6778               parse_error_context 
6779                 (wfl, "Keyword `this' used outside allowed context");
6780               return 1;
6781             }
6782           if (ctxp->explicit_constructor_p)
6783             {
6784               parse_error_context (wfl, "Can't reference `this' before the "
6785                                    "superclass constructor has been called");
6786               return 1;
6787             }
6788           /* We have to generate code for intermediate acess */
6789           *where_found = decl = current_this;
6790           *type_found = type = QUAL_DECL_TYPE (decl);
6791           continue;
6792         }
6793
6794       /* 15.10.2 Accessing Superclass Members using SUPER */
6795       if (EXPR_WFL_NODE (qual_wfl) == super_identifier_node)
6796         {
6797           tree node;
6798           /* Check on the restricted use of SUPER */
6799           if (METHOD_STATIC (current_function_decl)
6800               || current_class == object_type_node)
6801             {
6802               parse_error_context 
6803                 (wfl, "Keyword `super' used outside allowed context");
6804               return 1;
6805             }
6806           /* Otherwise, treat SUPER as (SUPER_CLASS)THIS */
6807           node = build_cast (EXPR_WFL_LINECOL (qual_wfl), 
6808                              CLASSTYPE_SUPER (current_class),
6809                              build_this (EXPR_WFL_LINECOL (qual_wfl)));
6810           *where_found = decl = java_complete_tree (node);
6811           if (decl == error_mark_node)
6812             return 1;
6813           *type_found = type = QUAL_DECL_TYPE (decl);
6814           from_super = from_type = 1;
6815           continue;
6816         }
6817
6818       /* 15.13.1: Can't search for field name in packages, so we
6819          assume a variable/class name was meant. */
6820       if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
6821         {
6822           tree name = resolve_package (wfl, &q);
6823           if (name)
6824             {
6825               *where_found = decl = resolve_no_layout (name, qual_wfl);
6826               /* We wan't to be absolutely that the class is laid
6827                  out. We're going to search something inside it. */
6828               *type_found = type = TREE_TYPE (decl);
6829               layout_class (type);
6830               from_type = 1;
6831               /* Should be a list, really. FIXME */
6832               RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (TREE_CHAIN (q))) = 1;
6833               RESOLVE_PACKAGE_NAME_P (QUAL_WFL (TREE_CHAIN (q))) = 0;
6834             }
6835           else
6836             {
6837               if (from_super || from_cast)
6838                 parse_error_context 
6839                   ((from_cast ? qual_wfl : wfl),
6840                    "No variable `%s' defined in class `%s'",
6841                    IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
6842                    lang_printable_name (type, 0));
6843               else
6844                 parse_error_context
6845                   (qual_wfl, "Undefined variable or class name: `%s'",
6846                    IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)));
6847               return 1;
6848             }
6849         }
6850
6851       /* We have a type name. It's been already resolved when the
6852          expression was qualified. */
6853       else if (RESOLVE_TYPE_NAME_P (qual_wfl))
6854         {
6855           if (!(decl = QUAL_RESOLUTION (q)))
6856             return 1;           /* Error reported already */
6857
6858           if (not_accessible_p (TREE_TYPE (decl), decl, 0))
6859             {
6860               parse_error_context 
6861                 (qual_wfl, "Can't access %s field `%s.%s' from `%s'",
6862                  java_accstring_lookup (get_access_flags_from_decl (decl)),
6863                  GET_TYPE_NAME (type),
6864                  IDENTIFIER_POINTER (DECL_NAME (decl)),
6865                  IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
6866               return 1;
6867             }
6868           check_deprecation (qual_wfl, decl);
6869           
6870           type = TREE_TYPE (decl);
6871           from_type = 1;
6872         }
6873       /* We resolve and expression name */
6874       else 
6875         {
6876           tree field_decl = NULL_TREE;
6877
6878           /* If there exists an early resolution, use it. That occurs
6879              only once and we know that there are more things to
6880              come. Don't do that when processing something after SUPER
6881              (we need more thing to be put in place below */
6882           if (!from_super && QUAL_RESOLUTION (q))
6883             {
6884               decl = QUAL_RESOLUTION (q);
6885               if (!type)
6886                 {
6887                   if (TREE_CODE (decl) == FIELD_DECL && !FIELD_STATIC (decl))
6888                     {
6889                       if (current_this)
6890                         *where_found = current_this;
6891                       else
6892                         {
6893                           static_ref_err (qual_wfl, DECL_NAME (decl),
6894                                           current_class);
6895                           return 1;
6896                         }
6897                     }
6898                   else
6899                     {
6900                       *where_found = TREE_TYPE (decl);
6901                       if (TREE_CODE (*where_found) == POINTER_TYPE)
6902                         *where_found = TREE_TYPE (*where_found);
6903                     }
6904                 }
6905             }
6906
6907           /* We have to search for a field, knowing the type of its
6908              container. The flag FROM_TYPE indicates that we resolved
6909              the last member of the expression as a type name, which
6910              means that for the resolution of this field, we'll look
6911              for other errors than if it was resolved as a member of
6912              an other field. */
6913           else
6914             {
6915               int is_static;
6916               tree field_decl_type; /* For layout */
6917
6918               if (!from_type && !JREFERENCE_TYPE_P (type))
6919                 {
6920                   parse_error_context 
6921                     (qual_wfl, "Attempt to reference field `%s' in `%s %s'",
6922                      IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
6923                      lang_printable_name (type, 0),
6924                      IDENTIFIER_POINTER (DECL_NAME (field_decl)));
6925                   return 1;
6926                 }
6927               
6928               field_decl = lookup_field_wrapper (type,
6929                                                  EXPR_WFL_NODE (qual_wfl));
6930               if (field_decl == NULL_TREE)
6931                 {
6932                   parse_error_context 
6933                     (qual_wfl, "No variable `%s' defined in type `%s'",
6934                      IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)), 
6935                      GET_TYPE_NAME (type));
6936                   return 1;
6937                 }
6938               if (field_decl == error_mark_node)
6939                 return 1;
6940
6941               /* Layout the type of field_decl, since we may need
6942                  it. Don't do primitive types or loaded classes. The
6943                  situation of non primitive arrays may not handled
6944                  properly here. FIXME */
6945               if (TREE_CODE (TREE_TYPE (field_decl)) == POINTER_TYPE)
6946                 field_decl_type = TREE_TYPE (TREE_TYPE (field_decl));
6947               else
6948                 field_decl_type = TREE_TYPE (field_decl);
6949               if (!JPRIMITIVE_TYPE_P (field_decl_type) 
6950                   && !CLASS_LOADED_P (field_decl_type)
6951                   && !TYPE_ARRAY_P (field_decl_type))
6952                 resolve_and_layout (field_decl_type, NULL_TREE);
6953               if (TYPE_ARRAY_P (field_decl_type))
6954                 CLASS_LOADED_P (field_decl_type) = 1;
6955               
6956               /* Check on accessibility here */
6957               if (not_accessible_p (type, field_decl, from_super))
6958                 {
6959                   parse_error_context 
6960                     (qual_wfl,
6961                      "Can't access %s field `%s.%s' from `%s'",
6962                      java_accstring_lookup 
6963                        (get_access_flags_from_decl (field_decl)),
6964                      GET_TYPE_NAME (type),
6965                      IDENTIFIER_POINTER (DECL_NAME (field_decl)),
6966                      IDENTIFIER_POINTER 
6967                        (DECL_NAME (TYPE_NAME (current_class))));
6968                   return 1;
6969                 }
6970               check_deprecation (qual_wfl, field_decl);
6971               
6972               /* There are things to check when fields are accessed
6973                  from type. There are no restrictions on a static
6974                  declaration of the field when it is accessed from an
6975                  interface */
6976               is_static = FIELD_STATIC (field_decl);
6977               if (!from_super && from_type 
6978                   && !TYPE_INTERFACE_P (type) && !is_static)
6979                 {
6980                   static_ref_err (qual_wfl, EXPR_WFL_NODE (qual_wfl), type);
6981                   return 1;
6982                 }
6983               from_cast = from_super = 0;
6984
6985               /* If we need to generate something to get a proper
6986                  handle on what this field is accessed from, do it
6987                  now. */
6988               if (!is_static)
6989                 {
6990                   decl = maybe_access_field (decl, *where_found, *type_found);
6991                   if (decl == error_mark_node)
6992                     return 1;
6993                 }
6994
6995               /* We want to keep the location were found it, and the type
6996                  we found. */
6997               *where_found = decl;
6998               *type_found = type;
6999
7000               /* This is the decl found and eventually the next one to
7001                  search from */
7002               decl = field_decl;
7003             }
7004           from_type = 0;
7005           type = QUAL_DECL_TYPE (decl);
7006         }
7007     }
7008   *found_decl = decl;
7009   return 0;
7010 }
7011
7012 /* 6.6 Qualified name and access control. Returns 1 if MEMBER (a decl)
7013    can't be accessed from REFERENCE (a record type). */
7014
7015 static int
7016 not_accessible_p (reference, member, from_super)
7017      tree reference, member;
7018      int from_super;
7019 {
7020   int access_flag = get_access_flags_from_decl (member);
7021
7022   /* Access always granted for members declared public */
7023   if (access_flag & ACC_PUBLIC)
7024     return 0;
7025   
7026   /* Check access on protected members */
7027   if (access_flag & ACC_PROTECTED)
7028     {
7029       /* Access granted if it occurs from within the package
7030          containing the class in which the protected member is
7031          declared */
7032       if (class_in_current_package (DECL_CONTEXT (member)))
7033         return 0;
7034
7035       /* If accessed with the form `super.member', then access is granted */
7036       if (from_super)
7037         return 0;
7038
7039       /* Otherwise, access is granted if occuring from the class where
7040          member is declared or a subclass of it */
7041       if (inherits_from_p (reference, current_class))
7042         return 0;
7043       return 1;
7044     }
7045
7046   /* Check access on private members. Access is granted only if it
7047      occurs from within the class in witch it is declared */
7048   if (access_flag & ACC_PRIVATE)
7049     return (current_class == DECL_CONTEXT (member) ? 0 : 1);
7050
7051   /* Default access are permitted only when occuring within the
7052      package in which the type (REFERENCE) is declared. In other words,
7053      REFERENCE is defined in the current package */
7054   if (ctxp->package)
7055     return !class_in_current_package (reference);
7056   
7057   /* Otherwise, access is granted */
7058   return 0;
7059 }
7060
7061 /* Test deprecated decl access.  */
7062 static void
7063 check_deprecation (wfl, decl)
7064      tree wfl, decl;
7065 {
7066   const char *file = DECL_SOURCE_FILE (decl);
7067   /* Complain if the field is deprecated and the file it was defined
7068      in isn't compiled at the same time the file which contains its
7069      use is */
7070   if (DECL_DEPRECATED (decl) 
7071       && !IS_A_COMMAND_LINE_FILENAME_P (get_identifier (file)))
7072     {
7073       char the [20];
7074       switch (TREE_CODE (decl))
7075         {
7076         case FUNCTION_DECL:
7077           strcpy (the, "method");
7078           break;
7079         case FIELD_DECL:
7080           strcpy (the, "field");
7081           break;
7082         case TYPE_DECL:
7083           strcpy (the, "class");
7084           break;
7085         default:
7086           fatal ("unexpected DECL code - check_deprecation");
7087         }
7088       parse_warning_context 
7089         (wfl, "The %s `%s' in class `%s' has been deprecated", 
7090          the, lang_printable_name (decl, 0),
7091          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)))));
7092     }
7093 }
7094
7095 /* Returns 1 if class was declared in the current package, 0 otherwise */
7096
7097 static int
7098 class_in_current_package (class)
7099      tree class;
7100 {
7101   static tree cache = NULL_TREE;
7102   int qualified_flag;
7103   tree left;
7104
7105   if (cache == class)
7106     return 1;
7107
7108   qualified_flag = QUALIFIED_P (DECL_NAME (TYPE_NAME (class)));
7109
7110   /* If the current package is empty and the name of CLASS is
7111      qualified, class isn't in the current package.  If there is a
7112      current package and the name of the CLASS is not qualified, class
7113      isn't in the current package */
7114   if ((!ctxp->package && qualified_flag) || (ctxp->package && !qualified_flag))
7115     return 0;
7116
7117   /* If there is not package and the name of CLASS isn't qualified,
7118      they belong to the same unnamed package */
7119   if (!ctxp->package && !qualified_flag)
7120     return 1;
7121
7122   /* Compare the left part of the name of CLASS with the package name */
7123   breakdown_qualified (&left, NULL, DECL_NAME (TYPE_NAME (class)));
7124   if (ctxp->package == left)
7125     {
7126       cache = class;
7127       return 1;
7128     }
7129   return 0;
7130 }
7131
7132 /* This function may generate code to access DECL from WHERE. This is
7133    done only if certain conditions meet.  */
7134
7135 static tree
7136 maybe_access_field (decl, where, type)
7137   tree decl, where, type;
7138 {
7139   if (TREE_CODE (decl) == FIELD_DECL && decl != current_this
7140       && !FIELD_STATIC (decl))
7141     decl = build_field_ref (where ? where : current_this, 
7142                             (type ? type : DECL_CONTEXT (decl)),
7143                             DECL_NAME (decl));
7144   return decl;
7145 }
7146
7147 /* Build a method invocation, by patching PATCH. If non NULL
7148    and according to the situation, PRIMARY and WHERE may be
7149    used. IS_STATIC is set to 1 if the invoked function is static. */
7150
7151 static tree
7152 patch_method_invocation (patch, primary, where, is_static, ret_decl)
7153      tree patch, primary, where;
7154      int *is_static;
7155      tree *ret_decl;
7156 {
7157   tree wfl = TREE_OPERAND (patch, 0);
7158   tree args = TREE_OPERAND (patch, 1);
7159   tree name = EXPR_WFL_NODE (wfl);
7160   tree list;
7161   int is_static_flag = 0;
7162   int is_super_init = 0;
7163   tree this_arg = NULL_TREE;
7164   
7165   /* Should be overriden if everything goes well. Otherwise, if
7166      something fails, it should keep this value. It stop the
7167      evaluation of a bogus assignment. See java_complete_tree,
7168      MODIFY_EXPR: for the reasons why we sometimes want to keep on
7169      evaluating an assignment */
7170   TREE_TYPE (patch) = error_mark_node;
7171
7172   /* Since lookup functions are messing with line numbers, save the
7173      context now.  */
7174   java_parser_context_save_global ();
7175
7176   /* 15.11.1: Compile-Time Step 1: Determine Class or Interface to Search */
7177
7178   /* Resolution of qualified name, excluding constructors */
7179   if (QUALIFIED_P (name) && !CALL_CONSTRUCTOR_P (patch))
7180     {
7181       tree class_decl, identifier, identifier_wfl;
7182       /* Extract the last IDENTIFIER of the qualified
7183          expression. This is a wfl and we will use it's location
7184          data during error report. */
7185       identifier_wfl = cut_identifier_in_qualified (wfl);
7186       identifier = EXPR_WFL_NODE (identifier_wfl);
7187       
7188       /* Given the context, IDENTIFIER is syntactically qualified
7189          as a MethodName. We need to qualify what's before */
7190       qualify_ambiguous_name (wfl);
7191
7192       /* Package resolution */
7193       if (RESOLVE_PACKAGE_NAME_P (wfl))
7194         {
7195           tree next, decl, name = resolve_package (wfl, &next);
7196           
7197           if (!name)
7198             {
7199               tree remainder;
7200               breakdown_qualified (&remainder, NULL, EXPR_WFL_NODE (wfl));
7201               parse_error_context (wfl, "Can't search method `%s' in package "
7202                                    "`%s'",IDENTIFIER_POINTER (identifier),
7203                                    IDENTIFIER_POINTER (remainder));
7204               PATCH_METHOD_RETURN_ERROR ();
7205             }
7206           RESOLVE_PACKAGE_NAME_P (wfl) = 0;
7207           if ((decl = resolve_no_layout (name, QUAL_WFL (next))))
7208             {
7209               QUAL_RESOLUTION (EXPR_WFL_QUALIFICATION (wfl)) = decl;
7210               RESOLVE_EXPRESSION_NAME_P (wfl) = 0;
7211               RESOLVE_TYPE_NAME_P (wfl) = 1;
7212             }
7213           else
7214             {
7215               RESOLVE_EXPRESSION_NAME_P (wfl) = 1;
7216               RESOLVE_TYPE_NAME_P (wfl) = 0;
7217             }
7218         }
7219
7220       /* We're resolving a call from a type */
7221       if (RESOLVE_TYPE_NAME_P (wfl))
7222         {
7223           tree decl = QUAL_RESOLUTION (EXPR_WFL_QUALIFICATION (wfl));
7224           tree name = DECL_NAME (decl);
7225           tree type;
7226
7227           class_decl = resolve_and_layout (name, wfl);
7228           if (CLASS_INTERFACE (decl))
7229             {
7230               parse_error_context
7231                 (identifier_wfl, "Can't make static reference to method "
7232                  "`%s' in interface `%s'", IDENTIFIER_POINTER (identifier), 
7233                  IDENTIFIER_POINTER (name));
7234               PATCH_METHOD_RETURN_ERROR ();
7235             }
7236           /* Look the method up in the type selector. The method ought
7237              to be static. */
7238           type = TREE_TYPE (class_decl);
7239           list = lookup_method_invoke (0, wfl, type, identifier, args);
7240           if (list && !METHOD_STATIC (list))
7241             {
7242               char *fct_name = xstrdup (lang_printable_name (list, 0));
7243               parse_error_context 
7244                 (identifier_wfl,
7245                  "Can't make static reference to method `%s %s' in class `%s'",
7246                  lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0), 
7247                  fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
7248               free (fct_name);
7249               PATCH_METHOD_RETURN_ERROR ();
7250             }
7251           args = nreverse (args);
7252         }
7253       /* We're resolving an expression name */
7254       else
7255         {
7256           tree field, type;
7257           
7258           /* 1- Find the field to which the call applies */
7259           field = resolve_field_access (wfl, NULL, &type);
7260           if (field == error_mark_node)
7261             PATCH_METHOD_RETURN_ERROR ();
7262           /* field is used in lieu of a primary. It alows us not to
7263            report errors on erroneous use of `this' in
7264            constructors. */
7265           primary = field;      
7266           
7267           /* 2- Do the layout of the class where the last field
7268              was found, so we can search it. */
7269           class_decl = resolve_and_layout (type, NULL_TREE);
7270           if (class_decl != NULL_TREE)
7271           type = TREE_TYPE (class_decl);
7272
7273           /* 3- Retrieve a filtered list of method matches, Refine
7274              if necessary. In any cases, point out errors.  */
7275           list = lookup_method_invoke (0, identifier_wfl, type, 
7276                                        identifier, args);
7277
7278           /* 4- Add the field as an argument */
7279           args = nreverse (args);
7280           this_arg = field;
7281         }
7282
7283       /* IDENTIFIER_WFL will be used to report any problem further */
7284       wfl = identifier_wfl;
7285     }
7286   /* Resolution of simple names, names generated after a primary: or
7287      constructors */
7288   else
7289     {
7290       tree class_to_search = NULL_TREE;
7291       int lc;           /* Looking for Constructor */
7292       
7293       /* We search constructor in their target class */
7294       if (CALL_CONSTRUCTOR_P (patch))
7295         {
7296           if (TREE_CODE (patch) == NEW_CLASS_EXPR)
7297             class_to_search = EXPR_WFL_NODE (wfl);
7298           else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) == 
7299                    this_identifier_node)
7300             class_to_search = NULL_TREE;
7301           else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) ==
7302                    super_identifier_node)
7303             {
7304               is_super_init = 1;
7305               if (CLASSTYPE_SUPER (current_class))
7306                 class_to_search = 
7307                   DECL_NAME (TYPE_NAME (CLASSTYPE_SUPER (current_class)));
7308               else
7309                 {
7310                   parse_error_context (wfl, "Can't invoke super constructor "
7311                                        "on java.lang.Object");
7312                   PATCH_METHOD_RETURN_ERROR ();
7313                 }
7314             }
7315
7316           /* Class to search is NULL if we're searching the current one */
7317           if (class_to_search)
7318             {
7319               class_to_search = resolve_and_layout (class_to_search, 
7320                                                     NULL_TREE);
7321               if (!class_to_search)
7322                 {
7323                   parse_error_context 
7324                     (wfl, "Class `%s' not found in type declaration",
7325                      IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
7326                   PATCH_METHOD_RETURN_ERROR ();
7327                 }
7328               
7329               /* Can't instantiate an abstract class, but we can
7330                  invoke it's constructor. It's use within the `new'
7331                  context is denied here. */
7332               if (CLASS_ABSTRACT (class_to_search) 
7333                   && TREE_CODE (patch) == NEW_CLASS_EXPR)
7334                 {
7335                   parse_error_context 
7336                     (wfl, "Class `%s' is an abstract class. It can't be "
7337                      "instantiated", IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
7338                   PATCH_METHOD_RETURN_ERROR ();
7339                 }
7340               class_to_search = TREE_TYPE (class_to_search);
7341             }
7342           else
7343             class_to_search = current_class;
7344           lc = 1;
7345         }
7346       /* This is a regular search in the local class, unless an
7347          alternate class is specified. */
7348       else
7349         {
7350           class_to_search = (where ? where : current_class);
7351           lc = 0;
7352         }
7353       
7354       /* NAME is a simple identifier or comes from a primary. Search
7355          in the class whose declaration contain the method being
7356          invoked. */
7357       resolve_and_layout (class_to_search, NULL_TREE);
7358       list = lookup_method_invoke (lc, wfl, class_to_search, name, args);
7359
7360       /* Don't continue if no method were found, as the next statement
7361          can't be executed then. */
7362       if (!list)
7363         PATCH_METHOD_RETURN_ERROR ();
7364
7365       /* Check for static reference if non static methods */
7366       if (check_for_static_method_reference (wfl, patch, list, 
7367                                              class_to_search, primary))
7368         PATCH_METHOD_RETURN_ERROR ();
7369
7370       /* Non static methods are called with the current object extra
7371          argument. If patch a `new TYPE()', the argument is the value
7372          returned by the object allocator. If method is resolved as a
7373          primary, use the primary otherwise use the current THIS. */
7374       args = nreverse (args);
7375       if (TREE_CODE (patch) != NEW_CLASS_EXPR)
7376         this_arg = primary ? primary : current_this;
7377     }
7378
7379   /* Merge point of all resolution schemes. If we have nothing, this
7380      is an error, already signaled */
7381   if (!list) 
7382     PATCH_METHOD_RETURN_ERROR ();
7383
7384   /* Check accessibility, position the is_static flag, build and
7385      return the call */
7386   if (not_accessible_p (DECL_CONTEXT (current_function_decl), list, 0))
7387     {
7388       char *fct_name = xstrdup (lang_printable_name (list, 0));
7389       parse_error_context 
7390         (wfl, "Can't access %s method `%s %s.%s' from `%s'",
7391          java_accstring_lookup (get_access_flags_from_decl (list)),
7392          lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0), 
7393          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (list)))), 
7394          fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
7395       free (fct_name);
7396       PATCH_METHOD_RETURN_ERROR ();
7397     }
7398   check_deprecation (wfl, list);
7399
7400   is_static_flag = METHOD_STATIC (list);
7401   if (! METHOD_STATIC (list) && this_arg != NULL_TREE)
7402     args = tree_cons (NULL_TREE, this_arg, args);
7403
7404   /* In the context of an explicit constructor invocation, we can't
7405      invoke any method relying on `this'. Exceptions are: we're
7406      invoking a static function, primary exists and is not the current
7407      this, we're creating a new object. */
7408   if (ctxp->explicit_constructor_p 
7409       && !is_static_flag 
7410       && (!primary || primary == current_this)
7411       && (TREE_CODE (patch) != NEW_CLASS_EXPR))
7412     {
7413       parse_error_context 
7414         (wfl, "Can't reference `this' before the superclass constructor has "
7415          "been called");
7416       PATCH_METHOD_RETURN_ERROR ();
7417     }
7418   java_parser_context_restore_global ();
7419   if (is_static) 
7420     *is_static = is_static_flag;
7421   /* Sometimes, we want the decl of the selected method. Such as for
7422      EH checking */
7423   if (ret_decl)
7424     *ret_decl = list;
7425   patch = patch_invoke (patch, list, args);
7426   if (is_super_init && CLASS_HAS_FINIT_P (current_class))
7427     {
7428       /* Generate the code used to initialize fields declared with an
7429          initialization statement. For now, it returns a call the the
7430          artificial function $finit$, if required. */
7431
7432       tree finit_call =
7433         build_method_invocation (build_expr_wfl (finit_identifier_node,  
7434                                                  input_filename, 0, 0),  
7435                                  NULL_TREE);
7436       patch = build (COMPOUND_EXPR, void_type_node, patch,
7437                      java_complete_tree (finit_call));
7438       CAN_COMPLETE_NORMALLY (patch) = 1;
7439     }
7440   return patch;
7441 }
7442
7443 /* Check that we're not trying to do a static reference to a method in
7444    non static method. Return 1 if it's the case, 0 otherwise. */
7445
7446 static int
7447 check_for_static_method_reference (wfl, node, method, where, primary)
7448      tree wfl, node, method, where, primary;
7449 {
7450   if (METHOD_STATIC (current_function_decl) 
7451       && !METHOD_STATIC (method) && !primary && !CALL_CONSTRUCTOR_P (node))
7452     {
7453       char *fct_name = xstrdup (lang_printable_name (method, 0));
7454       parse_error_context 
7455         (wfl, "Can't make static reference to method `%s %s' in class `%s'", 
7456          lang_printable_name (TREE_TYPE (TREE_TYPE (method)), 0), fct_name,
7457          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (where))));
7458       free (fct_name);
7459       return 1;
7460     }
7461   return 0;
7462 }
7463
7464 /* Patch an invoke expression METHOD and ARGS, based on its invocation
7465    mode.  */
7466
7467 static tree
7468 patch_invoke (patch, method, args)
7469      tree patch, method, args;
7470 {
7471   tree dtable, func;
7472   tree original_call, t, ta;
7473
7474   /* Last step for args: convert build-in types. If we're dealing with
7475      a new TYPE() type call, the first argument to the constructor
7476      isn't found in the incomming argument list, but delivered by
7477      `new' */
7478   t = TYPE_ARG_TYPES (TREE_TYPE (method));
7479   if (TREE_CODE (patch) == NEW_CLASS_EXPR)
7480     t = TREE_CHAIN (t);
7481   for (ta = args; t != end_params_node && ta; 
7482        t = TREE_CHAIN (t), ta = TREE_CHAIN (ta))
7483     if (JPRIMITIVE_TYPE_P (TREE_TYPE (TREE_VALUE (ta))) &&
7484         TREE_TYPE (TREE_VALUE (ta)) != TREE_VALUE (t))
7485       TREE_VALUE (ta) = convert (TREE_VALUE (t), TREE_VALUE (ta));
7486
7487   /* Resolve unresolved returned type isses */
7488   t = TREE_TYPE (TREE_TYPE (method));
7489   if (TREE_CODE (t) == POINTER_TYPE && !CLASS_LOADED_P (TREE_TYPE (t)))
7490     resolve_and_layout (TREE_TYPE (t), NULL);
7491   
7492   if (flag_emit_class_files || flag_emit_xref)
7493     func = method;
7494   else
7495     {
7496       tree signature = build_java_signature (TREE_TYPE (method));
7497       switch (invocation_mode (method, CALL_USING_SUPER (patch)))
7498         {
7499         case INVOKE_VIRTUAL:
7500           dtable = invoke_build_dtable (0, args);
7501           func = build_invokevirtual (dtable, method);
7502           break;
7503
7504         case INVOKE_SUPER:
7505         case INVOKE_STATIC:
7506           func = build_known_method_ref (method, TREE_TYPE (method),
7507                                          DECL_CONTEXT (method),
7508                                          signature, args);
7509           break;
7510
7511         case INVOKE_INTERFACE:
7512           dtable = invoke_build_dtable (1, args);
7513           func = build_invokeinterface (dtable, DECL_NAME (method), signature);
7514           break;
7515
7516         default:
7517           fatal ("internal error - unknown invocation_mode result");
7518         }
7519
7520       /* Ensure self_type is initialized, (invokestatic). FIXME */
7521       func = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (method)), func);
7522     }
7523
7524   TREE_TYPE (patch) = TREE_TYPE (TREE_TYPE (method));
7525   TREE_OPERAND (patch, 0) = func;
7526   TREE_OPERAND (patch, 1) = args;
7527   original_call = patch;
7528
7529   /* We're processing a `new TYPE ()' form. New is called an its
7530      returned value is the first argument to the constructor. We build
7531      a COMPOUND_EXPR and use saved expression so that the overall NEW
7532      expression value is a pointer to a newly created and initialized
7533      class. */
7534   if (TREE_CODE (original_call) == NEW_CLASS_EXPR)
7535     {
7536       tree class = DECL_CONTEXT (method);
7537       tree c1, saved_new, size, new;
7538       if (flag_emit_class_files || flag_emit_xref)
7539         {
7540           TREE_TYPE (patch) = build_pointer_type (class);
7541           return patch;
7542         }
7543       if (!TYPE_SIZE (class))
7544         safe_layout_class (class);
7545       size = size_in_bytes (class);
7546       new = build (CALL_EXPR, promote_type (class),
7547                    build_address_of (alloc_object_node),
7548                    tree_cons (NULL_TREE, build_class_ref (class),
7549                               build_tree_list (NULL_TREE, 
7550                                                size_in_bytes (class))),
7551                    NULL_TREE);
7552       saved_new = save_expr (new);
7553       c1 = build_tree_list (NULL_TREE, saved_new);
7554       TREE_CHAIN (c1) = TREE_OPERAND (original_call, 1);
7555       TREE_OPERAND (original_call, 1) = c1;
7556       TREE_SET_CODE (original_call, CALL_EXPR);
7557       patch = build (COMPOUND_EXPR, TREE_TYPE (new), patch, saved_new);
7558     }
7559   return patch;
7560 }
7561
7562 static int
7563 invocation_mode (method, super)
7564      tree method;
7565      int super;
7566 {
7567   int access = get_access_flags_from_decl (method);
7568
7569   if (super)
7570     return INVOKE_SUPER;
7571
7572   if (access & ACC_STATIC || access & ACC_FINAL || access & ACC_PRIVATE)
7573     return INVOKE_STATIC;
7574
7575   if (CLASS_FINAL (TYPE_NAME (DECL_CONTEXT (method))))
7576     return INVOKE_STATIC;
7577   
7578   if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))))
7579     return INVOKE_INTERFACE;
7580   
7581   if (DECL_CONSTRUCTOR_P (method))
7582     return INVOKE_STATIC;
7583
7584   return INVOKE_VIRTUAL;
7585 }
7586
7587 /* Retrieve a refined list of matching methods. It covers the step
7588    15.11.2 (Compile-Time Step 2) */
7589
7590 static tree
7591 lookup_method_invoke (lc, cl, class, name, arg_list)
7592      int lc;
7593      tree cl;
7594      tree class, name, arg_list;
7595 {
7596   tree atl = end_params_node;           /* Arg Type List */
7597   tree method, signature, list, node;
7598   const char *candidates;               /* Used for error report */
7599   char *dup;
7600
7601   /* Fix the arguments */
7602   for (node = arg_list; node; node = TREE_CHAIN (node))
7603     {
7604       tree current_arg = TREE_TYPE (TREE_VALUE (node));
7605       /* Non primitive type may have to be resolved */
7606       if (!JPRIMITIVE_TYPE_P (current_arg))
7607         resolve_and_layout (current_arg, NULL_TREE);
7608       /* And promoted */
7609       if (TREE_CODE (current_arg) == RECORD_TYPE)
7610         current_arg = promote_type (current_arg);
7611       atl = tree_cons (NULL_TREE, current_arg, atl);
7612     }
7613
7614   /* Find all candidates and then refine the list, searching for the
7615      most specific method. */
7616   list = find_applicable_accessible_methods_list (lc, class, name, atl);
7617   list = find_most_specific_methods_list (list);
7618   if (list && !TREE_CHAIN (list))
7619     return TREE_VALUE (list);
7620
7621   /* Issue an error. List candidates if any. Candidates are listed
7622      only if accessible (non accessible methods may end-up here for
7623      the sake of a better error report). */
7624   candidates = NULL;
7625   if (list)
7626     {
7627       tree current;
7628       obstack_grow (&temporary_obstack, ". Candidates are:\n", 18);
7629       for (current = list; current; current = TREE_CHAIN (current))
7630         {
7631           tree cm = TREE_VALUE (current);
7632           char string [4096];
7633           if (!cm || not_accessible_p (class, cm, 0))
7634             continue;
7635           sprintf 
7636             (string, "  `%s' in `%s'%s",
7637              get_printable_method_name (cm),
7638              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (cm)))),
7639              (TREE_CHAIN (current) ? "\n" : ""));
7640           obstack_grow (&temporary_obstack, string, strlen (string));
7641         }
7642       obstack_1grow (&temporary_obstack, '\0');
7643       candidates = obstack_finish (&temporary_obstack);
7644     }
7645   /* Issue the error message */
7646   method = make_node (FUNCTION_TYPE);
7647   TYPE_ARG_TYPES (method) = atl;
7648   signature = build_java_argument_signature (method);
7649   dup = strdup (lang_printable_name (class, 0));
7650   parse_error_context (cl, "Can't find %s `%s(%s)' in type `%s'%s",
7651                        (lc ? "constructor" : "method"),
7652                        (lc ? dup : IDENTIFIER_POINTER (name)),
7653                        IDENTIFIER_POINTER (signature), dup,
7654                        (candidates ? candidates : ""));
7655   free (dup);
7656   return NULL_TREE;
7657 }
7658
7659 /* 15.11.2.1: Find Methods that are Applicable and Accessible. LC is 1
7660    when we're looking for a constructor. */
7661
7662 static tree
7663 find_applicable_accessible_methods_list (lc, class, name, arglist)
7664      int lc;
7665      tree class, name, arglist;
7666 {
7667   tree list = NULL_TREE, all_list = NULL_TREE;
7668
7669   /* Search interfaces */
7670   if (CLASS_INTERFACE (TYPE_NAME (class)) 
7671       || CLASS_ABSTRACT (TYPE_NAME (class)))
7672     {
7673       static tree searched_interfaces = NULL_TREE;
7674       static int search_not_done = 0;
7675       int i, n;
7676       tree basetype_vec = TYPE_BINFO_BASETYPES (class);
7677
7678       /* Have we searched this interface already? */
7679       if (searched_interfaces)
7680         {  
7681           tree current;  
7682           for (current = searched_interfaces; 
7683                current; current = TREE_CHAIN (current))
7684             if (TREE_VALUE (current) == class)
7685               return NULL;
7686         }
7687       searched_interfaces = tree_cons (NULL_TREE, class, searched_interfaces);
7688
7689       search_applicable_methods_list 
7690         (lc, TYPE_METHODS (class), name, arglist, &list, &all_list);
7691
7692       n = TREE_VEC_LENGTH (basetype_vec);
7693       for (i = 0; i < n; i++)
7694         {
7695           tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
7696           tree rlist;
7697
7698           /* Skip java.lang.Object (we'll search it once later.) */
7699           if (t == object_type_node)
7700             continue;
7701
7702           search_not_done++;
7703           rlist = find_applicable_accessible_methods_list (lc,  t, name, 
7704                                                            arglist);
7705           all_list = chainon (rlist, (list ? list : all_list)); 
7706           search_not_done--;
7707         }
7708
7709       /* We're done. Reset the searched interfaces list and finally search
7710          java.lang.Object */
7711       if (!search_not_done)
7712         {  
7713           searched_interfaces = NULL_TREE;  
7714           search_applicable_methods_list (lc, TYPE_METHODS (object_type_node),
7715                                           name, arglist, &list, &all_list);
7716         }
7717     }
7718   /* Search classes */
7719   else
7720     while (class != NULL_TREE)
7721       {
7722         search_applicable_methods_list 
7723           (lc, TYPE_METHODS (class), name, arglist, &list, &all_list);
7724         class = (lc ? NULL_TREE : CLASSTYPE_SUPER (class));
7725       }
7726
7727   /* Either return the list obtained or all selected (but
7728      inaccessible) methods for better error report. */
7729   return (!list ? all_list : list);
7730 }
7731
7732 /* Effectively search for the approriate method in method */
7733
7734 static void 
7735 search_applicable_methods_list(lc, method, name, arglist, list, all_list)
7736      int lc;
7737      tree method, name, arglist;
7738      tree *list, *all_list;
7739 {
7740   for (; method; method = TREE_CHAIN (method))
7741     {
7742       /* When dealing with constructor, stop here, otherwise search
7743          other classes */
7744       if (lc && !DECL_CONSTRUCTOR_P (method))
7745         continue;
7746       else if (!lc && (DECL_CONSTRUCTOR_P (method) 
7747                        || (GET_METHOD_NAME (method) != name)))
7748         continue;
7749           
7750       if (argument_types_convertible (method, arglist))
7751         {
7752           /* Retain accessible methods only */
7753           if (!not_accessible_p (DECL_CONTEXT (current_function_decl), 
7754                                  method, 0))
7755             *list = tree_cons (NULL_TREE, method, *list);
7756           else
7757             /* Also retain all selected method here */
7758             *all_list = tree_cons (NULL_TREE, method, *list);
7759         }
7760     }
7761 }    
7762
7763 /* 15.11.2.2 Choose the Most Specific Method */
7764
7765 static tree
7766 find_most_specific_methods_list (list)
7767      tree list;
7768 {
7769   int max = 0;
7770   tree current, new_list = NULL_TREE;
7771   for (current = list; current; current = TREE_CHAIN (current))
7772     {
7773       tree method;
7774       DECL_SPECIFIC_COUNT (TREE_VALUE (current)) = 0;
7775
7776       for (method = list; method; method = TREE_CHAIN (method))
7777         {
7778           /* Don't test a method against itself */
7779           if (method == current)
7780             continue;
7781
7782           /* Compare arguments and location where method where declared */
7783           if (argument_types_convertible (TREE_VALUE (method), 
7784                                           TREE_VALUE (current))
7785               && valid_method_invocation_conversion_p 
7786                    (DECL_CONTEXT (TREE_VALUE (method)), 
7787                     DECL_CONTEXT (TREE_VALUE (current))))
7788             {
7789               int v = ++DECL_SPECIFIC_COUNT (TREE_VALUE (current));
7790               max = (v > max ? v : max);
7791             }
7792         }
7793     }
7794
7795   /* Review the list and select the maximally specific methods */
7796   for (current = list; current; current = TREE_CHAIN (current))
7797     if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
7798       new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
7799
7800   /* If we can't find one, lower expectations and try to gather multiple
7801      maximally specific methods */
7802   while (!new_list)
7803     {
7804       while (--max > 0)
7805         {
7806           if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
7807             new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
7808         }
7809       return new_list;
7810     }
7811
7812   return new_list;
7813 }
7814
7815 /* Make sure that the type of each M2_OR_ARGLIST arguments can be
7816    converted by method invocation conversion (5.3) to the type of the
7817    corresponding parameter of M1. Implementation expects M2_OR_ARGLIST
7818    to change less often than M1. */
7819
7820 static int
7821 argument_types_convertible (m1, m2_or_arglist)
7822     tree m1, m2_or_arglist;
7823 {
7824   static tree m2_arg_value = NULL_TREE;
7825   static tree m2_arg_cache = NULL_TREE;
7826
7827   register tree m1_arg, m2_arg;
7828
7829   m1_arg = TYPE_ARG_TYPES (TREE_TYPE (m1));
7830   if (!METHOD_STATIC (m1))
7831     m1_arg = TREE_CHAIN (m1_arg);
7832
7833   if (m2_arg_value == m2_or_arglist)
7834     m2_arg = m2_arg_cache;
7835   else
7836     {
7837       /* M2_OR_ARGLIST can be a function DECL or a raw list of
7838          argument types */
7839       if (m2_or_arglist && TREE_CODE (m2_or_arglist) == FUNCTION_DECL)
7840         {
7841           m2_arg = TYPE_ARG_TYPES (TREE_TYPE (m2_or_arglist));
7842           if (!METHOD_STATIC (m2_or_arglist))
7843             m2_arg = TREE_CHAIN (m2_arg);
7844         }
7845       else
7846         m2_arg = m2_or_arglist;
7847
7848       m2_arg_value = m2_or_arglist;
7849       m2_arg_cache = m2_arg;
7850     }
7851
7852   while (m1_arg != end_params_node && m2_arg != end_params_node)
7853     {
7854       resolve_and_layout (TREE_VALUE (m1_arg), NULL_TREE);
7855       if (!valid_method_invocation_conversion_p (TREE_VALUE (m1_arg),
7856                                                  TREE_VALUE (m2_arg)))
7857         break;
7858       m1_arg = TREE_CHAIN (m1_arg);
7859       m2_arg = TREE_CHAIN (m2_arg);
7860     }
7861   return m1_arg == end_params_node && m2_arg == end_params_node;
7862 }
7863
7864 /* Qualification routines */
7865
7866 static void
7867 qualify_ambiguous_name (id)
7868      tree id;
7869 {
7870   tree qual, qual_wfl, name = NULL_TREE, decl, ptr_type = NULL_TREE,
7871     saved_current_class;
7872   int again, super_found = 0, this_found = 0, new_array_found = 0;
7873   int code;
7874
7875   /* We first qualify the first element, then derive qualification of
7876      others based on the first one. If the first element is qualified
7877      by a resolution (field or type), this resolution is stored in the
7878      QUAL_RESOLUTION of the qual element being examined. We need to
7879      save the current_class since the use of SUPER might change the
7880      its value. */
7881   saved_current_class = current_class;
7882   qual = EXPR_WFL_QUALIFICATION (id);
7883   do {
7884
7885     /* Simple qualified expression feature a qual_wfl that is a
7886        WFL. Expression derived from a primary feature more complicated
7887        things like a CALL_EXPR. Expression from primary need to be
7888        worked out to extract the part on which the qualification will
7889        take place. */
7890     qual_wfl = QUAL_WFL (qual);
7891     switch (TREE_CODE (qual_wfl))
7892       {
7893       case CALL_EXPR:
7894         qual_wfl = TREE_OPERAND (qual_wfl, 0);
7895         if (TREE_CODE (qual_wfl) != EXPR_WITH_FILE_LOCATION)
7896           {
7897             qual = EXPR_WFL_QUALIFICATION (qual_wfl);
7898             qual_wfl = QUAL_WFL (qual);
7899           }
7900         break;
7901       case NEW_ARRAY_EXPR:
7902         qual = TREE_CHAIN (qual);
7903         again = new_array_found = 1;
7904         continue;
7905       case NEW_CLASS_EXPR:
7906       case CONVERT_EXPR:
7907         qual_wfl = TREE_OPERAND (qual_wfl, 0);
7908         break;
7909       case ARRAY_REF:
7910         while (TREE_CODE (qual_wfl) == ARRAY_REF)
7911           qual_wfl = TREE_OPERAND (qual_wfl, 0);
7912         break;
7913       case STRING_CST:
7914         qual = TREE_CHAIN (qual);
7915         qual_wfl = QUAL_WFL (qual);
7916         break;
7917       default:
7918         /* Fix for -Wall. Just break doing nothing */
7919         break;
7920       }
7921
7922     ptr_type = current_class;
7923     again = 0;
7924     code = TREE_CODE (qual_wfl);
7925
7926     /* Pos evaluation: non WFL leading expression nodes */
7927     if (code == CONVERT_EXPR
7928         && TREE_CODE (TREE_TYPE (qual_wfl)) == EXPR_WITH_FILE_LOCATION)
7929       name = EXPR_WFL_NODE (TREE_TYPE (qual_wfl));
7930
7931     else if ((code == ARRAY_REF || code == CALL_EXPR || code == MODIFY_EXPR) &&
7932              TREE_CODE (TREE_OPERAND (qual_wfl, 0)) == EXPR_WITH_FILE_LOCATION)
7933       name = EXPR_WFL_NODE (TREE_OPERAND (qual_wfl, 0));
7934
7935     else if (code == STRING_CST || code == CONDITIONAL_EXPR 
7936              || code == PLUS_EXPR)
7937       {
7938         qual = TREE_CHAIN (qual);
7939         qual_wfl = QUAL_WFL (qual);
7940         again = 1;
7941       }
7942     else 
7943       {
7944         name = EXPR_WFL_NODE (qual_wfl);
7945         if (!name)
7946           {
7947             qual = EXPR_WFL_QUALIFICATION (qual_wfl);
7948             again = 1;
7949           }
7950       }
7951
7952     /* If we have a THIS (from a primary), we set the context accordingly */
7953     if (name == this_identifier_node)
7954       {
7955         qual = TREE_CHAIN (qual);
7956         qual_wfl = QUAL_WFL (qual);
7957         if (TREE_CODE (qual_wfl) == CALL_EXPR)
7958           again = 1;
7959         else
7960           name = EXPR_WFL_NODE (qual_wfl);
7961         this_found = 1;
7962       }
7963     /* If we have a SUPER, we set the context accordingly */
7964     if (name == super_identifier_node)
7965       {
7966         current_class = CLASSTYPE_SUPER (ptr_type);
7967         /* Check that there is such a thing as a super class. If not,
7968            return.  The error will be caught later on, during the
7969            resolution */
7970         if (!current_class)
7971           {
7972             current_class = saved_current_class;
7973             return;
7974           }
7975         qual = TREE_CHAIN (qual);
7976         /* Do one more interation to set things up */
7977         super_found = again = 1;
7978       }
7979   } while (again);
7980   
7981   /* If name appears within the scope of a location variable
7982      declaration or parameter declaration, then it is an expression
7983      name. We don't carry this test out if we're in the context of the
7984      use of SUPER or THIS */
7985   if (!this_found && !super_found && 
7986       TREE_CODE (name) != STRING_CST && (decl = IDENTIFIER_LOCAL_VALUE (name)))
7987     {
7988       RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
7989       QUAL_RESOLUTION (qual) = decl;
7990     }
7991
7992   /* If within the class/interface NAME was found to be used there
7993      exists a (possibly inherited) field named NAME, then this is an
7994      expression name. If we saw a NEW_ARRAY_EXPR before and want to
7995      address length, it is OK. */
7996   else if ((decl = lookup_field_wrapper (ptr_type, name))
7997            || (new_array_found && name == length_identifier_node))
7998     {
7999       RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
8000       QUAL_RESOLUTION (qual) = (new_array_found ? NULL_TREE : decl);
8001     }
8002
8003   /* We reclassify NAME as yielding to a type name resolution if:
8004      - NAME is a class/interface declared within the compilation
8005        unit containing NAME,
8006      - NAME is imported via a single-type-import declaration,
8007      - NAME is declared in an another compilation unit of the package
8008        of the compilation unit containing NAME,
8009      - NAME is declared by exactly on type-import-on-demand declaration
8010      of the compilation unit containing NAME. 
8011      - NAME is actually a STRING_CST. */
8012   else if (TREE_CODE (name) == STRING_CST ||
8013            (decl = resolve_and_layout (name, NULL_TREE)))
8014     {
8015       RESOLVE_TYPE_NAME_P (qual_wfl) = 1;
8016       QUAL_RESOLUTION (qual) = decl;
8017     }
8018
8019   /* Method call are expression name */
8020   else if (TREE_CODE (QUAL_WFL (qual)) == CALL_EXPR
8021            || TREE_CODE (QUAL_WFL (qual)) == ARRAY_REF
8022            || TREE_CODE (QUAL_WFL (qual)) == CONVERT_EXPR)
8023     RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
8024
8025   /* Check here that NAME isn't declared by more than one
8026      type-import-on-demand declaration of the compilation unit
8027      containing NAME. FIXME */
8028
8029   /* Otherwise, NAME is reclassified as a package name */
8030   else 
8031     RESOLVE_PACKAGE_NAME_P (qual_wfl) = 1;
8032
8033   /* Propagate the qualification accross other components of the
8034      qualified name */
8035   for (qual = TREE_CHAIN (qual); qual;
8036        qual_wfl = QUAL_WFL (qual), qual = TREE_CHAIN (qual))
8037     {
8038       if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
8039         RESOLVE_PACKAGE_NAME_P (QUAL_WFL (qual)) = 1;
8040       else 
8041         RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (qual)) = 1;
8042     }
8043
8044   /* Store the global qualification for the ambiguous part of ID back
8045      into ID fields */
8046   if (RESOLVE_EXPRESSION_NAME_P (qual_wfl))
8047     RESOLVE_EXPRESSION_NAME_P (id) = 1;
8048   else if (RESOLVE_TYPE_NAME_P (qual_wfl))
8049     RESOLVE_TYPE_NAME_P (id) = 1;
8050   else if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
8051     RESOLVE_PACKAGE_NAME_P (id) = 1;
8052
8053   /* Restore the current class */
8054   current_class = saved_current_class;
8055 }
8056
8057 static int
8058 breakdown_qualified (left, right, source)
8059     tree *left, *right, source;
8060 {
8061   char *p = IDENTIFIER_POINTER (source), *base;
8062   int   l = IDENTIFIER_LENGTH (source);
8063
8064   /* Breakdown NAME into REMAINDER . IDENTIFIER */
8065   base = p;
8066   p += (l-1);
8067   while (*p != '.' && p != base)
8068     p--;
8069
8070   /* We didn't find a '.'. Return an error */
8071   if (p == base)
8072     return 1;
8073
8074   *p = '\0';
8075   if (right)
8076     *right = get_identifier (p+1);
8077   *left = get_identifier (IDENTIFIER_POINTER (source));
8078   *p = '.';
8079   
8080   return 0;
8081 }
8082
8083 /* Patch tree nodes in a function body. When a BLOCK is found, push
8084    local variable decls if present.
8085    Same as java_complete_lhs, but does resolve static finals to values. */
8086
8087 static tree
8088 java_complete_tree (node)
8089      tree node;
8090 {
8091   node = java_complete_lhs (node);
8092   if (TREE_CODE (node) == VAR_DECL && FIELD_STATIC (node)
8093       && FIELD_FINAL (node) && DECL_INITIAL (node) != NULL_TREE
8094       && !flag_emit_xref)
8095     {
8096       tree value = DECL_INITIAL (node);
8097       DECL_INITIAL (node) = NULL_TREE;
8098       push_obstacks (&permanent_obstack, &permanent_obstack);
8099       value = fold_constant_for_init (value, node);
8100       pop_obstacks ();
8101       DECL_INITIAL (node) = value;
8102       if (value != NULL_TREE)
8103         return value;
8104     }
8105   return node;
8106 }
8107
8108 static tree
8109 java_stabilize_reference (node)
8110      tree node;
8111 {
8112   if (TREE_CODE (node) == COMPOUND_EXPR)
8113     {
8114       tree op0 = TREE_OPERAND (node, 0);
8115       tree op1 = TREE_OPERAND (node, 1);
8116       TREE_OPERAND (node, 0) = save_expr (op0);
8117       TREE_OPERAND (node, 1) = java_stabilize_reference (op1);
8118       return node;
8119     }
8120   return stabilize_reference (node);
8121 }
8122
8123 /* Patch tree nodes in a function body. When a BLOCK is found, push
8124    local variable decls if present.
8125    Same as java_complete_tree, but does not resolve static finals to values. */
8126
8127 static tree
8128 java_complete_lhs (node)
8129      tree node;
8130 {
8131   tree nn, cn, wfl_op1, wfl_op2, wfl_op3;
8132   int flag;
8133
8134   /* CONVERT_EXPR always has its type set, even though it needs to be
8135      worked out. */
8136   if (TREE_TYPE (node) && TREE_CODE (node) != CONVERT_EXPR)
8137     return node;
8138
8139   /* The switch block implements cases processing container nodes
8140      first.  Contained nodes are always written back. Leaves come
8141      next and return a value. */
8142   switch (TREE_CODE (node))
8143     {
8144     case BLOCK:
8145
8146       /* 1- Block section.
8147          Set the local values on decl names so we can identify them
8148          faster when they're referenced. At that stage, identifiers
8149          are legal so we don't check for declaration errors. */
8150       for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
8151         {
8152           DECL_CONTEXT (cn) = current_function_decl;
8153           IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = cn;
8154         }
8155       if (BLOCK_EXPR_BODY (node) == NULL_TREE)
8156           CAN_COMPLETE_NORMALLY (node) = 1;
8157       else
8158         {
8159           tree stmt = BLOCK_EXPR_BODY (node);
8160           tree *ptr;
8161           int error_seen = 0;
8162           if (TREE_CODE (stmt) == COMPOUND_EXPR)
8163             {
8164               /* Re-order from (((A; B); C); ...; Z) to 
8165                  (A; (B; (C ; (...; Z)))).
8166                  This makes it easier to scan the statements left-to-right
8167                  without using recursion (which might overflow the stack
8168                  if the block has many statements. */
8169               for (;;)
8170                 {
8171                   tree left = TREE_OPERAND (stmt, 0);
8172                   if (TREE_CODE (left) != COMPOUND_EXPR)
8173                     break;
8174                   TREE_OPERAND (stmt, 0) = TREE_OPERAND (left, 1);
8175                   TREE_OPERAND (left, 1) = stmt;
8176                   stmt = left;
8177                 }
8178               BLOCK_EXPR_BODY (node) = stmt;
8179             }
8180
8181           /* Now do the actual complete, without deep recursion for
8182              long blocks. */
8183           ptr = &BLOCK_EXPR_BODY (node);
8184           while (TREE_CODE (*ptr) == COMPOUND_EXPR
8185                  && TREE_OPERAND (*ptr, 1) != empty_stmt_node)
8186             {
8187               tree cur = java_complete_tree (TREE_OPERAND (*ptr, 0));
8188               tree *next = &TREE_OPERAND (*ptr, 1);
8189               TREE_OPERAND (*ptr, 0) = cur;
8190               if (cur == empty_stmt_node)
8191                 {
8192                   /* Optimization;  makes it easier to detect empty bodies.
8193                      Most useful for <clinit> with all-constant initializer. */
8194                   *ptr = *next;
8195                   continue;
8196                 }
8197               if (TREE_CODE (cur) == ERROR_MARK)
8198                 error_seen++;
8199               else if (! CAN_COMPLETE_NORMALLY (cur))
8200                 {
8201                   wfl_op2 = *next;
8202                   for (;;)
8203                     {
8204                       if (TREE_CODE (wfl_op2) == BLOCK)
8205                         wfl_op2 = BLOCK_EXPR_BODY (wfl_op2);
8206                       else if (TREE_CODE (wfl_op2) == COMPOUND_EXPR)
8207                         wfl_op2 = TREE_OPERAND (wfl_op2, 0);
8208                       else
8209                         break;
8210                     }
8211                   if (TREE_CODE (wfl_op2) != CASE_EXPR
8212                       && TREE_CODE (wfl_op2) != DEFAULT_EXPR)
8213                     unreachable_stmt_error (*ptr);
8214                 }
8215               ptr = next;
8216             }
8217           *ptr = java_complete_tree (*ptr);
8218
8219           if (TREE_CODE (*ptr) == ERROR_MARK || error_seen > 0)
8220             return error_mark_node;
8221           CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (*ptr);
8222         }
8223       /* Turn local bindings to null */
8224       for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
8225         IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = NULL_TREE;
8226
8227       TREE_TYPE (node) = void_type_node;
8228       break;
8229
8230       /* 2- They are expressions but ultimately deal with statements */
8231
8232     case THROW_EXPR:
8233       wfl_op1 = TREE_OPERAND (node, 0);
8234       COMPLETE_CHECK_OP_0 (node);
8235       /* CAN_COMPLETE_NORMALLY (node) = 0; */
8236       return patch_throw_statement (node, wfl_op1);
8237
8238     case SYNCHRONIZED_EXPR:
8239       wfl_op1 = TREE_OPERAND (node, 0);
8240       return patch_synchronized_statement (node, wfl_op1);
8241
8242     case TRY_EXPR:
8243       return patch_try_statement (node);
8244
8245     case TRY_FINALLY_EXPR:
8246       COMPLETE_CHECK_OP_0 (node);
8247       COMPLETE_CHECK_OP_1 (node);
8248       CAN_COMPLETE_NORMALLY (node)
8249         = (CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0))
8250            && CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)));
8251       TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 0));
8252       return node;
8253
8254     case CLEANUP_POINT_EXPR:
8255       COMPLETE_CHECK_OP_0 (node);
8256       TREE_TYPE (node) = void_type_node;
8257       CAN_COMPLETE_NORMALLY (node) = 
8258         CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
8259       return node;
8260
8261     case WITH_CLEANUP_EXPR:
8262       COMPLETE_CHECK_OP_0 (node);
8263       COMPLETE_CHECK_OP_2 (node);
8264       CAN_COMPLETE_NORMALLY (node) = 
8265         CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
8266       TREE_TYPE (node) = void_type_node;
8267       return node;
8268
8269     case LABELED_BLOCK_EXPR:
8270       PUSH_LABELED_BLOCK (node);
8271       if (LABELED_BLOCK_BODY (node))
8272         COMPLETE_CHECK_OP_1 (node);
8273       TREE_TYPE (node) = void_type_node;
8274       POP_LABELED_BLOCK ();
8275
8276       if (LABELED_BLOCK_BODY (node) == empty_stmt_node)
8277         {
8278           LABELED_BLOCK_BODY (node) = NULL_TREE;
8279           CAN_COMPLETE_NORMALLY (node) = 1;
8280         }
8281       else if (CAN_COMPLETE_NORMALLY (LABELED_BLOCK_BODY (node)))
8282         CAN_COMPLETE_NORMALLY (node) = 1;
8283       return node;
8284
8285     case EXIT_BLOCK_EXPR:
8286       /* We don't complete operand 1, because it's the return value of
8287          the EXIT_BLOCK_EXPR which doesn't exist it Java */
8288       return patch_bc_statement (node);
8289
8290     case CASE_EXPR:
8291       cn = java_complete_tree (TREE_OPERAND (node, 0));
8292       if (cn == error_mark_node)
8293         return cn;
8294
8295       /* First, the case expression must be constant. Values of final
8296          fields are accepted. */
8297       cn = fold (cn);
8298       if ((TREE_CODE (cn) == COMPOUND_EXPR || TREE_CODE (cn) == COMPONENT_REF)
8299           && JDECL_P (TREE_OPERAND (cn, 1))
8300           && FIELD_FINAL (TREE_OPERAND (cn, 1))
8301           && DECL_INITIAL (TREE_OPERAND (cn, 1)))
8302         {
8303           push_obstacks (&permanent_obstack, &permanent_obstack);
8304           cn = fold_constant_for_init (DECL_INITIAL (TREE_OPERAND (cn, 1)),
8305                                        TREE_OPERAND (cn, 1));
8306           pop_obstacks ();
8307         }
8308
8309       if (!TREE_CONSTANT (cn) && !flag_emit_xref)
8310         {
8311           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
8312           parse_error_context (node, "Constant expression required");
8313           return error_mark_node;
8314         }
8315
8316       nn = ctxp->current_loop;
8317
8318       /* It must be assignable to the type of the switch expression. */
8319       if (!try_builtin_assignconv (NULL_TREE, 
8320                                    TREE_TYPE (TREE_OPERAND (nn, 0)), cn))
8321         {
8322           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
8323           parse_error_context 
8324             (wfl_operator,
8325              "Incompatible type for case. Can't convert `%s' to `int'",
8326              lang_printable_name (TREE_TYPE (cn), 0));
8327           return error_mark_node;
8328         }
8329
8330       cn = fold (convert (int_type_node, cn));
8331
8332       /* Multiple instance of a case label bearing the same
8333          value is checked during code generation. The case
8334          expression is allright so far. */
8335       TREE_OPERAND (node, 0) = cn;
8336       TREE_TYPE (node) = void_type_node;
8337       CAN_COMPLETE_NORMALLY (node) = 1;
8338       TREE_SIDE_EFFECTS (node) = 1;
8339       break;
8340
8341     case DEFAULT_EXPR:
8342       nn = ctxp->current_loop;
8343       /* Only one default label is allowed per switch statement */
8344       if (SWITCH_HAS_DEFAULT (nn))
8345         {
8346           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
8347           parse_error_context (wfl_operator, 
8348                                "Duplicate case label: `default'");
8349           return error_mark_node;
8350         }
8351       else
8352         SWITCH_HAS_DEFAULT (nn) = 1;
8353       TREE_TYPE (node) = void_type_node;
8354       TREE_SIDE_EFFECTS (node) = 1;
8355       CAN_COMPLETE_NORMALLY (node) = 1;
8356       break;
8357
8358     case SWITCH_EXPR:
8359     case LOOP_EXPR:
8360       PUSH_LOOP (node);
8361       /* Check whether the loop was enclosed in a labeled
8362          statement. If not, create one, insert the loop in it and
8363          return the node */
8364       nn = patch_loop_statement (node);
8365
8366       /* Anyways, walk the body of the loop */
8367       if (TREE_CODE (node) == LOOP_EXPR)
8368         TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
8369       /* Switch statement: walk the switch expression and the cases */
8370       else
8371         node = patch_switch_statement (node);
8372
8373       if (TREE_OPERAND (node, 0) == error_mark_node)
8374         nn = error_mark_node;
8375       else
8376         {
8377           TREE_TYPE (nn) = TREE_TYPE (node) = void_type_node;
8378           /* If we returned something different, that's because we
8379              inserted a label. Pop the label too. */
8380           if (nn != node)
8381             {
8382               if (CAN_COMPLETE_NORMALLY (node))
8383                 CAN_COMPLETE_NORMALLY (nn) = 1;
8384               POP_LABELED_BLOCK ();
8385             }
8386         }
8387       POP_LOOP ();
8388       return nn;
8389
8390     case EXIT_EXPR:
8391       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
8392       return patch_exit_expr (node);
8393
8394     case COND_EXPR:
8395       /* Condition */
8396       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
8397       if (TREE_OPERAND (node, 0) == error_mark_node)
8398         return error_mark_node;
8399       /* then-else branches */
8400       TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
8401       if (TREE_OPERAND (node, 1) == error_mark_node)
8402         return error_mark_node;
8403       TREE_OPERAND (node, 2) = java_complete_tree (TREE_OPERAND (node, 2));
8404       if (TREE_OPERAND (node, 2) == error_mark_node)
8405         return error_mark_node;
8406       return patch_if_else_statement (node);
8407       break;
8408
8409     case CONDITIONAL_EXPR:
8410       /* Condition */
8411       wfl_op1 = TREE_OPERAND (node, 0);
8412       COMPLETE_CHECK_OP_0 (node);
8413       wfl_op2 = TREE_OPERAND (node, 1);
8414       COMPLETE_CHECK_OP_1 (node);
8415       wfl_op3 = TREE_OPERAND (node, 2);
8416       COMPLETE_CHECK_OP_2 (node);
8417       return patch_conditional_expr (node, wfl_op1, wfl_op2);
8418
8419       /* 3- Expression section */
8420     case COMPOUND_EXPR:
8421       wfl_op2 = TREE_OPERAND (node, 1);
8422       TREE_OPERAND (node, 0) = nn = 
8423         java_complete_tree (TREE_OPERAND (node, 0));
8424       if (wfl_op2 == empty_stmt_node)
8425         CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (nn);
8426       else
8427         {
8428           if (! CAN_COMPLETE_NORMALLY (nn) && TREE_CODE (nn) != ERROR_MARK)
8429             {
8430               /* An unreachable condition in a do-while statement
8431                  is *not* (technically) an unreachable statement. */
8432               nn = wfl_op2;
8433               if (TREE_CODE (nn) == EXPR_WITH_FILE_LOCATION)
8434                 nn = EXPR_WFL_NODE (nn);
8435               if (TREE_CODE (nn) != EXIT_EXPR)
8436                 {
8437                   SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
8438                   parse_error_context (wfl_operator, "Unreachable statement");
8439                 }
8440             }
8441           TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
8442           if (TREE_OPERAND (node, 1) == error_mark_node)
8443             return error_mark_node;
8444           CAN_COMPLETE_NORMALLY (node)
8445             = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1));
8446         }
8447       TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 1));
8448       break;
8449
8450     case RETURN_EXPR:
8451       /* CAN_COMPLETE_NORMALLY (node) = 0; */
8452       return patch_return (node);
8453
8454     case EXPR_WITH_FILE_LOCATION:
8455       if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
8456           || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
8457         {
8458           tree wfl = node;
8459           node = resolve_expression_name (node, NULL);
8460           if (node == error_mark_node)
8461             return node;
8462           /* Keep line number information somewhere were it doesn't
8463              disrupt the completion process. */
8464           if (flag_emit_xref && TREE_CODE (node) != CALL_EXPR)
8465             {
8466               EXPR_WFL_NODE (wfl) = TREE_OPERAND (node, 1);
8467               TREE_OPERAND (node, 1) = wfl;
8468             }
8469           CAN_COMPLETE_NORMALLY (node) = 1;
8470         }
8471       else
8472         {
8473           tree body;
8474           int save_lineno = lineno;
8475           lineno = EXPR_WFL_LINENO (node);
8476           body = java_complete_tree (EXPR_WFL_NODE (node));
8477           lineno = save_lineno;
8478           EXPR_WFL_NODE (node) = body;
8479           TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (body);
8480           CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (body);
8481           if (body == empty_stmt_node)
8482             {
8483               /* Optimization;  makes it easier to detect empty bodies. */
8484               return body;
8485             }
8486           if (body == error_mark_node)
8487             {
8488               /* Its important for the evaluation of assignment that
8489                  this mark on the TREE_TYPE is propagated. */
8490               TREE_TYPE (node) = error_mark_node;
8491               return error_mark_node;
8492             }
8493           else
8494             TREE_TYPE (node) = TREE_TYPE (EXPR_WFL_NODE (node));
8495           
8496         }
8497       break;
8498
8499     case NEW_ARRAY_EXPR:
8500       /* Patch all the dimensions */
8501       flag = 0;
8502       for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
8503         {
8504           int location = EXPR_WFL_LINECOL (TREE_VALUE (cn));
8505           tree dim = convert (int_type_node, 
8506                               java_complete_tree (TREE_VALUE (cn)));
8507           if (dim == error_mark_node)
8508             {
8509               flag = 1;
8510               continue;
8511             }
8512           else
8513             {
8514               TREE_VALUE (cn) = dim;
8515               /* Setup the location of the current dimension, for
8516                  later error report. */
8517               TREE_PURPOSE (cn) = 
8518                 build_expr_wfl (NULL_TREE, input_filename, 0, 0);
8519               EXPR_WFL_LINECOL (TREE_PURPOSE (cn)) = location;
8520             }
8521         }
8522       /* They complete the array creation expression, if no errors
8523          were found. */
8524       CAN_COMPLETE_NORMALLY (node) = 1;
8525       return (flag ? error_mark_node
8526               : force_evaluation_order (patch_newarray (node)));
8527
8528     case NEW_CLASS_EXPR:
8529     case CALL_EXPR:
8530       /* Complete function's argument(s) first */
8531       if (complete_function_arguments (node))
8532         return error_mark_node;
8533       else
8534         {
8535           tree decl, wfl = TREE_OPERAND (node, 0);
8536           int in_this = CALL_THIS_CONSTRUCTOR_P (node);
8537
8538           node = patch_method_invocation (node, NULL_TREE, 
8539                                           NULL_TREE, 0, &decl);
8540           if (node == error_mark_node)
8541             return error_mark_node;
8542
8543           check_thrown_exceptions (EXPR_WFL_LINECOL (node), decl);
8544           /* If we call this(...), register signature and positions */
8545           if (in_this)
8546             DECL_CONSTRUCTOR_CALLS (current_function_decl) = 
8547               tree_cons (wfl, decl, 
8548                          DECL_CONSTRUCTOR_CALLS (current_function_decl));
8549           CAN_COMPLETE_NORMALLY (node) = 1;
8550           return force_evaluation_order (node);
8551         }
8552
8553     case MODIFY_EXPR:
8554       /* Save potential wfls */
8555       wfl_op1 = TREE_OPERAND (node, 0);
8556       TREE_OPERAND (node, 0) = nn = java_complete_lhs (wfl_op1);
8557       if (MODIFY_EXPR_FROM_INITIALIZATION_P (node)
8558           && TREE_CODE (nn) == VAR_DECL && TREE_STATIC (nn)
8559           && DECL_INITIAL (nn) != NULL_TREE)
8560         {
8561           tree value;
8562           
8563           push_obstacks (&permanent_obstack, &permanent_obstack);
8564           value = fold_constant_for_init (nn, nn);
8565           pop_obstacks ();
8566           if (value != NULL_TREE)
8567             {
8568               tree type = TREE_TYPE (value);
8569               if (JPRIMITIVE_TYPE_P (type) || type == string_ptr_type_node)
8570                 return empty_stmt_node;
8571             }
8572           DECL_INITIAL (nn) = NULL_TREE;
8573         }
8574       wfl_op2 = TREE_OPERAND (node, 1);
8575
8576       if (TREE_OPERAND (node, 0) == error_mark_node)
8577         return error_mark_node;
8578
8579       flag = COMPOUND_ASSIGN_P (wfl_op2);
8580       if (flag)
8581         {
8582           tree lvalue = java_stabilize_reference (TREE_OPERAND (node, 0)); 
8583
8584           /* Hand stablize the lhs on both places */
8585           TREE_OPERAND (node, 0) = lvalue;
8586           TREE_OPERAND (TREE_OPERAND (node, 1), 0) = 
8587             (flag_emit_class_files ? lvalue : save_expr (lvalue));
8588
8589           /* 15.25.2.a: Left hand is not an array access. FIXME */
8590           /* Now complete the RHS. We write it back later on. */
8591           nn = java_complete_tree (TREE_OPERAND (node, 1));
8592
8593           if ((cn = patch_string (nn)))
8594             nn = cn;
8595
8596           /* The last part of the rewrite for E1 op= E2 is to have 
8597              E1 = (T)(E1 op E2), with T being the type of E1. */
8598           nn = java_complete_tree (build_cast (EXPR_WFL_LINECOL (wfl_op2), 
8599                                                TREE_TYPE (lvalue), nn));
8600
8601           /* 15.25.2.b: Left hand is an array access. FIXME */
8602         }
8603
8604       /* If we're about to patch a NEW_ARRAY_INIT, we call a special
8605          function to complete this RHS */
8606       else if (TREE_CODE (wfl_op2) == NEW_ARRAY_INIT)
8607         nn = patch_new_array_init (TREE_TYPE (TREE_OPERAND (node, 0)),
8608                                    TREE_OPERAND (node, 1));
8609       /* Otherwise we simply complete the RHS */
8610       else
8611         nn = java_complete_tree (TREE_OPERAND (node, 1));
8612
8613       if (nn == error_mark_node)
8614         return error_mark_node;
8615
8616       /* Write back the RHS as we evaluated it. */
8617       TREE_OPERAND (node, 1) = nn;
8618
8619       /* In case we're handling = with a String as a RHS, we need to
8620          produce a String out of the RHS (it might still be a
8621          STRING_CST or a StringBuffer at this stage */
8622       if ((nn = patch_string (TREE_OPERAND (node, 1))))
8623         TREE_OPERAND (node, 1) = nn;
8624       node = patch_assignment (node, wfl_op1, wfl_op2);
8625       /* Reorganize the tree if necessary. */
8626       if (flag && (!JREFERENCE_TYPE_P (TREE_TYPE (node)) 
8627                    || JSTRING_P (TREE_TYPE (node))))
8628         node = java_refold (node);
8629       CAN_COMPLETE_NORMALLY (node) = 1;
8630       return node;
8631
8632     case MULT_EXPR:
8633     case PLUS_EXPR:
8634     case MINUS_EXPR:
8635     case LSHIFT_EXPR:
8636     case RSHIFT_EXPR:
8637     case URSHIFT_EXPR:
8638     case BIT_AND_EXPR:
8639     case BIT_XOR_EXPR:
8640     case BIT_IOR_EXPR:
8641     case TRUNC_MOD_EXPR:
8642     case RDIV_EXPR:
8643     case TRUTH_ANDIF_EXPR:
8644     case TRUTH_ORIF_EXPR:
8645     case EQ_EXPR: 
8646     case NE_EXPR:
8647     case GT_EXPR:
8648     case GE_EXPR:
8649     case LT_EXPR:
8650     case LE_EXPR:
8651       /* Operands 0 and 1 are WFL in certain cases only. patch_binop
8652          knows how to handle those cases. */
8653       wfl_op1 = TREE_OPERAND (node, 0);
8654       wfl_op2 = TREE_OPERAND (node, 1);
8655
8656       CAN_COMPLETE_NORMALLY (node) = 1;
8657       /* Don't complete string nodes if dealing with the PLUS operand. */
8658       if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op1))
8659         {
8660           nn = java_complete_tree (wfl_op1);
8661           if (nn == error_mark_node)
8662             return error_mark_node;
8663           if ((cn = patch_string (nn)))
8664             nn = cn;
8665           TREE_OPERAND (node, 0) = nn;
8666         }
8667       if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op2))
8668         {
8669           nn = java_complete_tree (wfl_op2);
8670           if (nn == error_mark_node)
8671             return error_mark_node;
8672           if ((cn = patch_string (nn)))
8673             nn = cn;
8674           TREE_OPERAND (node, 1) = nn;
8675         }
8676       return force_evaluation_order (patch_binop (node, wfl_op1, wfl_op2));
8677
8678     case INSTANCEOF_EXPR:
8679       wfl_op1 = TREE_OPERAND (node, 0);
8680       COMPLETE_CHECK_OP_0 (node);
8681       if (flag_emit_xref)
8682         {
8683           TREE_TYPE (node) = boolean_type_node;
8684           return node;
8685         }
8686       return patch_binop (node, wfl_op1, TREE_OPERAND (node, 1));
8687
8688     case UNARY_PLUS_EXPR:
8689     case NEGATE_EXPR:
8690     case TRUTH_NOT_EXPR:
8691     case BIT_NOT_EXPR:
8692     case PREDECREMENT_EXPR:
8693     case PREINCREMENT_EXPR:
8694     case POSTDECREMENT_EXPR:
8695     case POSTINCREMENT_EXPR:
8696     case CONVERT_EXPR:
8697       /* There are cases were wfl_op1 is a WFL. patch_unaryop knows
8698          how to handle those cases. */
8699       wfl_op1 = TREE_OPERAND (node, 0);
8700       CAN_COMPLETE_NORMALLY (node) = 1;
8701       TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
8702       if (TREE_OPERAND (node, 0) == error_mark_node)
8703         return error_mark_node;
8704       node = patch_unaryop (node, wfl_op1);
8705       CAN_COMPLETE_NORMALLY (node) = 1;
8706       break;
8707
8708     case ARRAY_REF:
8709       /* There are cases were wfl_op1 is a WFL. patch_array_ref knows
8710          how to handle those cases. */
8711       wfl_op1 = TREE_OPERAND (node, 0);
8712       TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
8713       if (TREE_OPERAND (node, 0) == error_mark_node)
8714         return error_mark_node;
8715       if (!flag_emit_class_files && !flag_emit_xref)
8716         TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
8717       /* The same applies to wfl_op2 */
8718       wfl_op2 = TREE_OPERAND (node, 1);
8719       TREE_OPERAND (node, 1) = java_complete_tree (wfl_op2);
8720       if (TREE_OPERAND (node, 1) == error_mark_node)
8721         return error_mark_node;
8722       if (!flag_emit_class_files && !flag_emit_xref)
8723         TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1));
8724       return patch_array_ref (node);
8725
8726     case RECORD_TYPE:
8727       return node;;
8728
8729     case COMPONENT_REF:
8730       /* The first step in the re-write of qualified name handling.  FIXME.
8731          So far, this is only to support PRIMTYPE.class -> PRIMCLASS.TYPE. */
8732       TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
8733       if (TREE_CODE (TREE_OPERAND (node, 0)) == RECORD_TYPE)
8734         {
8735           tree name = TREE_OPERAND (node, 1);
8736           tree field = lookup_field_wrapper (TREE_OPERAND (node, 0), name);
8737           if (field == NULL_TREE)
8738             {
8739               error ("missing static field `%s'", IDENTIFIER_POINTER (name));
8740               return error_mark_node;
8741             }
8742           if (! FIELD_STATIC (field))
8743             {
8744               error ("not a static field `%s'", IDENTIFIER_POINTER (name));
8745               return error_mark_node;
8746             }
8747           return field;
8748         }
8749       else
8750         fatal ("unimplemented java_complete_tree for COMPONENT_REF");
8751       break;
8752
8753     case THIS_EXPR:
8754       /* Can't use THIS in a static environment */
8755       if (!current_this)
8756         {
8757           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
8758           parse_error_context (wfl_operator, "Keyword `this' used outside "
8759                                "allowed context");
8760           TREE_TYPE (node) = error_mark_node;
8761           return error_mark_node;
8762         }
8763       if (ctxp->explicit_constructor_p)
8764         {
8765           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
8766           parse_error_context 
8767             (wfl_operator, "Can't reference `this' or `super' before the "
8768              "superclass constructor has been called");
8769           TREE_TYPE (node) = error_mark_node;
8770           return error_mark_node;
8771         }
8772       return current_this;
8773
8774     default:
8775       CAN_COMPLETE_NORMALLY (node) = 1;
8776       /* Ok: may be we have a STRING_CST or a crafted `StringBuffer'
8777          and it's time to turn it into the appropriate String object
8778          */
8779       if ((node = patch_string (node)))
8780         return node;
8781       fatal ("No case for tree code `%s' - java_complete_tree\n",
8782              tree_code_name [TREE_CODE (node)]);
8783     }
8784   return node;
8785 }
8786
8787 /* Complete function call's argument. Return a non zero value is an
8788    error was found.  */
8789
8790 static int
8791 complete_function_arguments (node)
8792      tree node;
8793 {
8794   int flag = 0;
8795   tree cn;
8796
8797   ctxp->explicit_constructor_p += (CALL_EXPLICIT_CONSTRUCTOR_P (node) ? 1 : 0);
8798   for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
8799     {
8800       tree wfl = TREE_VALUE (cn), parm, temp;
8801       parm = java_complete_tree (wfl);
8802       if (parm == error_mark_node)
8803         {
8804           flag = 1;
8805           continue;
8806         }
8807       /* If have a string literal that we haven't transformed yet or a
8808          crafted string buffer, as a result of use of the the String
8809          `+' operator. Build `parm.toString()' and expand it. */
8810       if ((temp = patch_string (parm)))
8811         parm = temp;
8812       /* Inline PRIMTYPE.TYPE read access */
8813       parm = maybe_build_primttype_type_ref (parm, wfl);
8814
8815       TREE_VALUE (cn) = parm;
8816     }
8817   ctxp->explicit_constructor_p -= (CALL_EXPLICIT_CONSTRUCTOR_P (node) ? 1 : 0);
8818   return flag;
8819 }
8820
8821 /* Sometimes (for loops and variable initialized during their
8822    declaration), we want to wrap a statement around a WFL and turn it
8823    debugable.  */
8824
8825 static tree
8826 build_debugable_stmt (location, stmt)
8827     int location;
8828     tree stmt;
8829 {
8830   if (TREE_CODE (stmt) != EXPR_WITH_FILE_LOCATION)
8831     {
8832       stmt = build_expr_wfl (stmt, input_filename, 0, 0);
8833       EXPR_WFL_LINECOL (stmt) = location;
8834     }
8835   JAVA_MAYBE_GENERATE_DEBUG_INFO (stmt);
8836   return stmt;
8837 }
8838
8839 static tree
8840 build_expr_block (body, decls)
8841      tree body, decls;
8842 {
8843   tree node = make_node (BLOCK);
8844   BLOCK_EXPR_DECLS (node) = decls;
8845   BLOCK_EXPR_BODY (node) = body;
8846   if (body)
8847     TREE_TYPE (node) = TREE_TYPE (body);
8848   TREE_SIDE_EFFECTS (node) = 1;
8849   return node;
8850 }
8851
8852 /* Create a new function block and link it approriately to current
8853    function block chain */
8854
8855 static tree
8856 enter_block ()
8857 {
8858   return (enter_a_block (build_expr_block (NULL_TREE, NULL_TREE)));
8859 }
8860
8861 /* Link block B supercontext to the previous block. The current
8862    function DECL is used as supercontext when enter_a_block is called
8863    for the first time for a given function. The current function body
8864    (DECL_FUNCTION_BODY) is set to be block B.  */
8865
8866 static tree
8867 enter_a_block (b)
8868      tree b;
8869 {
8870   tree fndecl = current_function_decl; 
8871
8872   if (!fndecl) {
8873     BLOCK_SUPERCONTEXT (b) = current_static_block;
8874     current_static_block = b;
8875   }
8876
8877   else if (!DECL_FUNCTION_BODY (fndecl))
8878     {
8879       BLOCK_SUPERCONTEXT (b) = fndecl;
8880       DECL_FUNCTION_BODY (fndecl) = b;
8881     }
8882   else
8883     {
8884       BLOCK_SUPERCONTEXT (b) = DECL_FUNCTION_BODY (fndecl);
8885       DECL_FUNCTION_BODY (fndecl) = b;
8886     }
8887   return b;
8888 }
8889
8890 /* Exit a block by changing the current function body
8891    (DECL_FUNCTION_BODY) to the current block super context, only if
8892    the block being exited isn't the method's top level one.  */
8893
8894 static tree
8895 exit_block ()
8896 {
8897   tree b;
8898   if (current_function_decl)
8899     {
8900       b = DECL_FUNCTION_BODY (current_function_decl);
8901       if (BLOCK_SUPERCONTEXT (b) != current_function_decl)
8902         DECL_FUNCTION_BODY (current_function_decl) = BLOCK_SUPERCONTEXT (b);
8903     }
8904   else
8905     {
8906       b = current_static_block;
8907
8908       if (BLOCK_SUPERCONTEXT (b))
8909         current_static_block = BLOCK_SUPERCONTEXT (b);
8910     }
8911   return b;
8912 }
8913
8914 /* Lookup for NAME in the nested function's blocks, all the way up to
8915    the current toplevel one. It complies with Java's local variable
8916    scoping rules.  */
8917
8918 static tree
8919 lookup_name_in_blocks (name)
8920      tree name;
8921 {
8922   tree b = GET_CURRENT_BLOCK (current_function_decl);
8923
8924   while (b != current_function_decl)
8925     {
8926       tree current;
8927
8928       /* Paranoid sanity check. To be removed */
8929       if (TREE_CODE (b) != BLOCK)
8930         fatal ("non block expr function body - lookup_name_in_blocks");
8931
8932       for (current = BLOCK_EXPR_DECLS (b); current; 
8933            current = TREE_CHAIN (current))
8934         if (DECL_NAME (current) == name)
8935           return current;
8936       b = BLOCK_SUPERCONTEXT (b);
8937     }
8938   return NULL_TREE;
8939 }
8940
8941 static void
8942 maybe_absorb_scoping_blocks ()
8943 {
8944   while (BLOCK_EXPR_ORIGIN (GET_CURRENT_BLOCK (current_function_decl)))
8945     {
8946       tree b = exit_block ();
8947       java_method_add_stmt (current_function_decl, b);
8948       SOURCE_FRONTEND_DEBUG (("Absorbing scoping block at line %d", lineno));
8949     }
8950 }
8951
8952 \f
8953 /* This section of the source is reserved to build_* functions that
8954    are building incomplete tree nodes and the patch_* functions that
8955    are completing them.  */
8956
8957 /* Build a super() constructor invocation. Returns empty_stmt_node if
8958    we're currently dealing with the class java.lang.Object. */
8959
8960 static tree
8961 build_super_invocation (mdecl)
8962      tree mdecl;
8963 {
8964   if (DECL_CONTEXT (mdecl) == object_type_node)
8965     return empty_stmt_node;
8966   else
8967     {
8968       tree super_wfl = build_wfl_node (super_identifier_node);
8969       return build_method_invocation (super_wfl, NULL_TREE);
8970     }
8971 }
8972
8973 /* Build a SUPER/THIS qualified method invocation.  */
8974
8975 static tree
8976 build_this_super_qualified_invocation (use_this, name, args, lloc, rloc)
8977      int use_this;
8978      tree name, args;
8979      int lloc, rloc;
8980
8981 {
8982   tree invok;
8983   tree wfl = 
8984     build_wfl_node (use_this ? this_identifier_node : super_identifier_node);
8985   EXPR_WFL_LINECOL (wfl) = lloc;
8986   invok = build_method_invocation (name, args);
8987   return make_qualified_primary (wfl, invok, rloc);
8988 }
8989
8990 /* Build an incomplete CALL_EXPR node. */
8991
8992 static tree
8993 build_method_invocation (name, args)
8994     tree name;
8995     tree args;
8996 {
8997   tree call = build (CALL_EXPR, NULL_TREE, name, args, NULL_TREE);
8998   TREE_SIDE_EFFECTS (call) = 1;
8999   EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
9000   return call;
9001 }
9002
9003 /* Build an incomplete new xxx(...) node. */
9004
9005 static tree
9006 build_new_invocation (name, args)
9007     tree name, args;
9008 {
9009   tree call = build (NEW_CLASS_EXPR, NULL_TREE, name, args, NULL_TREE);
9010   TREE_SIDE_EFFECTS (call) = 1;
9011   EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
9012   return call;
9013 }
9014
9015 /* Build an incomplete assignment expression. */
9016
9017 static tree
9018 build_assignment (op, op_location, lhs, rhs)
9019      int op, op_location;
9020      tree lhs, rhs;
9021 {
9022   tree assignment;
9023   /* Build the corresponding binop if we deal with a Compound
9024      Assignment operator. Mark the binop sub-tree as part of a
9025      Compound Assignment expression */
9026   if (op != ASSIGN_TK)
9027     {
9028       rhs = build_binop (BINOP_LOOKUP (op), op_location, lhs, rhs);
9029       COMPOUND_ASSIGN_P (rhs) = 1;
9030     }
9031   assignment = build (MODIFY_EXPR, NULL_TREE, lhs, rhs);
9032   TREE_SIDE_EFFECTS (assignment) = 1;
9033   EXPR_WFL_LINECOL (assignment) = op_location;
9034   return assignment;
9035 }
9036
9037 /* Print an INTEGER_CST node in a static buffer, and return the buffer. */
9038
9039 char *
9040 print_int_node (node)
9041     tree node;
9042 {
9043   static char buffer [80];
9044   if (TREE_CONSTANT_OVERFLOW (node))
9045     sprintf (buffer, "<overflow>");
9046     
9047   if (TREE_INT_CST_HIGH (node) == 0)
9048     sprintf (buffer, HOST_WIDE_INT_PRINT_UNSIGNED,
9049              TREE_INT_CST_LOW (node));
9050   else if (TREE_INT_CST_HIGH (node) == -1
9051            && TREE_INT_CST_LOW (node) != 0)
9052     {
9053       buffer [0] = '-';
9054       sprintf (&buffer [1], HOST_WIDE_INT_PRINT_UNSIGNED,
9055                -TREE_INT_CST_LOW (node));
9056     }
9057   else
9058     sprintf (buffer, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
9059              TREE_INT_CST_HIGH (node), TREE_INT_CST_LOW (node));
9060
9061   return buffer;
9062 }
9063
9064 /* Return 1 if an assignment to a FINAL is attempted in a non suitable
9065    context.  */
9066
9067 static int
9068 check_final_assignment (lvalue, wfl)
9069      tree lvalue, wfl;
9070 {
9071   if (JDECL_P (lvalue) 
9072       && FIELD_FINAL (lvalue) && !IS_CLINIT (current_function_decl))
9073     {
9074       parse_error_context 
9075         (wfl, "Can't assign a value to the final variable `%s'",
9076          IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
9077       return 1;
9078     }
9079   return 0;
9080 }
9081
9082 /* Inline references to java.lang.PRIMTYPE.TYPE when accessed in
9083    read. This is needed to avoid circularities in the implementation
9084    of these fields in libjava. */
9085
9086 static tree
9087 maybe_build_primttype_type_ref (rhs, wfl)
9088     tree rhs, wfl;
9089 {
9090   tree to_return = NULL_TREE;
9091   tree rhs_type = TREE_TYPE (rhs);
9092   if (TREE_CODE (rhs) == COMPOUND_EXPR)
9093     {
9094       tree n = TREE_OPERAND (rhs, 1);
9095       if (TREE_CODE (n) == VAR_DECL 
9096           && DECL_NAME (n) == TYPE_identifier_node
9097           && rhs_type == class_ptr_type)
9098         {
9099           const char *self_name = IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl));
9100           if (!strncmp (self_name, "java.lang.", 10))
9101             to_return = build_primtype_type_ref (self_name);
9102         }
9103     }
9104   return (to_return ? to_return : rhs );
9105 }
9106
9107 /* 15.25 Assignment operators. */
9108
9109 static tree
9110 patch_assignment (node, wfl_op1, wfl_op2)
9111      tree node;
9112      tree wfl_op1;
9113      tree wfl_op2;
9114 {
9115   tree rhs = TREE_OPERAND (node, 1);
9116   tree lvalue = TREE_OPERAND (node, 0), llvalue;
9117   tree lhs_type = NULL_TREE, rhs_type, new_rhs = NULL_TREE;
9118   int error_found = 0;
9119   int lvalue_from_array = 0;
9120
9121   /* Can't assign to a final. */
9122   if (check_final_assignment (lvalue, wfl_op1))
9123     error_found = 1;
9124
9125   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
9126
9127   /* Lhs can be a named variable */
9128   if (JDECL_P (lvalue))
9129     {
9130       lhs_type = TREE_TYPE (lvalue);
9131     }
9132   /* Or Lhs can be a array acccess. Should that be lvalue ? FIXME +
9133      comment on reason why */
9134   else if (TREE_CODE (wfl_op1) == ARRAY_REF)
9135     {
9136       lhs_type = TREE_TYPE (lvalue);
9137       lvalue_from_array = 1;
9138     }
9139   /* Or a field access */
9140   else if (TREE_CODE (lvalue) == COMPONENT_REF)
9141     lhs_type = TREE_TYPE (lvalue);
9142   /* Or a function return slot */
9143   else if (TREE_CODE (lvalue) == RESULT_DECL)
9144     lhs_type = TREE_TYPE (lvalue);
9145   /* Otherwise, we might want to try to write into an optimized static
9146      final, this is an of a different nature, reported further on. */
9147   else if (TREE_CODE (wfl_op1) == EXPR_WITH_FILE_LOCATION
9148            && resolve_expression_name (wfl_op1, &llvalue))
9149     {
9150       if (check_final_assignment (llvalue, wfl_op1))
9151         {
9152           /* What we should do instead is resetting the all the flags
9153              previously set, exchange lvalue for llvalue and continue. */
9154           error_found = 1;
9155           return error_mark_node;
9156         }
9157       else 
9158         lhs_type = TREE_TYPE (lvalue);
9159     }
9160   else 
9161     {
9162       parse_error_context (wfl_op1, "Invalid left hand side of assignment");
9163       error_found = 1;
9164     }
9165
9166   rhs_type = TREE_TYPE (rhs);
9167   /* 5.1 Try the assignment conversion for builtin type. */
9168   new_rhs = try_builtin_assignconv (wfl_op1, lhs_type, rhs);
9169
9170   /* 5.2 If it failed, try a reference conversion */
9171   if (!new_rhs && (new_rhs = try_reference_assignconv (lhs_type, rhs)))
9172     lhs_type = promote_type (rhs_type);
9173
9174   /* 15.25.2 If we have a compound assignment, convert RHS into the
9175      type of the LHS */
9176   else if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
9177     new_rhs = convert (lhs_type, rhs);
9178
9179   /* Explicit cast required. This is an error */
9180   if (!new_rhs)
9181     {
9182       char *t1 = xstrdup (lang_printable_name (TREE_TYPE (rhs), 0));
9183       char *t2 = xstrdup (lang_printable_name (lhs_type, 0));
9184       tree wfl;
9185       char operation [32];      /* Max size known */
9186
9187       /* If the assignment is part of a declaration, we use the WFL of
9188          the declared variable to point out the error and call it a
9189          declaration problem. If the assignment is a genuine =
9190          operator, we call is a operator `=' problem, otherwise we
9191          call it an assignment problem. In both of these last cases,
9192          we use the WFL of the operator to indicate the error. */
9193
9194       if (MODIFY_EXPR_FROM_INITIALIZATION_P (node))
9195         {
9196           wfl = wfl_op1;
9197           strcpy (operation, "declaration");
9198         }
9199       else
9200         {
9201           wfl = wfl_operator;
9202           if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
9203             strcpy (operation, "assignment");
9204           else if (TREE_CODE (TREE_OPERAND (node, 0)) == RESULT_DECL)
9205             strcpy (operation, "`return'");
9206           else
9207             strcpy (operation, "`='");
9208         }
9209
9210       if (!valid_cast_to_p (rhs_type, lhs_type))
9211         parse_error_context (wfl, "Incompatible type for %s. "
9212                              "Can't convert `%s' to `%s'",
9213                              operation, t1, t2);
9214       else
9215         parse_error_context (wfl, "Incompatible type for %s. "
9216                              "Explicit cast needed to convert `%s' to `%s'",
9217                              operation, t1, t2);
9218       free (t1); free (t2);
9219       error_found = 1;
9220     }
9221
9222   /* Inline read access to java.lang.PRIMTYPE.TYPE */
9223   if (new_rhs)
9224     new_rhs = maybe_build_primttype_type_ref (new_rhs, wfl_op2);
9225
9226   if (error_found)
9227     return error_mark_node;
9228
9229   /* 10.10: Array Store Exception runtime check */
9230   if (!flag_emit_class_files
9231       && !flag_emit_xref
9232       && lvalue_from_array 
9233       && JREFERENCE_TYPE_P (TYPE_ARRAY_ELEMENT (lhs_type)))
9234     {
9235       tree check;
9236       tree base = lvalue;
9237
9238       /* We need to retrieve the right argument for _Jv_CheckArrayStore */
9239       if (TREE_CODE (lvalue) == COMPOUND_EXPR)
9240         base = TREE_OPERAND (lvalue, 0);
9241       else
9242         {
9243           if (flag_bounds_check)
9244             base = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (base, 0), 1), 0);
9245           else
9246             base = TREE_OPERAND (TREE_OPERAND (base, 0), 0);
9247         }
9248
9249       /* Build the invocation of _Jv_CheckArrayStore */
9250       new_rhs = save_expr (new_rhs);
9251       check = build (CALL_EXPR, void_type_node,
9252                      build_address_of (soft_checkarraystore_node),
9253                      tree_cons (NULL_TREE, base,
9254                                 build_tree_list (NULL_TREE, new_rhs)),
9255                      NULL_TREE);
9256       TREE_SIDE_EFFECTS (check) = 1;
9257
9258       /* We have to decide on an insertion point */
9259       if (TREE_CODE (lvalue) == COMPOUND_EXPR)
9260         {
9261           tree t;
9262           if (flag_bounds_check)
9263             {
9264               t = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (lvalue, 1), 0), 0);
9265               TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (lvalue, 1), 0), 0) =
9266                 build (COMPOUND_EXPR, void_type_node, t, check);
9267             }
9268           else
9269             TREE_OPERAND (lvalue, 1) = build (COMPOUND_EXPR, lhs_type,
9270                                               check, TREE_OPERAND (lvalue, 1));
9271         }
9272       else 
9273         {
9274           /* Make sure the bound check will happen before the store check */
9275           if (flag_bounds_check)
9276             TREE_OPERAND (TREE_OPERAND (lvalue, 0), 0) =
9277               build (COMPOUND_EXPR, void_type_node,
9278                      TREE_OPERAND (TREE_OPERAND (lvalue, 0), 0), check);
9279           else
9280             lvalue = build (COMPOUND_EXPR, lhs_type, check, lvalue);
9281         }
9282     }
9283
9284   TREE_OPERAND (node, 0) = lvalue;
9285   TREE_OPERAND (node, 1) = new_rhs;
9286   TREE_TYPE (node) = lhs_type;
9287   return node;
9288 }
9289
9290 /* Check that type SOURCE can be cast into type DEST. If the cast
9291    can't occur at all, return 0 otherwise 1. This function is used to
9292    produce accurate error messages on the reasons why an assignment
9293    failed. */
9294
9295 static tree
9296 try_reference_assignconv (lhs_type, rhs)
9297      tree lhs_type, rhs;
9298 {
9299   tree new_rhs = NULL_TREE;
9300   tree rhs_type = TREE_TYPE (rhs);
9301
9302   if (!JPRIMITIVE_TYPE_P (rhs_type) && JREFERENCE_TYPE_P (lhs_type))
9303     {
9304       /* `null' may be assigned to any reference type */
9305       if (rhs == null_pointer_node)
9306         new_rhs = null_pointer_node;
9307       /* Try the reference assignment conversion */
9308       else if (valid_ref_assignconv_cast_p (rhs_type, lhs_type, 0))
9309         new_rhs = rhs;
9310       /* This is a magic assignment that we process differently */
9311       else if (rhs == soft_exceptioninfo_call_node)
9312         new_rhs = rhs;
9313     }
9314   return new_rhs;
9315 }
9316
9317 /* Check that RHS can be converted into LHS_TYPE by the assignment
9318    conversion (5.2), for the cases of RHS being a builtin type. Return
9319    NULL_TREE if the conversion fails or if because RHS isn't of a
9320    builtin type. Return a converted RHS if the conversion is possible.  */
9321
9322 static tree
9323 try_builtin_assignconv (wfl_op1, lhs_type, rhs)
9324      tree wfl_op1, lhs_type, rhs;
9325 {
9326   tree new_rhs = NULL_TREE;
9327   tree rhs_type = TREE_TYPE (rhs);
9328
9329   /* Zero accepted everywhere */
9330   if (TREE_CODE (rhs) == INTEGER_CST 
9331       && TREE_INT_CST_HIGH (rhs) == 0 && TREE_INT_CST_LOW (rhs) == 0
9332       && JPRIMITIVE_TYPE_P (rhs_type))
9333     new_rhs = convert (lhs_type, rhs);
9334
9335   /* 5.1.1 Try Identity Conversion,
9336      5.1.2 Try Widening Primitive Conversion */
9337   else if (valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type))
9338     new_rhs = convert (lhs_type, rhs);
9339
9340   /* Try a narrowing primitive conversion (5.1.3): 
9341        - expression is a constant expression of type int AND
9342        - variable is byte, short or char AND
9343        - The value of the expression is representable in the type of the 
9344          variable */
9345   else if (rhs_type == int_type_node && TREE_CONSTANT (rhs)
9346            && (lhs_type == byte_type_node || lhs_type == char_type_node
9347                || lhs_type == short_type_node))
9348     {
9349       if (int_fits_type_p (rhs, lhs_type))
9350         new_rhs = convert (lhs_type, rhs);
9351       else if (wfl_op1)         /* Might be called with a NULL */
9352         parse_warning_context 
9353           (wfl_op1, "Constant expression `%s' to wide for narrowing "
9354            "primitive conversion to `%s'", 
9355            print_int_node (rhs), lang_printable_name (lhs_type, 0));
9356       /* Reported a warning that will turn into an error further
9357          down, so we don't return */
9358     }
9359
9360   return new_rhs;
9361 }
9362
9363 /* Return 1 if RHS_TYPE can be converted to LHS_TYPE by identity
9364    conversion (5.1.1) or widening primitve conversion (5.1.2).  Return
9365    0 is the conversion test fails.  This implements parts the method
9366    invocation convertion (5.3).  */
9367
9368 static int
9369 valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type)
9370      tree lhs_type, rhs_type;
9371 {
9372   /* 5.1.1: This is the identity conversion part. */
9373   if (lhs_type == rhs_type)
9374     return 1;
9375
9376   /* Reject non primitive types */
9377   if (!JPRIMITIVE_TYPE_P (lhs_type) || !JPRIMITIVE_TYPE_P (rhs_type))
9378     return 0;
9379
9380   /* 5.1.2: widening primitive conversion. byte, even if it's smaller
9381      than a char can't be converted into a char. Short can't too, but
9382      the < test below takes care of that */
9383   if (lhs_type == char_type_node && rhs_type == byte_type_node)
9384     return 0;
9385
9386   /* Accept all promoted type here. Note, we can't use <= in the test
9387      below, because we still need to bounce out assignments of short
9388      to char and the likes */
9389   if (lhs_type == int_type_node
9390       && (rhs_type == promoted_byte_type_node
9391           || rhs_type == promoted_short_type_node
9392           || rhs_type == promoted_char_type_node
9393           || rhs_type == promoted_boolean_type_node))
9394     return 1;
9395
9396   /* From here, an integral is widened if its precision is smaller
9397      than the precision of the LHS or if the LHS is a floating point
9398      type, or the RHS is a float and the RHS a double. */
9399   if ((JINTEGRAL_TYPE_P (rhs_type) && JINTEGRAL_TYPE_P (lhs_type) 
9400        && (TYPE_PRECISION (rhs_type) < TYPE_PRECISION (lhs_type)))
9401       || (JINTEGRAL_TYPE_P (rhs_type) && JFLOAT_TYPE_P (lhs_type))
9402       || (rhs_type == float_type_node && lhs_type == double_type_node))
9403     return 1;
9404
9405   return 0;
9406 }
9407
9408 /* Check that something of SOURCE type can be assigned or cast to
9409    something of DEST type at runtime. Return 1 if the operation is
9410    valid, 0 otherwise. If CAST is set to 1, we're treating the case
9411    were SOURCE is cast into DEST, which borrows a lot of the
9412    assignment check. */
9413
9414 static int
9415 valid_ref_assignconv_cast_p (source, dest, cast)
9416      tree source;
9417      tree dest;
9418      int cast;
9419 {
9420   /* SOURCE or DEST might be null if not from a declared entity. */
9421   if (!source || !dest)
9422     return 0;
9423   if (JNULLP_TYPE_P (source))
9424     return 1;
9425   if (TREE_CODE (source) == POINTER_TYPE)
9426     source = TREE_TYPE (source);
9427   if (TREE_CODE (dest) == POINTER_TYPE)
9428     dest = TREE_TYPE (dest);
9429   /* Case where SOURCE is a class type */
9430   if (TYPE_CLASS_P (source))
9431     {
9432       if (TYPE_CLASS_P (dest))
9433         return  source == dest || inherits_from_p (source, dest)
9434           || (cast && inherits_from_p (dest, source));
9435       if (TYPE_INTERFACE_P (dest))
9436         {
9437           /* If doing a cast and SOURCE is final, the operation is
9438              always correct a compile time (because even if SOURCE
9439              does not implement DEST, a subclass of SOURCE might). */
9440           if (cast && !CLASS_FINAL (TYPE_NAME (source)))
9441             return 1;
9442           /* Otherwise, SOURCE must implement DEST */
9443           return interface_of_p (dest, source);
9444         }
9445       /* DEST is an array, cast permited if SOURCE is of Object type */
9446       return (cast && source == object_type_node ? 1 : 0);
9447     }
9448   if (TYPE_INTERFACE_P (source))
9449     {
9450       if (TYPE_CLASS_P (dest))
9451         {
9452           /* If not casting, DEST must be the Object type */
9453           if (!cast)
9454             return dest == object_type_node;
9455           /* We're doing a cast. The cast is always valid is class
9456              DEST is not final, otherwise, DEST must implement SOURCE */
9457           else if (!CLASS_FINAL (TYPE_NAME (dest)))
9458             return 1;
9459           else
9460             return interface_of_p (source, dest);
9461         }
9462       if (TYPE_INTERFACE_P (dest))
9463         {
9464           /* If doing a cast, then if SOURCE and DEST contain method
9465              with the same signature but different return type, then
9466              this is a (compile time) error */
9467           if (cast)
9468             {
9469               tree method_source, method_dest;
9470               tree source_type;
9471               tree source_sig;
9472               tree source_name;
9473               for (method_source = TYPE_METHODS (source); method_source; 
9474                    method_source = TREE_CHAIN (method_source))
9475                 {
9476                   source_sig = 
9477                     build_java_argument_signature (TREE_TYPE (method_source));
9478                   source_type = TREE_TYPE (TREE_TYPE (method_source));
9479                   source_name = DECL_NAME (method_source);
9480                   for (method_dest = TYPE_METHODS (dest);
9481                        method_dest; method_dest = TREE_CHAIN (method_dest))
9482                     if (source_sig == 
9483                         build_java_argument_signature (TREE_TYPE (method_dest))
9484                         && source_name == DECL_NAME (method_dest)
9485                         && source_type != TREE_TYPE (TREE_TYPE (method_dest)))
9486                       return 0;
9487                 }
9488               return 1;
9489             }
9490           else
9491             return source == dest || interface_of_p (dest, source);
9492         }
9493       else                      /* Array */
9494         return (cast ? 
9495                 (DECL_NAME (TYPE_NAME (source)) == java_lang_cloneable) : 0);
9496     }
9497   if (TYPE_ARRAY_P (source))
9498     {
9499       if (TYPE_CLASS_P (dest))
9500         return dest == object_type_node;
9501       /* Can't cast an array to an interface unless the interface is
9502          java.lang.Cloneable */
9503       if (TYPE_INTERFACE_P (dest))
9504         return (DECL_NAME (TYPE_NAME (dest)) == java_lang_cloneable ? 1 : 0);
9505       else                      /* Arrays */
9506         {
9507           tree source_element_type = TYPE_ARRAY_ELEMENT (source);
9508           tree dest_element_type = TYPE_ARRAY_ELEMENT (dest);
9509           
9510           /* In case of severe errors, they turn out null */
9511           if (!dest_element_type || !source_element_type)
9512             return 0;
9513           if (source_element_type == dest_element_type)
9514             return 1;
9515           return valid_ref_assignconv_cast_p (source_element_type,
9516                                               dest_element_type, cast);
9517         }
9518       return 0;
9519     }
9520   return 0;
9521 }
9522
9523 static int
9524 valid_cast_to_p (source, dest)
9525      tree source;
9526      tree dest;
9527 {
9528   if (TREE_CODE (source) == POINTER_TYPE)
9529     source = TREE_TYPE (source);
9530   if (TREE_CODE (dest) == POINTER_TYPE)
9531     dest = TREE_TYPE (dest);
9532
9533   if (TREE_CODE (source) == RECORD_TYPE && TREE_CODE (dest) == RECORD_TYPE)
9534     return valid_ref_assignconv_cast_p (source, dest, 1);
9535
9536   else if (JNUMERIC_TYPE_P (source) && JNUMERIC_TYPE_P (dest))
9537     return 1;
9538
9539   return 0;
9540 }
9541
9542 /* Method invocation conversion test. Return 1 if type SOURCE can be
9543    converted to type DEST through the methond invocation conversion
9544    process (5.3) */
9545
9546 static tree
9547 do_unary_numeric_promotion (arg)
9548      tree arg;
9549 {
9550   tree type = TREE_TYPE (arg);
9551   if (TREE_CODE (type) == INTEGER_TYPE ? TYPE_PRECISION (type) < 32
9552       : TREE_CODE (type) == CHAR_TYPE)
9553     arg = convert (int_type_node, arg);
9554   return arg;
9555 }
9556
9557 /* Return a non zero value if SOURCE can be converted into DEST using
9558    the method invocation conversion rule (5.3).  */
9559 static int
9560 valid_method_invocation_conversion_p (dest, source)
9561      tree dest, source;
9562 {
9563   return ((JPRIMITIVE_TYPE_P (source) && JPRIMITIVE_TYPE_P (dest)
9564            && valid_builtin_assignconv_identity_widening_p (dest, source))
9565           || ((JREFERENCE_TYPE_P (source) || JNULLP_TYPE_P (source))
9566               && (JREFERENCE_TYPE_P (dest) || JNULLP_TYPE_P (dest))
9567               && valid_ref_assignconv_cast_p (source, dest, 0)));
9568 }
9569
9570 /* Build an incomplete binop expression. */
9571
9572 static tree
9573 build_binop (op, op_location, op1, op2)
9574      enum tree_code op;
9575      int op_location;
9576      tree op1, op2;
9577 {
9578   tree binop = build (op, NULL_TREE, op1, op2);
9579   TREE_SIDE_EFFECTS (binop) = 1;
9580   /* Store the location of the operator, for better error report. The
9581      string of the operator will be rebuild based on the OP value. */
9582   EXPR_WFL_LINECOL (binop) = op_location;
9583   return binop;
9584 }
9585
9586 /* Build the string of the operator retained by NODE. If NODE is part
9587    of a compound expression, add an '=' at the end of the string. This
9588    function is called when an error needs to be reported on an
9589    operator. The string is returned as a pointer to a static character
9590    buffer. */
9591
9592 static char *
9593 operator_string (node)
9594      tree node;
9595 {
9596 #define BUILD_OPERATOR_STRING(S)                                        \
9597   {                                                                     \
9598     sprintf (buffer, "%s%s", S, (COMPOUND_ASSIGN_P (node) ? "=" : "")); \
9599     return buffer;                                                      \
9600   }
9601   
9602   static char buffer [10];
9603   switch (TREE_CODE (node))
9604     {
9605     case MULT_EXPR: BUILD_OPERATOR_STRING ("*");
9606     case RDIV_EXPR: BUILD_OPERATOR_STRING ("/");
9607     case TRUNC_MOD_EXPR: BUILD_OPERATOR_STRING ("%");
9608     case PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
9609     case MINUS_EXPR: BUILD_OPERATOR_STRING ("-");
9610     case LSHIFT_EXPR: BUILD_OPERATOR_STRING ("<<");
9611     case RSHIFT_EXPR: BUILD_OPERATOR_STRING (">>");
9612     case URSHIFT_EXPR: BUILD_OPERATOR_STRING (">>>");
9613     case BIT_AND_EXPR: BUILD_OPERATOR_STRING ("&");
9614     case BIT_XOR_EXPR: BUILD_OPERATOR_STRING ("^");
9615     case BIT_IOR_EXPR: BUILD_OPERATOR_STRING ("|");
9616     case TRUTH_ANDIF_EXPR: BUILD_OPERATOR_STRING ("&&");
9617     case TRUTH_ORIF_EXPR: BUILD_OPERATOR_STRING ("||");
9618     case EQ_EXPR: BUILD_OPERATOR_STRING ("==");
9619     case NE_EXPR: BUILD_OPERATOR_STRING ("!=");
9620     case GT_EXPR: BUILD_OPERATOR_STRING (">");
9621     case GE_EXPR: BUILD_OPERATOR_STRING (">=");
9622     case LT_EXPR: BUILD_OPERATOR_STRING ("<");
9623     case LE_EXPR: BUILD_OPERATOR_STRING ("<=");
9624     case UNARY_PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
9625     case NEGATE_EXPR: BUILD_OPERATOR_STRING ("-");
9626     case TRUTH_NOT_EXPR: BUILD_OPERATOR_STRING ("!");
9627     case BIT_NOT_EXPR: BUILD_OPERATOR_STRING ("~");
9628     case PREINCREMENT_EXPR:     /* Fall through */
9629     case POSTINCREMENT_EXPR: BUILD_OPERATOR_STRING ("++");
9630     case PREDECREMENT_EXPR:     /* Fall through */
9631     case POSTDECREMENT_EXPR: BUILD_OPERATOR_STRING ("--");
9632     default:
9633       fatal ("unregistered operator %s - operator_string",
9634              tree_code_name [TREE_CODE (node)]);
9635     }
9636   return NULL;
9637 #undef BUILD_OPERATOR_STRING
9638 }
9639
9640 /* Return 1 if VAR_ACCESS1 is equivalent to VAR_ACCESS2.  */
9641
9642 static int
9643 java_decl_equiv (var_acc1, var_acc2)
9644      tree var_acc1, var_acc2;
9645 {
9646   if (JDECL_P (var_acc1))
9647     return (var_acc1 == var_acc2);
9648   
9649   return (TREE_CODE (var_acc1) == COMPONENT_REF
9650           && TREE_CODE (var_acc2) == COMPONENT_REF
9651           && TREE_OPERAND (TREE_OPERAND (var_acc1, 0), 0)
9652              == TREE_OPERAND (TREE_OPERAND (var_acc2, 0), 0)
9653           && TREE_OPERAND (var_acc1, 1) == TREE_OPERAND (var_acc2, 1));
9654 }
9655
9656 /* Return a non zero value if CODE is one of the operators that can be
9657    used in conjunction with the `=' operator in a compound assignment.  */
9658
9659 static int
9660 binop_compound_p (code)
9661     enum tree_code code;
9662 {
9663   int i;
9664   for (i = 0; i < BINOP_COMPOUND_CANDIDATES; i++)
9665     if (binop_lookup [i] == code)
9666       break;
9667
9668   return i < BINOP_COMPOUND_CANDIDATES;
9669 }
9670
9671 /* Reorganize after a fold to get SAVE_EXPR to generate what we want.  */
9672
9673 static tree
9674 java_refold (t)
9675      tree t;
9676 {
9677   tree c, b, ns, decl;
9678
9679   if (TREE_CODE (t) != MODIFY_EXPR)
9680     return t;
9681
9682   c = TREE_OPERAND (t, 1);
9683   if (! (c && TREE_CODE (c) == COMPOUND_EXPR
9684          && TREE_CODE (TREE_OPERAND (c, 0)) == MODIFY_EXPR
9685          && binop_compound_p (TREE_CODE (TREE_OPERAND (c, 1)))))
9686     return t;
9687
9688   /* Now the left branch of the binary operator. */
9689   b = TREE_OPERAND (TREE_OPERAND (c, 1), 0);
9690   if (! (b && TREE_CODE (b) == NOP_EXPR 
9691          && TREE_CODE (TREE_OPERAND (b, 0)) == SAVE_EXPR))
9692     return t;
9693
9694   ns = TREE_OPERAND (TREE_OPERAND (b, 0), 0);
9695   if (! (ns && TREE_CODE (ns) == NOP_EXPR
9696          && TREE_CODE (TREE_OPERAND (ns, 0)) == SAVE_EXPR))
9697     return t;
9698
9699   decl = TREE_OPERAND (TREE_OPERAND (ns, 0), 0);
9700   if ((JDECL_P (decl) || TREE_CODE (decl) == COMPONENT_REF)
9701       /* It's got to be the an equivalent decl */
9702       && java_decl_equiv (decl, TREE_OPERAND (TREE_OPERAND (c, 0), 0)))
9703     {
9704       /* Shorten the NOP_EXPR/SAVE_EXPR path. */
9705       TREE_OPERAND (TREE_OPERAND (c, 1), 0) = TREE_OPERAND (ns, 0);
9706       /* Substitute the COMPOUND_EXPR by the BINOP_EXPR */
9707       TREE_OPERAND (t, 1) = TREE_OPERAND (c, 1);
9708       /* Change the right part of the BINOP_EXPR */
9709       TREE_OPERAND (TREE_OPERAND (t, 1), 1) = TREE_OPERAND (c, 0);
9710     }
9711
9712   return t;
9713 }
9714
9715 /* Binary operators (15.16 up to 15.18). We return error_mark_node on
9716    errors but we modify NODE so that it contains the type computed
9717    according to the expression, when it's fixed. Otherwise, we write
9718    error_mark_node as the type. It allows us to further the analysis
9719    of remaining nodes and detects more errors in certain cases.  */
9720
9721 static tree
9722 patch_binop (node, wfl_op1, wfl_op2)
9723      tree node;
9724      tree wfl_op1;
9725      tree wfl_op2;
9726 {
9727   tree op1 = TREE_OPERAND (node, 0);
9728   tree op2 = TREE_OPERAND (node, 1);
9729   tree op1_type = TREE_TYPE (op1);
9730   tree op2_type = TREE_TYPE (op2);
9731   tree prom_type = NULL_TREE;
9732   int code = TREE_CODE (node);
9733
9734   /* If 1, tell the routine that we have to return error_mark_node
9735      after checking for the initialization of the RHS */
9736   int error_found = 0;
9737
9738   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
9739
9740   switch (code)
9741     {
9742     /* 15.16 Multiplicative operators */
9743     case MULT_EXPR:             /* 15.16.1 Multiplication Operator * */
9744     case RDIV_EXPR:             /* 15.16.2 Division Operator / */
9745     case TRUNC_MOD_EXPR:        /* 15.16.3 Remainder operator % */
9746       if (!JPRIMITIVE_TYPE_P (op1_type) || !JPRIMITIVE_TYPE_P (op2_type))
9747         {
9748           if (!JPRIMITIVE_TYPE_P (op1_type))
9749             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
9750           if (!JPRIMITIVE_TYPE_P (op2_type) && (op1_type != op2_type))
9751             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
9752           TREE_TYPE (node) = error_mark_node;
9753           error_found = 1;
9754           break;
9755         }
9756       prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
9757       /* Change the division operator if necessary */
9758       if (code == RDIV_EXPR && TREE_CODE (prom_type) == INTEGER_TYPE)
9759         TREE_SET_CODE (node, TRUNC_DIV_EXPR);
9760
9761       if (TREE_CODE (prom_type) == INTEGER_TYPE
9762           && flag_use_divide_subroutine
9763           && ! flag_emit_class_files
9764           && (code == RDIV_EXPR || code == TRUNC_MOD_EXPR))
9765         return build_java_soft_divmod (TREE_CODE (node), prom_type, op1, op2);
9766  
9767       /* This one is more complicated. FLOATs are processed by a
9768          function call to soft_fmod. Duplicate the value of the
9769          COMPOUND_ASSIGN_P flag. */
9770       if (code == TRUNC_MOD_EXPR)
9771         {
9772           tree mod = build_java_binop (TRUNC_MOD_EXPR, prom_type, op1, op2);
9773           COMPOUND_ASSIGN_P (mod) = COMPOUND_ASSIGN_P (node);
9774           TREE_SIDE_EFFECTS (mod)
9775             = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
9776           return mod;
9777         }
9778       break;
9779
9780     /* 15.17 Additive Operators */
9781     case PLUS_EXPR:             /* 15.17.1 String Concatenation Operator + */
9782
9783       /* Operation is valid if either one argument is a string
9784          constant, a String object or a StringBuffer crafted for the
9785          purpose of the a previous usage of the String concatenation
9786          operator */
9787
9788       if (TREE_CODE (op1) == STRING_CST 
9789           || TREE_CODE (op2) == STRING_CST
9790           || JSTRING_TYPE_P (op1_type)
9791           || JSTRING_TYPE_P (op2_type)
9792           || IS_CRAFTED_STRING_BUFFER_P (op1)
9793           || IS_CRAFTED_STRING_BUFFER_P (op2))
9794         return build_string_concatenation (op1, op2);
9795
9796     case MINUS_EXPR:            /* 15.17.2 Additive Operators (+ and -) for
9797                                    Numeric Types */
9798       if (!JPRIMITIVE_TYPE_P (op1_type) || !JPRIMITIVE_TYPE_P (op2_type))
9799         {
9800           if (!JPRIMITIVE_TYPE_P (op1_type))
9801             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
9802           if (!JPRIMITIVE_TYPE_P (op2_type) && (op1_type != op2_type))
9803             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
9804           TREE_TYPE (node) = error_mark_node;
9805           error_found = 1;
9806           break;
9807         }
9808       prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
9809       break;
9810
9811     /* 15.18 Shift Operators */
9812     case LSHIFT_EXPR:
9813     case RSHIFT_EXPR:
9814     case URSHIFT_EXPR:
9815       if (!JINTEGRAL_TYPE_P (op1_type) || !JINTEGRAL_TYPE_P (op2_type))
9816         {
9817           if (!JINTEGRAL_TYPE_P (op1_type))
9818             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
9819           else
9820             {
9821               if (JPRIMITIVE_TYPE_P (op2_type))
9822                 parse_error_context (wfl_operator,
9823                                      "Incompatible type for `%s'. "
9824                                      "Explicit cast needed to convert "
9825                                      "shift distance from `%s' to integral",
9826                                      operator_string (node),
9827                                      lang_printable_name (op2_type, 0));
9828               else
9829                 parse_error_context (wfl_operator, "Incompatible type for `%s'."
9830                                      " Can't convert shift distance from "
9831                                      "`%s' to integral", 
9832                                      operator_string (node),
9833                                      lang_printable_name (op2_type, 0));
9834             }
9835           TREE_TYPE (node) = error_mark_node;
9836           error_found = 1;
9837           break;
9838         }
9839
9840       /* Unary numeric promotion (5.6.1) is performed on each operand
9841          separatly */
9842       op1 = do_unary_numeric_promotion (op1);
9843       op2 = do_unary_numeric_promotion (op2);
9844
9845       /* The type of the shift expression is the type of the promoted
9846          type of the left-hand operand */
9847       prom_type = TREE_TYPE (op1);
9848
9849       /* Shift int only up to 0x1f and long up to 0x3f */
9850       if (prom_type == int_type_node)
9851         op2 = fold (build (BIT_AND_EXPR, int_type_node, op2, 
9852                            build_int_2 (0x1f, 0)));
9853       else
9854         op2 = fold (build (BIT_AND_EXPR, int_type_node, op2, 
9855                            build_int_2 (0x3f, 0)));
9856
9857       /* The >>> operator is a >> operating on unsigned quantities */
9858       if (code == URSHIFT_EXPR && ! flag_emit_class_files)
9859         {
9860           tree to_return;
9861           tree utype = unsigned_type (prom_type);
9862           op1 = convert (utype, op1);
9863           TREE_SET_CODE (node, RSHIFT_EXPR);
9864           TREE_OPERAND (node, 0) = op1;
9865           TREE_OPERAND (node, 1) = op2;
9866           TREE_TYPE (node) = utype;
9867           to_return = convert (prom_type, node);
9868           /* Copy the original value of the COMPOUND_ASSIGN_P flag */
9869           COMPOUND_ASSIGN_P (to_return) = COMPOUND_ASSIGN_P (node);
9870           TREE_SIDE_EFFECTS (to_return)
9871             = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
9872           return to_return;
9873         }
9874       break;
9875
9876       /* 15.19.1 Type Comparison Operator instaceof */
9877     case INSTANCEOF_EXPR:
9878
9879       TREE_TYPE (node) = boolean_type_node;
9880
9881       if (!(op2_type = resolve_type_during_patch (op2)))
9882         return error_mark_node;
9883
9884       /* The first operand must be a reference type or the null type */
9885       if (!JREFERENCE_TYPE_P (op1_type) && op1 != null_pointer_node)
9886         error_found = 1;        /* Error reported further below */
9887
9888       /* The second operand must be a reference type */
9889       if (!JREFERENCE_TYPE_P (op2_type))
9890         {
9891           SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
9892           parse_error_context
9893             (wfl_operator, "Invalid argument `%s' for `instanceof'",
9894              lang_printable_name (op2_type, 0));
9895           error_found = 1;
9896         }
9897
9898       if (!error_found && valid_ref_assignconv_cast_p (op1_type, op2_type, 1))
9899         {
9900           /* If the first operand is null, the result is always false */
9901           if (op1 == null_pointer_node)
9902             return boolean_false_node;
9903           else if (flag_emit_class_files)
9904             {
9905               TREE_OPERAND (node, 1) = op2_type;
9906               TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1);
9907               return node;
9908             }
9909           /* Otherwise we have to invoke instance of to figure it out */
9910           else
9911             {
9912               tree call =
9913                 build (CALL_EXPR, boolean_type_node,
9914                        build_address_of (soft_instanceof_node),
9915                        tree_cons 
9916                        (NULL_TREE, op1,
9917                         build_tree_list (NULL_TREE,
9918                                          build_class_ref (op2_type))),
9919                        NULL_TREE);
9920               TREE_SIDE_EFFECTS (call) = TREE_SIDE_EFFECTS (op1);
9921               return call;
9922             }
9923         }
9924       /* There is no way the expression operand can be an instance of
9925          the type operand. This is a compile time error. */
9926       else
9927         {
9928           char *t1 = xstrdup (lang_printable_name (op1_type, 0));
9929           SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
9930           parse_error_context 
9931             (wfl_operator, "Impossible for `%s' to be instance of `%s'",
9932              t1, lang_printable_name (op2_type, 0));
9933           free (t1);
9934           error_found = 1;
9935         }
9936       
9937       break;
9938
9939       /* 15.21 Bitwise and Logical Operators */
9940     case BIT_AND_EXPR:
9941     case BIT_XOR_EXPR:
9942     case BIT_IOR_EXPR:
9943       if (JINTEGRAL_TYPE_P (op1_type) && JINTEGRAL_TYPE_P (op2_type))
9944         /* Binary numeric promotion is performed on both operand and the
9945            expression retain that type */
9946         prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
9947
9948       else if (TREE_CODE (op1_type) == BOOLEAN_TYPE 
9949                && TREE_CODE (op1_type) == BOOLEAN_TYPE)
9950         /* The type of the bitwise operator expression is BOOLEAN */
9951         prom_type = boolean_type_node;
9952       else
9953         {
9954           if (!JINTEGRAL_TYPE_P (op1_type))
9955             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
9956           if (!JINTEGRAL_TYPE_P (op2_type) && (op1_type != op2_type))
9957             ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op2_type);
9958           TREE_TYPE (node) = error_mark_node;
9959           error_found = 1;
9960           /* Insert a break here if adding thing before the switch's
9961              break for this case */
9962         }
9963       break;
9964
9965       /* 15.22 Conditional-And Operator */
9966     case TRUTH_ANDIF_EXPR:
9967       /* 15.23 Conditional-Or Operator */
9968     case TRUTH_ORIF_EXPR:
9969       /* Operands must be of BOOLEAN type */
9970       if (TREE_CODE (op1_type) != BOOLEAN_TYPE || 
9971           TREE_CODE (op2_type) != BOOLEAN_TYPE)
9972         {
9973           if (TREE_CODE (op1_type) != BOOLEAN_TYPE)
9974             ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op1_type);
9975           if (TREE_CODE (op2_type) != BOOLEAN_TYPE && (op1_type != op2_type))
9976             ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op2_type);
9977           TREE_TYPE (node) = boolean_type_node;
9978           error_found = 1;
9979           break;
9980         }
9981       /* The type of the conditional operators is BOOLEAN */
9982       prom_type = boolean_type_node;
9983       break;
9984
9985       /* 15.19.1 Numerical Comparison Operators <, <=, >, >= */
9986     case LT_EXPR:
9987     case GT_EXPR:
9988     case LE_EXPR:
9989     case GE_EXPR:
9990       /* The type of each of the operands must be a primitive numeric
9991          type */
9992       if (!JNUMERIC_TYPE_P (op1_type) || ! JNUMERIC_TYPE_P (op2_type))
9993         {
9994           if (!JNUMERIC_TYPE_P (op1_type))
9995             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
9996           if (!JNUMERIC_TYPE_P (op2_type) && (op1_type != op2_type))
9997             ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
9998           TREE_TYPE (node) = boolean_type_node;
9999           error_found = 1;
10000           break;
10001         }
10002       /* Binary numeric promotion is performed on the operands */
10003       binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
10004       /* The type of the relation expression is always BOOLEAN */
10005       prom_type = boolean_type_node;
10006       break;
10007
10008       /* 15.20 Equality Operator */
10009     case EQ_EXPR:
10010     case NE_EXPR:
10011       /* 15.20.1 Numerical Equality Operators == and != */
10012       /* Binary numeric promotion is performed on the operands */
10013       if (JNUMERIC_TYPE_P (op1_type) && JNUMERIC_TYPE_P (op2_type))
10014         binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
10015       
10016       /* 15.20.2 Boolean Equality Operators == and != */
10017       else if (TREE_CODE (op1_type) == BOOLEAN_TYPE &&
10018           TREE_CODE (op2_type) == BOOLEAN_TYPE)
10019         ;                       /* Nothing to do here */
10020       
10021       /* 15.20.3 Reference Equality Operators == and != */
10022       /* Types have to be either references or the null type. If
10023          they're references, it must be possible to convert either
10024          type to the other by casting conversion. */
10025       else if (op1 == null_pointer_node || op2 == null_pointer_node 
10026                || (JREFERENCE_TYPE_P (op1_type) && JREFERENCE_TYPE_P (op2_type)
10027                    && (valid_ref_assignconv_cast_p (op1_type, op2_type, 1)
10028                        || valid_ref_assignconv_cast_p (op2_type, 
10029                                                        op1_type, 1))))
10030         ;                       /* Nothing to do here */
10031           
10032       /* Else we have an error figure what can't be converted into
10033          what and report the error */
10034       else
10035         {
10036           char *t1;
10037           t1 = xstrdup (lang_printable_name (op1_type, 0));
10038           parse_error_context 
10039             (wfl_operator, "Incompatible type for `%s'. Can't convert `%s' "
10040              "to `%s'", operator_string (node), t1, 
10041              lang_printable_name (op2_type, 0));
10042           free (t1);
10043           TREE_TYPE (node) = boolean_type_node;
10044           error_found = 1;
10045           break;
10046         }
10047       prom_type = boolean_type_node;
10048       break;
10049     }
10050
10051   if (error_found)
10052     return error_mark_node;
10053
10054   TREE_OPERAND (node, 0) = op1;
10055   TREE_OPERAND (node, 1) = op2;
10056   TREE_TYPE (node) = prom_type;
10057   TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
10058   
10059   if (flag_emit_xref)
10060     return node;
10061
10062   /* fold does not respect side-effect order as required for Java but not C.
10063    * Also, it sometimes create SAVE_EXPRs which are bad when emitting
10064    * bytecode.
10065    */
10066   if (flag_emit_class_files ? (TREE_CONSTANT (op1) && TREE_CONSTANT (op2))
10067       : ! TREE_SIDE_EFFECTS (node))
10068     node = fold (node);
10069   return node;
10070 }
10071
10072 /* Concatenate the STRING_CST CSTE and STRING. When AFTER is a non
10073    zero value, the value of CSTE comes after the valude of STRING */
10074
10075 static tree
10076 do_merge_string_cste (cste, string, string_len, after)
10077      tree cste;
10078      const char *string;
10079      int string_len, after;
10080 {
10081   int len = TREE_STRING_LENGTH (cste) + string_len;
10082   const char *old = TREE_STRING_POINTER (cste);
10083   TREE_STRING_LENGTH (cste) = len;
10084   TREE_STRING_POINTER (cste) = obstack_alloc (expression_obstack, len+1);
10085   if (after)
10086     {
10087       strcpy (TREE_STRING_POINTER (cste), string);
10088       strcat (TREE_STRING_POINTER (cste), old);
10089     }
10090   else
10091     {
10092       strcpy (TREE_STRING_POINTER (cste), old);
10093       strcat (TREE_STRING_POINTER (cste), string);
10094     }
10095   return cste;
10096 }
10097
10098 /* Tries to merge OP1 (a STRING_CST) and OP2 (if suitable). Return a
10099    new STRING_CST on success, NULL_TREE on failure */
10100
10101 static tree
10102 merge_string_cste (op1, op2, after)
10103      tree op1, op2;
10104      int after;
10105 {
10106   /* Handle two string constants right away */
10107   if (TREE_CODE (op2) == STRING_CST)
10108     return do_merge_string_cste (op1, TREE_STRING_POINTER (op2), 
10109                                  TREE_STRING_LENGTH (op2), after);
10110   
10111   /* Reasonable integer constant can be treated right away */
10112   if (TREE_CODE (op2) == INTEGER_CST && !TREE_CONSTANT_OVERFLOW (op2))
10113     {
10114       static const char *boolean_true = "true";
10115       static const char *boolean_false = "false";
10116       static const char *null_pointer = "null";
10117       char ch[3];
10118       const char *string;
10119       
10120       if (op2 == boolean_true_node)
10121         string = boolean_true;
10122       else if (op2 == boolean_false_node)
10123         string = boolean_false;
10124       else if (op2 == null_pointer_node)
10125         string = null_pointer;
10126       else if (TREE_TYPE (op2) == char_type_node)
10127         {
10128           ch[0] = (char )TREE_INT_CST_LOW (op2);
10129           ch[1] = '\0';
10130           string = ch;
10131         }
10132       else
10133           string = print_int_node (op2);
10134       
10135       return do_merge_string_cste (op1, string, strlen (string), after);
10136     }
10137   return NULL_TREE;
10138 }
10139
10140 /* Tries to statically concatenate OP1 and OP2 if possible. Either one
10141    has to be a STRING_CST and the other part must be a STRING_CST or a
10142    INTEGRAL constant. Return a new STRING_CST if the operation
10143    succeed, NULL_TREE otherwise.
10144
10145    If the case we want to optimize for space, we might want to return
10146    NULL_TREE for each invocation of this routine. FIXME */
10147
10148 static tree
10149 string_constant_concatenation (op1, op2)
10150      tree op1, op2;
10151 {
10152   if (TREE_CODE (op1) == STRING_CST || (TREE_CODE (op2) == STRING_CST))
10153     {
10154       tree string, rest;
10155       int invert;
10156       
10157       string = (TREE_CODE (op1) == STRING_CST ? op1 : op2);
10158       rest   = (string == op1 ? op2 : op1);
10159       invert = (string == op1 ? 0 : 1 );
10160       
10161       /* Walk REST, only if it looks reasonable */
10162       if (TREE_CODE (rest) != STRING_CST
10163           && !IS_CRAFTED_STRING_BUFFER_P (rest)
10164           && !JSTRING_TYPE_P (TREE_TYPE (rest))
10165           && TREE_CODE (rest) == EXPR_WITH_FILE_LOCATION)
10166         {
10167           rest = java_complete_tree (rest);
10168           if (rest == error_mark_node)
10169             return error_mark_node;
10170           rest = fold (rest);
10171         }
10172       return merge_string_cste (string, rest, invert);
10173     }
10174   return NULL_TREE;
10175 }
10176
10177 /* Implement the `+' operator. Does static optimization if possible,
10178    otherwise create (if necessary) and append elements to a
10179    StringBuffer. The StringBuffer will be carried around until it is
10180    used for a function call or an assignment. Then toString() will be
10181    called on it to turn it into a String object. */
10182
10183 static tree
10184 build_string_concatenation (op1, op2)
10185      tree op1, op2;
10186 {
10187   tree result;
10188   int side_effects = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
10189
10190   if (flag_emit_xref)
10191     return build (PLUS_EXPR, string_type_node, op1, op2);
10192   
10193   /* Try to do some static optimization */
10194   if ((result = string_constant_concatenation (op1, op2)))
10195     return result;
10196
10197   /* Discard empty strings on either side of the expression */
10198   if (TREE_CODE (op1) == STRING_CST && TREE_STRING_LENGTH (op1) == 0)
10199     {
10200       op1 = op2;
10201       op2 = NULL_TREE;
10202     }
10203   else if (TREE_CODE (op2) == STRING_CST && TREE_STRING_LENGTH (op2) == 0)
10204     op2 = NULL_TREE;
10205
10206   /* If operands are string constant, turn then into object references */
10207   if (TREE_CODE (op1) == STRING_CST)
10208     op1 = patch_string_cst (op1);
10209   if (op2 && TREE_CODE (op2) == STRING_CST)
10210     op2 = patch_string_cst (op2);
10211
10212   /* If either one of the constant is null and the other non null
10213      operand is a String object, return it. */
10214   if (JSTRING_TYPE_P (TREE_TYPE (op1)) && !op2)
10215     return op1;
10216
10217   /* If OP1 isn't already a StringBuffer, create and
10218      initialize a new one */
10219   if (!IS_CRAFTED_STRING_BUFFER_P (op1))
10220     {
10221       /* Two solutions here: 
10222          1) OP1 is a string reference, we call new StringBuffer(OP1)
10223          2) OP1 is something else, we call new StringBuffer().append(OP1). */
10224       if (JSTRING_TYPE_P (TREE_TYPE (op1)))
10225         op1 = BUILD_STRING_BUFFER (op1);
10226       else
10227         {
10228           tree aNew = BUILD_STRING_BUFFER (NULL_TREE);
10229           op1 = make_qualified_primary (aNew, BUILD_APPEND (op1), 0);
10230         }
10231     }
10232
10233   if (op2)
10234     {
10235       /* OP1 is no longer the last node holding a crafted StringBuffer */
10236       IS_CRAFTED_STRING_BUFFER_P (op1) = 0;
10237       /* Create a node for `{new...,xxx}.append (op2)' */
10238       if (op2)
10239         op1 = make_qualified_primary (op1, BUILD_APPEND (op2), 0);
10240     }
10241
10242   /* Mark the last node holding a crafted StringBuffer */
10243   IS_CRAFTED_STRING_BUFFER_P (op1) = 1;
10244
10245   TREE_SIDE_EFFECTS (op1) = side_effects;
10246   return op1;
10247 }
10248
10249 /* Patch the string node NODE. NODE can be a STRING_CST of a crafted
10250    StringBuffer. If no string were found to be patched, return
10251    NULL. */
10252
10253 static tree
10254 patch_string (node)
10255     tree node;
10256 {
10257   if (node == error_mark_node)
10258     return error_mark_node;
10259   if (TREE_CODE (node) == STRING_CST)
10260     return patch_string_cst (node);
10261   else if (IS_CRAFTED_STRING_BUFFER_P (node))
10262     {
10263       int saved = ctxp->explicit_constructor_p;
10264       tree invoke = build_method_invocation (wfl_to_string, NULL_TREE);
10265       tree ret;
10266       /* Temporary disable forbid the use of `this'. */
10267       ctxp->explicit_constructor_p = 0;
10268       ret = java_complete_tree (make_qualified_primary (node, invoke, 0));
10269       /* Restore it at its previous value */
10270       ctxp->explicit_constructor_p = saved;
10271       return ret;
10272     }
10273   return NULL_TREE;
10274 }
10275
10276 /* Build the internal representation of a string constant.  */
10277
10278 static tree
10279 patch_string_cst (node)
10280      tree node;
10281 {
10282   int location;
10283   if (! flag_emit_class_files)
10284     {
10285       push_obstacks (&permanent_obstack, &permanent_obstack);
10286       node = get_identifier (TREE_STRING_POINTER (node));
10287       location = alloc_name_constant (CONSTANT_String, node);
10288       node = build_ref_from_constant_pool (location);
10289       pop_obstacks ();
10290     }
10291   TREE_TYPE (node) = string_ptr_type_node;
10292   TREE_CONSTANT (node) = 1;
10293   return node;
10294 }
10295
10296 /* Build an incomplete unary operator expression. */
10297
10298 static tree
10299 build_unaryop (op_token, op_location, op1)
10300      int op_token, op_location;
10301      tree op1;
10302 {
10303   enum tree_code op;
10304   tree unaryop;
10305   switch (op_token)
10306     {
10307     case PLUS_TK: op = UNARY_PLUS_EXPR; break;
10308     case MINUS_TK: op = NEGATE_EXPR; break;
10309     case NEG_TK: op = TRUTH_NOT_EXPR; break;
10310     case NOT_TK: op = BIT_NOT_EXPR; break;
10311     default: fatal ("Unknown token `%d' for unary operator - build_unaryop",
10312                     op_token);
10313     }
10314
10315   unaryop = build1 (op, NULL_TREE, op1);
10316   TREE_SIDE_EFFECTS (unaryop) = 1;
10317   /* Store the location of the operator, for better error report. The
10318      string of the operator will be rebuild based on the OP value. */
10319   EXPR_WFL_LINECOL (unaryop) = op_location;
10320   return unaryop;
10321 }
10322
10323 /* Special case for the ++/-- operators, since they require an extra
10324    argument to build, which is set to NULL and patched
10325    later. IS_POST_P is 1 if the operator, 0 otherwise.  */
10326
10327 static tree
10328 build_incdec (op_token, op_location, op1, is_post_p)
10329      int op_token, op_location;
10330      tree op1;
10331      int is_post_p;
10332 {
10333   static enum tree_code lookup [2][2] = 
10334     {
10335       { PREDECREMENT_EXPR, PREINCREMENT_EXPR, },
10336       { POSTDECREMENT_EXPR, POSTINCREMENT_EXPR, },
10337     };
10338   tree node = build (lookup [is_post_p][(op_token - DECR_TK)], 
10339                      NULL_TREE, op1, NULL_TREE);
10340   TREE_SIDE_EFFECTS (node) = 1;
10341   /* Store the location of the operator, for better error report. The
10342      string of the operator will be rebuild based on the OP value. */
10343   EXPR_WFL_LINECOL (node) = op_location;
10344   return node;
10345 }     
10346
10347 /* Build an incomplete cast operator, based on the use of the
10348    CONVERT_EXPR. Note that TREE_TYPE of the constructed node is
10349    set. java_complete_tree is trained to walk a CONVERT_EXPR even
10350    though its type is already set.  */
10351
10352 static tree
10353 build_cast (location, type, exp)
10354      int location;
10355      tree type, exp;
10356 {
10357   tree node = build1 (CONVERT_EXPR, type, exp);
10358   EXPR_WFL_LINECOL (node) = location;
10359   return node;
10360 }
10361
10362 /* 15.14 Unary operators. We return error_mark_node in case of error,
10363    but preserve the type of NODE if the type is fixed.  */
10364
10365 static tree
10366 patch_unaryop (node, wfl_op)
10367      tree node;
10368      tree wfl_op;
10369 {
10370   tree op = TREE_OPERAND (node, 0);
10371   tree op_type = TREE_TYPE (op);
10372   tree prom_type = NULL_TREE, value, decl;
10373   int code = TREE_CODE (node);
10374   int error_found = 0;
10375
10376   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10377
10378   switch (code)
10379     {
10380       /* 15.13.2 Postfix Increment Operator ++ */
10381     case POSTINCREMENT_EXPR:
10382       /* 15.13.3 Postfix Increment Operator -- */
10383     case POSTDECREMENT_EXPR:
10384       /* 15.14.1 Prefix Increment Operator ++ */
10385     case PREINCREMENT_EXPR:
10386       /* 15.14.2 Prefix Decrement Operator -- */
10387     case PREDECREMENT_EXPR:
10388       op = decl = strip_out_static_field_access_decl (op);
10389       /* We really should have a JAVA_ARRAY_EXPR to avoid this */
10390       if (!JDECL_P (decl) 
10391           && TREE_CODE (decl) != COMPONENT_REF
10392           && !(flag_emit_class_files && TREE_CODE (decl) == ARRAY_REF)
10393           && TREE_CODE (decl) != INDIRECT_REF
10394           && !(TREE_CODE (decl) == COMPOUND_EXPR
10395                && TREE_OPERAND (decl, 1)
10396                && (TREE_CODE (TREE_OPERAND (decl, 1)) == INDIRECT_REF)))
10397         {
10398           tree lvalue;
10399           /* Before screaming, check that we're not in fact trying to
10400              increment a optimized static final access, in which case
10401              we issue an different error message. */
10402           if (!(TREE_CODE (wfl_op) == EXPR_WITH_FILE_LOCATION
10403                 && resolve_expression_name (wfl_op, &lvalue)
10404                 && check_final_assignment (lvalue, wfl_op)))
10405             parse_error_context (wfl_operator, "Invalid argument to `%s'",
10406                                  operator_string (node));
10407           TREE_TYPE (node) = error_mark_node;
10408           error_found = 1;
10409         }
10410       else if (check_final_assignment (op, wfl_op))
10411         error_found = 1;
10412
10413       /* From now on, we know that op if a variable and that it has a
10414          valid wfl. We use wfl_op to locate errors related to the
10415          ++/-- operand. */
10416       else if (!JNUMERIC_TYPE_P (op_type))
10417         {
10418           parse_error_context
10419             (wfl_op, "Invalid argument type `%s' to `%s'",
10420              lang_printable_name (op_type, 0), operator_string (node));
10421           TREE_TYPE (node) = error_mark_node;
10422           error_found = 1;
10423         }
10424       else
10425         {
10426           /* Before the addition, binary numeric promotion is performed on
10427              both operands, if really necessary */
10428           if (JINTEGRAL_TYPE_P (op_type))
10429             {
10430               value = build_int_2 (1, 0);
10431               TREE_TYPE (value) = TREE_TYPE (node) = op_type;
10432             }
10433           else
10434             {
10435               value = build_int_2 (1, 0);
10436               TREE_TYPE (node) = 
10437                 binary_numeric_promotion (op_type, 
10438                                           TREE_TYPE (value), &op, &value);
10439             }
10440           /* And write back into the node. */
10441           TREE_OPERAND (node, 0) = op;
10442           TREE_OPERAND (node, 1) = value;
10443           /* Convert the overall back into its original type, if
10444              necessary, and return */
10445           if (JINTEGRAL_TYPE_P (op_type))
10446             return fold (node);
10447           else
10448             return fold (convert (op_type, node));
10449         }
10450       break;
10451
10452       /* 15.14.3 Unary Plus Operator + */
10453     case UNARY_PLUS_EXPR:
10454       /* 15.14.4 Unary Minus Operator - */
10455     case NEGATE_EXPR:
10456       if (!JNUMERIC_TYPE_P (op_type))
10457         {
10458           ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op_type);
10459           TREE_TYPE (node) = error_mark_node;
10460           error_found = 1;
10461         }
10462       /* Unary numeric promotion is performed on operand */
10463       else
10464         {
10465           op = do_unary_numeric_promotion (op);
10466           prom_type = TREE_TYPE (op);
10467           if (code == UNARY_PLUS_EXPR)
10468             return fold (op);
10469         }
10470       break;
10471
10472       /* 15.14.5 Bitwise Complement Operator ~ */
10473     case BIT_NOT_EXPR:
10474       if (!JINTEGRAL_TYPE_P (op_type))
10475         {
10476           ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op_type);
10477           TREE_TYPE (node) = error_mark_node;
10478           error_found = 1;
10479         }
10480       else
10481         {
10482           op = do_unary_numeric_promotion (op);
10483           prom_type = TREE_TYPE (op);
10484         }
10485       break;
10486
10487       /* 15.14.6 Logical Complement Operator ! */
10488     case TRUTH_NOT_EXPR:
10489       if (TREE_CODE (op_type) != BOOLEAN_TYPE)
10490         {
10491           ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op_type);
10492           /* But the type is known. We will report an error if further
10493              attempt of a assignment is made with this rhs */
10494           TREE_TYPE (node) = boolean_type_node;
10495           error_found = 1;
10496         }
10497       else
10498         prom_type = boolean_type_node;
10499       break;
10500
10501       /* 15.15 Cast Expression */
10502     case CONVERT_EXPR:
10503       value = patch_cast (node, wfl_operator);
10504       if (value == error_mark_node)
10505         {
10506           /* If this cast is part of an assignment, we tell the code
10507              that deals with it not to complain about a mismatch,
10508              because things have been cast, anyways */
10509           TREE_TYPE (node) = error_mark_node;
10510           error_found = 1;
10511         }
10512       else
10513         {
10514           value = fold (value);
10515           TREE_SIDE_EFFECTS (value) = TREE_SIDE_EFFECTS (op);
10516           return value;
10517         }
10518       break;
10519     }
10520   
10521   if (error_found)
10522     return error_mark_node;
10523
10524   /* There are cases where node has been replaced by something else
10525      and we don't end up returning here: UNARY_PLUS_EXPR,
10526      CONVERT_EXPR, {POST,PRE}{INCR,DECR}EMENT_EXPR. */
10527   TREE_OPERAND (node, 0) = fold (op);
10528   TREE_TYPE (node) = prom_type;
10529   TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op);
10530   return fold (node);
10531 }
10532
10533 /* Generic type resolution that sometimes takes place during node
10534    patching. Returned the resolved type or generate an error
10535    message. Return the resolved type or NULL_TREE.  */
10536
10537 static tree
10538 resolve_type_during_patch (type)
10539      tree type;
10540 {
10541   if (unresolved_type_p (type, NULL))
10542     {
10543       tree type_decl = resolve_no_layout (EXPR_WFL_NODE (type), NULL_TREE);
10544       if (!type_decl)
10545         {
10546           parse_error_context (type, 
10547                                "Class `%s' not found in type declaration",
10548                                IDENTIFIER_POINTER (EXPR_WFL_NODE (type)));
10549           return NULL_TREE;
10550         }
10551       else
10552         {
10553           CLASS_LOADED_P (TREE_TYPE (type_decl)) = 1;
10554           return TREE_TYPE (type_decl);
10555         }
10556     }
10557   return type;
10558 }
10559 /* 5.5 Casting Conversion. error_mark_node is returned if an error is
10560    found. Otherwise NODE or something meant to replace it is returned.  */
10561
10562 static tree
10563 patch_cast (node, wfl_operator)
10564      tree node;
10565      tree wfl_operator;
10566 {
10567   tree op = TREE_OPERAND (node, 0);
10568   tree op_type = TREE_TYPE (op);
10569   tree cast_type = TREE_TYPE (node);
10570   char *t1;
10571
10572   /* First resolve OP_TYPE if unresolved */
10573   if (!(cast_type = resolve_type_during_patch (cast_type)))
10574     return error_mark_node;
10575
10576   /* Check on cast that are proven correct at compile time */
10577   if (JNUMERIC_TYPE_P (cast_type) && JNUMERIC_TYPE_P (op_type))
10578     {
10579       /* Same type */
10580       if (cast_type == op_type)
10581         return node;
10582
10583       /* float and double type are converted to the original type main
10584          variant and then to the target type. */
10585       if (JFLOAT_TYPE_P (op_type) && TREE_CODE (cast_type) == CHAR_TYPE)
10586         op = convert (integer_type_node, op);
10587
10588       /* Try widening/narowwing convertion. Potentially, things need
10589          to be worked out in gcc so we implement the extreme cases
10590          correctly. fold_convert() needs to be fixed. */
10591       return convert (cast_type, op);
10592     }
10593
10594   /* It's also valid to cast a boolean into a boolean */
10595   if (op_type == boolean_type_node && cast_type == boolean_type_node)
10596     return node;
10597
10598   /* null can be casted to references */
10599   if (op == null_pointer_node && JREFERENCE_TYPE_P (cast_type))
10600     return build_null_of_type (cast_type);
10601
10602   /* The remaining legal casts involve conversion between reference
10603      types. Check for their compile time correctness. */
10604   if (JREFERENCE_TYPE_P (op_type) && JREFERENCE_TYPE_P (cast_type) 
10605       && valid_ref_assignconv_cast_p (op_type, cast_type, 1))
10606     {
10607       TREE_TYPE (node) = promote_type (cast_type);
10608       /* Now, the case can be determined correct at compile time if
10609          OP_TYPE can be converted into CAST_TYPE by assignment
10610          conversion (5.2) */
10611
10612       if (valid_ref_assignconv_cast_p (op_type, cast_type, 0))
10613         {
10614           TREE_SET_CODE (node, NOP_EXPR);
10615           return node;
10616         }
10617
10618       if (flag_emit_class_files)
10619         {
10620           TREE_SET_CODE (node, CONVERT_EXPR);
10621           return node;
10622         }
10623
10624       /* The cast requires a run-time check */
10625       return build (CALL_EXPR, promote_type (cast_type),
10626                     build_address_of (soft_checkcast_node),
10627                     tree_cons (NULL_TREE, build_class_ref (cast_type),
10628                                build_tree_list (NULL_TREE, op)),
10629                     NULL_TREE);
10630     }
10631
10632   /* Any other casts are proven incorrect at compile time */
10633   t1 = xstrdup (lang_printable_name (op_type, 0));
10634   parse_error_context (wfl_operator, "Invalid cast from `%s' to `%s'",
10635                        t1, lang_printable_name (cast_type, 0));
10636   free (t1);
10637   return error_mark_node;
10638 }
10639
10640 /* Build a null constant and give it the type TYPE.  */
10641
10642 static tree
10643 build_null_of_type (type)
10644      tree type;
10645 {
10646   tree node = build_int_2 (0, 0);
10647   TREE_TYPE (node) = promote_type (type);
10648   return node;
10649 }
10650
10651 /* Build an ARRAY_REF incomplete tree node. Note that operand 1 isn't
10652    a list of indices. */
10653 static tree
10654 build_array_ref (location, array, index)
10655      int location;
10656      tree array, index;
10657 {
10658   tree node = build (ARRAY_REF, NULL_TREE, array, index);
10659   EXPR_WFL_LINECOL (node) = location;
10660   return node;
10661 }
10662
10663 /* 15.12 Array Access Expression */
10664
10665 static tree
10666 patch_array_ref (node)
10667      tree node;
10668 {
10669   tree array = TREE_OPERAND (node, 0);
10670   tree array_type  = TREE_TYPE (array);
10671   tree index = TREE_OPERAND (node, 1);
10672   tree index_type = TREE_TYPE (index);
10673   int error_found = 0;
10674
10675   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
10676
10677   if (TREE_CODE (array_type) == POINTER_TYPE)
10678     array_type = TREE_TYPE (array_type);
10679
10680   /* The array reference must be an array */
10681   if (!TYPE_ARRAY_P (array_type))
10682     {
10683       parse_error_context 
10684         (wfl_operator, "`[]' can only be applied to arrays. It can't be "
10685          "applied to `%s'", lang_printable_name (array_type, 0));
10686       TREE_TYPE (node) = error_mark_node;
10687       error_found = 1;
10688     }
10689
10690   /* The array index underdoes unary numeric promotion. The promoted
10691      type must be int */
10692   index = do_unary_numeric_promotion (index);
10693   if (TREE_TYPE (index) != int_type_node)
10694     {
10695       if (valid_cast_to_p (index_type, int_type_node))
10696         parse_error_context (wfl_operator, "Incompatible type for `[]'. "
10697                              "Explicit cast needed to convert `%s' to `int'",
10698                              lang_printable_name (index_type, 0));
10699       else
10700         parse_error_context (wfl_operator, "Incompatible type for `[]'. "
10701                              "Can't convert `%s' to `int'",
10702                              lang_printable_name (index_type, 0));
10703       TREE_TYPE (node) = error_mark_node;
10704       error_found = 1;
10705     }
10706
10707   if (error_found)
10708     return error_mark_node;
10709
10710   array_type = TYPE_ARRAY_ELEMENT (array_type);
10711
10712   if (flag_emit_class_files || flag_emit_xref)
10713     {
10714       TREE_OPERAND (node, 0) = array;
10715       TREE_OPERAND (node, 1) = index;
10716     }
10717   else
10718     {
10719       /* The save_expr is for correct evaluation order.  It would be cleaner
10720          to use force_evaluation_order (see comment there), but that is
10721          difficult when we also have to deal with bounds checking. */
10722       if (TREE_SIDE_EFFECTS (index))
10723         array = save_expr (array);
10724       node = build_java_arrayaccess (array, array_type, index);
10725       if (TREE_SIDE_EFFECTS (index))
10726         node = build (COMPOUND_EXPR, array_type, array, node);
10727     }
10728   TREE_TYPE (node) = array_type;
10729   return node;
10730 }
10731
10732 /* 15.9 Array Creation Expressions */
10733
10734 static tree
10735 build_newarray_node (type, dims, extra_dims)
10736      tree type;
10737      tree dims;
10738      int extra_dims;
10739 {
10740   tree node =
10741     build (NEW_ARRAY_EXPR, NULL_TREE, type, nreverse (dims), 
10742            build_int_2 (extra_dims, 0));
10743   return node;
10744 }
10745
10746 static tree
10747 patch_newarray (node)
10748      tree node;
10749 {
10750   tree type = TREE_OPERAND (node, 0);
10751   tree dims = TREE_OPERAND (node, 1);
10752   tree cdim, array_type;
10753   int error_found = 0;
10754   int ndims = 0;
10755   int xdims = TREE_INT_CST_LOW (TREE_OPERAND (node, 2));
10756
10757   /* Dimension types are verified. It's better for the types to be
10758      verified in order. */
10759   for (cdim = dims, ndims = 0; cdim; cdim = TREE_CHAIN (cdim), ndims++ )
10760     {
10761       int dim_error = 0;
10762       tree dim = TREE_VALUE (cdim);
10763
10764       /* Dim might have been saved during its evaluation */
10765       dim = (TREE_CODE (dim) == SAVE_EXPR ? dim = TREE_OPERAND (dim, 0) : dim);
10766
10767       /* The type of each specified dimension must be an integral type. */
10768       if (!JINTEGRAL_TYPE_P (TREE_TYPE (dim)))
10769         dim_error = 1;
10770
10771       /* Each expression undergoes an unary numeric promotion (5.6.1) and the
10772          promoted type must be int. */
10773       else
10774         {
10775           dim = do_unary_numeric_promotion (dim);
10776           if (TREE_TYPE (dim) != int_type_node)
10777             dim_error = 1;
10778         }
10779
10780       /* Report errors on types here */
10781       if (dim_error)
10782         {
10783           parse_error_context 
10784             (TREE_PURPOSE (cdim), 
10785              "Incompatible type for dimension in array creation expression. "
10786              "%s convert `%s' to `int'", 
10787              (valid_cast_to_p (TREE_TYPE (dim), int_type_node) ?
10788               "Explicit cast needed to" : "Can't"),
10789              lang_printable_name (TREE_TYPE (dim), 0));
10790           error_found = 1;
10791         }
10792
10793       TREE_PURPOSE (cdim) = NULL_TREE;
10794     }
10795
10796   /* Resolve array base type if unresolved */
10797   if (!(type = resolve_type_during_patch (type)))
10798     error_found = 1;
10799
10800   if (error_found)
10801     {
10802       /* We don't want further evaluation of this bogus array creation
10803          operation */
10804       TREE_TYPE (node) = error_mark_node;
10805       return error_mark_node;
10806     }
10807
10808   /* Set array_type to the actual (promoted) array type of the result. */
10809   if (TREE_CODE (type) == RECORD_TYPE)
10810     type = build_pointer_type (type);
10811   while (--xdims >= 0)
10812     {
10813       type = promote_type (build_java_array_type (type, -1));
10814     }
10815   dims = nreverse (dims);
10816   array_type = type;
10817   for (cdim = dims; cdim; cdim = TREE_CHAIN (cdim))
10818     {
10819       type = array_type;
10820       array_type = build_java_array_type (type,
10821                                           TREE_CODE (cdim) == INTEGER_CST ?
10822                                           TREE_INT_CST_LOW (cdim) : -1);
10823       array_type = promote_type (array_type);
10824     }
10825   dims = nreverse (dims);
10826
10827   /* The node is transformed into a function call. Things are done
10828      differently according to the number of dimensions. If the number
10829      of dimension is equal to 1, then the nature of the base type
10830      (primitive or not) matters. */
10831   if (ndims == 1)
10832     return build_new_array (type, TREE_VALUE (dims));
10833   
10834   /* Can't reuse what's already written in expr.c because it uses the
10835      JVM stack representation. Provide a build_multianewarray. FIXME */
10836   return build (CALL_EXPR, array_type,
10837                 build_address_of (soft_multianewarray_node),
10838                 tree_cons (NULL_TREE, build_class_ref (TREE_TYPE (array_type)),
10839                            tree_cons (NULL_TREE, 
10840                                       build_int_2 (ndims, 0), dims )),
10841                 NULL_TREE);
10842 }
10843
10844 /* 10.6 Array initializer.  */
10845
10846 /* Build a wfl for array element that don't have one, so we can
10847    pin-point errors.  */
10848
10849 static tree
10850 maybe_build_array_element_wfl (node)
10851      tree node;
10852 {
10853   if (TREE_CODE (node) != EXPR_WITH_FILE_LOCATION)
10854     return build_expr_wfl (NULL_TREE, ctxp->filename,
10855                            ctxp->elc.line, ctxp->elc.prev_col);
10856   else
10857     return NULL_TREE;
10858 }
10859
10860 /* Build a NEW_ARRAY_INIT that features a CONSTRUCTOR node. This makes
10861    identification of initialized arrays easier to detect during walk
10862    and expansion.  */
10863
10864 static tree
10865 build_new_array_init (location, values)
10866      int location;
10867      tree values;
10868 {
10869   tree constructor = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, values);
10870   tree to_return = build1 (NEW_ARRAY_INIT, NULL_TREE, constructor);
10871   EXPR_WFL_LINECOL (to_return) = location;
10872   return to_return;
10873 }
10874
10875 /* Expand a NEW_ARRAY_INIT node. Return error_mark_node if an error
10876    occurred.  Otherwise return NODE after having set its type
10877    appropriately.  */
10878
10879 static tree
10880 patch_new_array_init (type, node)
10881      tree type, node;
10882 {
10883   int error_seen = 0;
10884   tree current, element_type;
10885   HOST_WIDE_INT length;
10886   int all_constant = 1;
10887   tree init = TREE_OPERAND (node, 0);
10888
10889   if (TREE_CODE (type) != POINTER_TYPE || ! TYPE_ARRAY_P (TREE_TYPE (type)))
10890     {
10891       parse_error_context (node,
10892                            "Invalid array initializer for non-array type `%s'",
10893                            lang_printable_name (type, 1));
10894       return error_mark_node;
10895     }
10896   type = TREE_TYPE (type);
10897   element_type = TYPE_ARRAY_ELEMENT (type);
10898
10899   CONSTRUCTOR_ELTS (init) = nreverse (CONSTRUCTOR_ELTS (init));
10900
10901   for (length = 0, current = CONSTRUCTOR_ELTS (init);
10902        current;  length++, current = TREE_CHAIN (current))
10903     {
10904       tree elt = TREE_VALUE (current);
10905       if (elt == NULL_TREE || TREE_CODE (elt) != NEW_ARRAY_INIT)
10906         {
10907           error_seen |= array_constructor_check_entry (element_type, current);
10908           elt = TREE_VALUE (current);
10909           /* When compiling to native code, STRING_CST is converted to
10910              INDIRECT_REF, but still with a TREE_CONSTANT flag. */
10911           if (! TREE_CONSTANT (elt) || TREE_CODE (elt) == INDIRECT_REF)
10912             all_constant = 0;
10913         }
10914       else
10915         {
10916           TREE_VALUE (current) = patch_new_array_init (element_type, elt);
10917           TREE_PURPOSE (current) = NULL_TREE;
10918           all_constant = 0;
10919         }
10920       if (elt && TREE_VALUE (elt) == error_mark_node)
10921         error_seen = 1;
10922     }
10923
10924   if (error_seen)
10925     return error_mark_node;
10926
10927   /* Create a new type. We can't reuse the one we have here by
10928      patching its dimension because it originally is of dimension -1
10929      hence reused by gcc. This would prevent triangular arrays. */
10930   type = build_java_array_type (element_type, length);
10931   TREE_TYPE (init) = TREE_TYPE (TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (type))));
10932   TREE_TYPE (node) = promote_type (type);
10933   TREE_CONSTANT (init) = all_constant;
10934   TREE_CONSTANT (node) = all_constant;
10935   return node;
10936 }
10937
10938 /* Verify that one entry of the initializer element list can be
10939    assigned to the array base type. Report 1 if an error occurred, 0
10940    otherwise.  */
10941
10942 static int
10943 array_constructor_check_entry (type, entry)
10944      tree type, entry;
10945 {
10946   char *array_type_string = NULL;       /* For error reports */
10947   tree value, type_value, new_value, wfl_value, patched;
10948   int error_seen = 0;
10949
10950   new_value = NULL_TREE;
10951   wfl_value = TREE_VALUE (entry);
10952
10953   push_obstacks (&permanent_obstack, &permanent_obstack);
10954   value = java_complete_tree (TREE_VALUE (entry));
10955   /* patch_string return error_mark_node if arg is error_mark_node */
10956   if ((patched = patch_string (value)))
10957     value = patched;
10958   if (value == error_mark_node)
10959     return 1;
10960   
10961   type_value = TREE_TYPE (value);
10962   
10963   /* At anytime, try_builtin_assignconv can report a warning on
10964      constant overflow during narrowing. */
10965   SET_WFL_OPERATOR (wfl_operator, TREE_PURPOSE (entry), wfl_value);
10966   new_value = try_builtin_assignconv (wfl_operator, type, value);
10967   if (!new_value && (new_value = try_reference_assignconv (type, value)))
10968     type_value = promote_type (type);
10969
10970   pop_obstacks ();
10971   /* Check and report errors */
10972   if (!new_value)
10973     {
10974       const char *msg = (!valid_cast_to_p (type_value, type) ?
10975                    "Can't" : "Explicit cast needed to");
10976       if (!array_type_string)
10977         array_type_string = xstrdup (lang_printable_name (type, 1));
10978       parse_error_context 
10979         (wfl_operator, "Incompatible type for array. %s convert `%s' to `%s'",
10980          msg, lang_printable_name (type_value, 1), array_type_string);
10981       error_seen = 1;
10982     }
10983   
10984   if (new_value)
10985     {
10986       new_value = maybe_build_primttype_type_ref (new_value, wfl_operator);
10987       TREE_VALUE (entry) = new_value;
10988     }
10989
10990   if (array_type_string)
10991     free (array_type_string);
10992
10993   TREE_PURPOSE (entry) = NULL_TREE;
10994   return error_seen;
10995 }
10996
10997 static tree
10998 build_this (location)
10999      int location;
11000 {
11001   tree node = build_wfl_node (this_identifier_node);
11002   TREE_SET_CODE (node, THIS_EXPR);
11003   EXPR_WFL_LINECOL (node) = location;
11004   return node;
11005 }
11006
11007 /* 14.15 The return statement. It builds a modify expression that
11008    assigns the returned value to the RESULT_DECL that hold the value
11009    to be returned. */
11010
11011 static tree
11012 build_return (location, op)
11013      int location;
11014      tree op;
11015 {
11016   tree node = build1 (RETURN_EXPR, NULL_TREE, op);
11017   EXPR_WFL_LINECOL (node) = location;
11018   node = build_debugable_stmt (location, node);
11019   return node;
11020 }
11021
11022 static tree
11023 patch_return (node)
11024      tree node;
11025 {
11026   tree return_exp = TREE_OPERAND (node, 0);
11027   tree meth = current_function_decl;
11028   tree mtype = TREE_TYPE (TREE_TYPE (current_function_decl));
11029   int error_found = 0;
11030
11031   TREE_TYPE (node) = error_mark_node;
11032   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11033
11034   /* It's invalid to have a return value within a function that is
11035      declared with the keyword void or that is a constructor */
11036   if (return_exp && (mtype == void_type_node || DECL_CONSTRUCTOR_P (meth)))
11037     error_found = 1;
11038
11039   /* It's invalid to use a return statement in a static block */
11040   if (IS_CLINIT (current_function_decl))
11041     error_found = 1;
11042
11043   /* It's invalid to have a no return value within a function that
11044      isn't declared with the keyword `void' */
11045   if (!return_exp && (mtype != void_type_node && !DECL_CONSTRUCTOR_P (meth)))
11046     error_found = 2;
11047
11048   if (error_found)
11049     {
11050       if (IS_CLINIT (current_function_decl))
11051         parse_error_context (wfl_operator,
11052                              "`return' inside static initializer.");
11053
11054       else if (!DECL_CONSTRUCTOR_P (meth))
11055         {
11056           char *t = xstrdup (lang_printable_name (mtype, 0));
11057           parse_error_context (wfl_operator, 
11058                                "`return' with%s value from `%s %s'",
11059                                (error_found == 1 ? "" : "out"), 
11060                                t, lang_printable_name (meth, 0));
11061           free (t);
11062         }
11063       else
11064         parse_error_context (wfl_operator, 
11065                              "`return' with value from constructor `%s'",
11066                              lang_printable_name (meth, 0));
11067       return error_mark_node;
11068     }
11069
11070   /* If we have a return_exp, build a modify expression and expand
11071      it. Note: at that point, the assignment is declared valid, but we
11072      may want to carry some more hacks */
11073   if (return_exp)
11074     {
11075       tree exp = java_complete_tree (return_exp);
11076       tree modify, patched;
11077
11078       /* If the function returned value and EXP are booleans, EXP has
11079       to be converted into the type of DECL_RESULT, which is integer
11080       (see complete_start_java_method) */
11081       if (TREE_TYPE (exp) == boolean_type_node &&
11082           TREE_TYPE (TREE_TYPE (meth)) == boolean_type_node)
11083         exp = convert_to_integer (TREE_TYPE (DECL_RESULT (meth)), exp);
11084
11085       /* `null' can be assigned to a function returning a reference */
11086       if (JREFERENCE_TYPE_P (TREE_TYPE (TREE_TYPE (meth))) &&
11087           exp == null_pointer_node)
11088         exp = build_null_of_type (TREE_TYPE (TREE_TYPE (meth)));
11089
11090       if ((patched = patch_string (exp)))
11091         exp = patched;
11092       
11093       modify = build (MODIFY_EXPR, NULL_TREE, DECL_RESULT (meth), exp);
11094       EXPR_WFL_LINECOL (modify) = EXPR_WFL_LINECOL (node);
11095       modify = java_complete_tree (modify);
11096
11097       if (modify != error_mark_node)
11098         {
11099           TREE_SIDE_EFFECTS (modify) = 1;
11100           TREE_OPERAND (node, 0) = modify;
11101         }
11102       else
11103         return error_mark_node;
11104     }
11105   TREE_TYPE (node) = void_type_node;
11106   TREE_SIDE_EFFECTS (node) = 1;
11107   return node;
11108 }
11109
11110 /* 14.8 The if Statement */
11111
11112 static tree
11113 build_if_else_statement (location, expression, if_body, else_body)
11114      int location;
11115      tree expression, if_body, else_body;
11116 {
11117   tree node;
11118   if (!else_body)
11119     else_body = empty_stmt_node;
11120   node = build (COND_EXPR, NULL_TREE, expression, if_body, else_body);
11121   EXPR_WFL_LINECOL (node) = location;
11122   node = build_debugable_stmt (location, node);
11123   return node;
11124 }
11125
11126 static tree
11127 patch_if_else_statement (node)
11128      tree node;
11129 {
11130   tree expression = TREE_OPERAND (node, 0);
11131
11132   TREE_TYPE (node) = error_mark_node;
11133   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11134
11135   /* The type of expression must be boolean */
11136   if (TREE_TYPE (expression) != boolean_type_node
11137       && TREE_TYPE (expression) != promoted_boolean_type_node)
11138     {
11139       parse_error_context 
11140         (wfl_operator, 
11141          "Incompatible type for `if'. Can't convert `%s' to `boolean'", 
11142          lang_printable_name (TREE_TYPE (expression), 0));
11143       return error_mark_node;
11144     }
11145   
11146   TREE_TYPE (node) = void_type_node;
11147   TREE_SIDE_EFFECTS (node) = 1;
11148   CAN_COMPLETE_NORMALLY (node)
11149     = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1))
11150     | CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 2));
11151   return node;
11152 }
11153
11154 /* 14.6 Labeled Statements */
11155
11156 /* Action taken when a lableled statement is parsed. a new
11157    LABELED_BLOCK_EXPR is created. No statement is attached to the
11158    label, yet.  LABEL can be NULL_TREE for artificially-generated blocks. */
11159
11160 static tree
11161 build_labeled_block (location, label)
11162      int location;
11163      tree label;
11164 {
11165   tree label_name ;
11166   tree label_decl, node;
11167   if (label == NULL_TREE || label == continue_identifier_node)
11168     label_name = label;
11169   else
11170     {
11171       label_name = merge_qualified_name (label_id, label);
11172       /* Issue an error if we try to reuse a label that was previously
11173          declared */
11174       if (IDENTIFIER_LOCAL_VALUE (label_name))
11175         {
11176           EXPR_WFL_LINECOL (wfl_operator) = location;
11177           parse_error_context (wfl_operator, "Declaration of `%s' shadows "
11178                                "a previous label declaration",
11179                                IDENTIFIER_POINTER (label));
11180           EXPR_WFL_LINECOL (wfl_operator) = 
11181             EXPR_WFL_LINECOL (IDENTIFIER_LOCAL_VALUE (label_name));
11182           parse_error_context (wfl_operator, "This is the location of the "
11183                                "previous declaration of label `%s'",
11184                                IDENTIFIER_POINTER (label));
11185           java_error_count--;
11186         }
11187     }
11188
11189   label_decl = create_label_decl (label_name);
11190   node = build (LABELED_BLOCK_EXPR, NULL_TREE, label_decl, NULL_TREE);
11191   EXPR_WFL_LINECOL (node) = location;
11192   TREE_SIDE_EFFECTS (node) = 1;
11193   return node;
11194 }
11195
11196 /* A labeled statement LBE is attached a statement.  */
11197
11198 static tree
11199 finish_labeled_statement (lbe, statement)
11200      tree lbe;                  /* Labeled block expr */
11201      tree statement;
11202 {
11203   /* In anyways, tie the loop to its statement */
11204   LABELED_BLOCK_BODY (lbe) = statement;
11205   pop_labeled_block ();
11206   POP_LABELED_BLOCK ();
11207   return lbe;
11208 }
11209
11210 /* 14.10, 14.11, 14.12 Loop Statements */
11211
11212 /* Create an empty LOOP_EXPR and make it the last in the nested loop
11213    list. */
11214
11215 static tree
11216 build_new_loop (loop_body)
11217      tree loop_body;
11218 {
11219   tree loop =  build (LOOP_EXPR, NULL_TREE, loop_body);
11220   TREE_SIDE_EFFECTS (loop) = 1;
11221   PUSH_LOOP (loop);
11222   return loop;
11223 }
11224
11225 /* Create a loop body according to the following structure:
11226      COMPOUND_EXPR
11227        COMPOUND_EXPR            (loop main body)
11228          EXIT_EXPR              (this order is for while/for loops.
11229          LABELED_BLOCK_EXPR      the order is reversed for do loops)
11230            LABEL_DECL           (a continue occuring here branches at the 
11231            BODY                  end of this labeled block)
11232        INCREMENT                (if any)
11233
11234   REVERSED, if non zero, tells that the loop condition expr comes
11235   after the body, like in the do-while loop.
11236
11237   To obtain a loop, the loop body structure described above is
11238   encapsulated within a LOOP_EXPR surrounded by a LABELED_BLOCK_EXPR:
11239
11240    LABELED_BLOCK_EXPR
11241      LABEL_DECL                   (use this label to exit the loop)
11242      LOOP_EXPR
11243        <structure described above> */
11244
11245 static tree
11246 build_loop_body (location, condition, reversed)
11247      int location;
11248      tree condition;
11249      int reversed;
11250 {
11251   tree first, second, body;
11252
11253   condition = build (EXIT_EXPR, NULL_TREE, condition); /* Force walk */
11254   EXPR_WFL_LINECOL (condition) = location; /* For accurate error report */
11255   condition = build_debugable_stmt (location, condition);
11256   TREE_SIDE_EFFECTS (condition) = 1;
11257
11258   body = build_labeled_block (0, continue_identifier_node);
11259   first = (reversed ? body : condition);
11260   second = (reversed ? condition : body);
11261   return 
11262     build (COMPOUND_EXPR, NULL_TREE, 
11263            build (COMPOUND_EXPR, NULL_TREE, first, second), empty_stmt_node);
11264 }
11265
11266 /* Install CONDITION (if any) and loop BODY (using REVERSED to tell
11267    their order) on the current loop. Unlink the current loop from the
11268    loop list.  */
11269
11270 static tree
11271 finish_loop_body (location, condition, body, reversed)
11272      int location;
11273      tree condition, body;
11274      int reversed;
11275 {
11276   tree to_return = ctxp->current_loop;
11277   tree loop_body = LOOP_EXPR_BODY (to_return);
11278   if (condition)
11279     {
11280       tree cnode = LOOP_EXPR_BODY_CONDITION_EXPR (loop_body, reversed);
11281       /* We wrapped the EXIT_EXPR around a WFL so we can debug it.
11282          The real EXIT_EXPR is one operand further. */
11283       EXPR_WFL_LINECOL (cnode) = location;
11284       /* This one is for accurate error reports */
11285       EXPR_WFL_LINECOL (TREE_OPERAND (cnode, 0)) = location;
11286       TREE_OPERAND (TREE_OPERAND (cnode, 0), 0) = condition;
11287     }
11288   LOOP_EXPR_BODY_BODY_EXPR (loop_body, reversed) = body;
11289   POP_LOOP ();
11290   return to_return;
11291 }
11292
11293 /* Tailored version of finish_loop_body for FOR loops, when FOR
11294    loops feature the condition part */
11295
11296 static tree
11297 finish_for_loop (location, condition, update, body)
11298     int location;
11299     tree condition, update, body;
11300 {
11301   /* Put the condition and the loop body in place */
11302   tree loop = finish_loop_body (location, condition, body, 0);
11303   /* LOOP is the current loop which has been now popped of the loop
11304      stack. Install the update block */
11305   LOOP_EXPR_BODY_UPDATE_BLOCK (LOOP_EXPR_BODY (loop)) = update;
11306   return loop;
11307 }
11308
11309 /* Try to find the loop a block might be related to. This comprises
11310    the case where the LOOP_EXPR is found as the second operand of a
11311    COMPOUND_EXPR, because the loop happens to have an initialization
11312    part, then expressed as the first operand of the COMPOUND_EXPR. If
11313    the search finds something, 1 is returned. Otherwise, 0 is
11314    returned. The search is assumed to start from a
11315    LABELED_BLOCK_EXPR's block.  */
11316
11317 static tree
11318 search_loop (statement)
11319     tree statement;
11320 {
11321   if (TREE_CODE (statement) == LOOP_EXPR)
11322     return statement;
11323
11324   if (TREE_CODE (statement) == BLOCK)
11325     statement = BLOCK_SUBBLOCKS (statement);
11326   else
11327     return NULL_TREE;
11328
11329   if (statement && TREE_CODE (statement) == COMPOUND_EXPR)
11330     while (statement && TREE_CODE (statement) == COMPOUND_EXPR)
11331       statement = TREE_OPERAND (statement, 1);
11332
11333   return (TREE_CODE (statement) == LOOP_EXPR
11334           && IS_FOR_LOOP_P (statement) ? statement : NULL_TREE);
11335 }
11336
11337 /* Return 1 if LOOP can be found in the labeled block BLOCK. 0 is
11338    returned otherwise.  */
11339
11340 static int
11341 labeled_block_contains_loop_p (block, loop)
11342     tree block, loop;
11343 {
11344   if (!block)
11345     return 0;
11346
11347   if (LABELED_BLOCK_BODY (block) == loop)
11348     return 1;
11349
11350   if (IS_FOR_LOOP_P (loop) 
11351       && search_loop (LABELED_BLOCK_BODY (block)) == loop)
11352     return 1;
11353
11354   return 0;
11355 }
11356
11357 /* If the loop isn't surrounded by a labeled statement, create one and
11358    insert LOOP as its body.  */
11359
11360 static tree
11361 patch_loop_statement (loop)
11362      tree loop;
11363 {
11364   tree loop_label;
11365
11366   TREE_TYPE (loop) = void_type_node;
11367   if (labeled_block_contains_loop_p (ctxp->current_labeled_block, loop))
11368     return loop;
11369
11370   loop_label = build_labeled_block (0, NULL_TREE);
11371   /* LOOP is an EXPR node, so it should have a valid EXPR_WFL_LINECOL
11372      that LOOP_LABEL could enquire about, for a better accuracy. FIXME */
11373   LABELED_BLOCK_BODY (loop_label) = loop;
11374   PUSH_LABELED_BLOCK (loop_label);
11375   return loop_label;
11376 }
11377
11378 /* 14.13, 14.14: break and continue Statements */
11379
11380 /* Build a break or a continue statement. a null NAME indicates an
11381    unlabeled break/continue statement.  */
11382
11383 static tree
11384 build_bc_statement (location, is_break, name)
11385      int location, is_break;
11386      tree name;
11387 {
11388   tree break_continue, label_block_expr = NULL_TREE;
11389
11390   if (name)
11391     {
11392       if (!(label_block_expr = IDENTIFIER_LOCAL_VALUE 
11393             (merge_qualified_name (label_id, EXPR_WFL_NODE (name)))))
11394         /* Null means that we don't have a target for this named
11395            break/continue. In this case, we make the target to be the
11396            label name, so that the error can be reported accuratly in
11397            patch_bc_statement. */
11398         label_block_expr = EXPR_WFL_NODE (name);
11399     }
11400   /* Unlabeled break/continue will be handled during the
11401      break/continue patch operation */
11402   break_continue 
11403     = build (EXIT_BLOCK_EXPR, NULL_TREE, label_block_expr, NULL_TREE);
11404
11405   IS_BREAK_STMT_P (break_continue) = is_break;
11406   TREE_SIDE_EFFECTS (break_continue) = 1;
11407   EXPR_WFL_LINECOL (break_continue) = location;
11408   break_continue = build_debugable_stmt (location, break_continue);
11409   return break_continue;
11410 }
11411
11412 /* Verification of a break/continue statement. */
11413
11414 static tree
11415 patch_bc_statement (node)
11416      tree node;
11417 {
11418   tree bc_label = EXIT_BLOCK_LABELED_BLOCK (node), target_stmt;
11419   tree labeled_block = ctxp->current_labeled_block;
11420   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11421  
11422   /* Having an identifier here means that the target is unknown. */
11423   if (bc_label != NULL_TREE && TREE_CODE (bc_label) == IDENTIFIER_NODE)
11424     {
11425       parse_error_context (wfl_operator, "No label definition found for `%s'",
11426                            IDENTIFIER_POINTER (bc_label));
11427       return error_mark_node;
11428     }
11429   if (! IS_BREAK_STMT_P (node))
11430     {
11431       /* It's a continue statement. */
11432       for (;; labeled_block = TREE_CHAIN (labeled_block))
11433         {
11434           if (labeled_block == NULL_TREE)
11435             {
11436               if (bc_label == NULL_TREE)
11437                 parse_error_context (wfl_operator,
11438                                      "`continue' must be in loop");
11439               else
11440                 parse_error_context 
11441                   (wfl_operator, "continue label `%s' does not name a loop",
11442                    IDENTIFIER_POINTER (bc_label));
11443               return error_mark_node;
11444             }
11445           if ((DECL_NAME (LABELED_BLOCK_LABEL (labeled_block))
11446                == continue_identifier_node)
11447               && (bc_label == NULL_TREE
11448                   || TREE_CHAIN (labeled_block) == bc_label))
11449             {
11450               bc_label = labeled_block;
11451               break;
11452             }
11453         }
11454     }
11455   else if (!bc_label)
11456     { 
11457       for (;; labeled_block = TREE_CHAIN (labeled_block))
11458         {
11459           if (labeled_block == NULL_TREE)
11460             {
11461               parse_error_context (wfl_operator,
11462                                      "`break' must be in loop or switch");
11463               return error_mark_node;
11464             }
11465           target_stmt = LABELED_BLOCK_BODY (labeled_block);
11466           if (TREE_CODE (target_stmt) == SWITCH_EXPR
11467               || search_loop (target_stmt))
11468             {
11469               bc_label = labeled_block;
11470               break;
11471             }
11472         }
11473     }
11474
11475   EXIT_BLOCK_LABELED_BLOCK (node) = bc_label;
11476   CAN_COMPLETE_NORMALLY (bc_label) = 1;
11477
11478   /* Our break/continue don't return values. */
11479   TREE_TYPE (node) = void_type_node;
11480   /* Encapsulate the break within a compound statement so that it's
11481      expanded all the times by expand_expr (and not clobbered
11482      sometimes, like after a if statement) */
11483   node = add_stmt_to_compound (NULL_TREE, void_type_node, node);
11484   TREE_SIDE_EFFECTS (node) = 1;
11485   return node;
11486 }
11487
11488 /* Process the exit expression belonging to a loop. Its type must be
11489    boolean.  */
11490
11491 static tree
11492 patch_exit_expr (node)
11493      tree node;
11494 {
11495   tree expression = TREE_OPERAND (node, 0);
11496   TREE_TYPE (node) = error_mark_node;
11497   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11498
11499   /* The type of expression must be boolean */
11500   if (TREE_TYPE (expression) != boolean_type_node)
11501     {
11502       parse_error_context 
11503         (wfl_operator, 
11504          "Incompatible type for loop conditional. Can't convert `%s' to "
11505          "`boolean'", 
11506          lang_printable_name (TREE_TYPE (expression), 0));
11507       return error_mark_node;
11508     }
11509   /* Now we know things are allright, invert the condition, fold and
11510      return */
11511   TREE_OPERAND (node, 0) = 
11512     fold (build1 (TRUTH_NOT_EXPR, boolean_type_node, expression));
11513
11514   if (! integer_zerop (TREE_OPERAND (node, 0))
11515       && ctxp->current_loop != NULL_TREE
11516       && TREE_CODE (ctxp->current_loop) == LOOP_EXPR)
11517     CAN_COMPLETE_NORMALLY (ctxp->current_loop) = 1;
11518   if (! integer_onep (TREE_OPERAND (node, 0)))
11519     CAN_COMPLETE_NORMALLY (node) = 1;
11520
11521
11522   TREE_TYPE (node) = void_type_node;
11523   return node;
11524 }
11525
11526 /* 14.9 Switch statement */
11527
11528 static tree
11529 patch_switch_statement (node)
11530      tree node;
11531 {
11532   tree se = TREE_OPERAND (node, 0), se_type;
11533
11534   /* Complete the switch expression */
11535   se = TREE_OPERAND (node, 0) = java_complete_tree (se);
11536   se_type = TREE_TYPE (se);
11537   /* The type of the switch expression must be char, byte, short or
11538      int */
11539   if (!JINTEGRAL_TYPE_P (se_type))
11540     {
11541       EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
11542       parse_error_context (wfl_operator, "Incompatible type for `switch'. "
11543                            "Can't convert `%s' to `int'",
11544                            lang_printable_name (se_type, 0));
11545       /* This is what java_complete_tree will check */
11546       TREE_OPERAND (node, 0) = error_mark_node;
11547       return error_mark_node;
11548     }
11549
11550   TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
11551
11552   /* Ready to return */
11553   if (TREE_CODE (TREE_OPERAND (node, 1)) == ERROR_MARK)
11554     {
11555       TREE_TYPE (node) = error_mark_node;
11556       return error_mark_node;
11557     }
11558   TREE_TYPE (node) = void_type_node;
11559   TREE_SIDE_EFFECTS (node) = 1;
11560   CAN_COMPLETE_NORMALLY (node)
11561     = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)) 
11562       || ! SWITCH_HAS_DEFAULT (node);
11563   return node;
11564 }
11565
11566 /* 14.18 The try statement */
11567
11568 static tree
11569 build_try_statement (location, try_block, catches)
11570      int location;
11571      tree try_block, catches;
11572 {
11573   tree node = build (TRY_EXPR, NULL_TREE, try_block, catches);
11574   EXPR_WFL_LINECOL (node) = location;
11575   return node;
11576 }
11577
11578 static tree
11579 build_try_finally_statement (location, try_block, finally)
11580      int location;
11581      tree try_block, finally;
11582 {
11583   tree node = build (TRY_FINALLY_EXPR, NULL_TREE, try_block, finally);
11584   EXPR_WFL_LINECOL (node) = location;
11585   return node;
11586 }
11587
11588 static tree
11589 patch_try_statement (node)
11590      tree node;
11591 {
11592   int error_found = 0;
11593   tree try = TREE_OPERAND (node, 0);
11594   /* Exception handlers are considered in left to right order */
11595   tree catch = nreverse (TREE_OPERAND (node, 1));
11596   tree current, caught_type_list = NULL_TREE;
11597
11598   /* Check catch clauses, if any. Every time we find an error, we try
11599      to process the next catch clause. We process the catch clause before
11600      the try block so that when processing the try block we can check thrown
11601      exceptions againts the caught type list. */
11602   for (current = catch; current; current = TREE_CHAIN (current))
11603     {
11604       tree carg_decl, carg_type;
11605       tree sub_current, catch_block, catch_clause;
11606       int unreachable;
11607
11608       /* At this point, the structure of the catch clause is
11609            CATCH_EXPR           (catch node)
11610              BLOCK              (with the decl of the parameter)
11611                COMPOUND_EXPR
11612                  MODIFY_EXPR   (assignment of the catch parameter)
11613                  BLOCK          (catch clause block)
11614        */
11615       catch_clause = TREE_OPERAND (current, 0);
11616       carg_decl = BLOCK_EXPR_DECLS (catch_clause);
11617       carg_type = TREE_TYPE (TREE_TYPE (carg_decl));
11618
11619       /* Catch clauses can't have more than one parameter declared,
11620          but it's already enforced by the grammar. Make sure that the
11621          only parameter of the clause statement in of class Throwable
11622          or a subclass of Throwable, but that was done earlier. The
11623          catch clause parameter type has also been resolved. */
11624       
11625       /* Just make sure that the catch clause parameter type inherits
11626          from java.lang.Throwable */
11627       if (!inherits_from_p (carg_type, throwable_type_node))
11628         {
11629           EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
11630           parse_error_context (wfl_operator,
11631                                "Can't catch class `%s'. Catch clause "
11632                                "parameter type must be a subclass of "
11633                                "class `java.lang.Throwable'",
11634                                lang_printable_name (carg_type, 0));
11635           error_found = 1;
11636           continue;
11637         }
11638       
11639       /* Partial check for unreachable catch statement: The catch
11640          clause is reachable iff is no earlier catch block A in
11641          the try statement such that the type of the catch
11642          clause's parameter is the same as or a subclass of the
11643          type of A's parameter */
11644       unreachable = 0;
11645       for (sub_current = catch;
11646            sub_current != current; sub_current = TREE_CHAIN (sub_current))
11647         {
11648           tree sub_catch_clause, decl;
11649           sub_catch_clause = TREE_OPERAND (sub_current, 0);
11650           decl = BLOCK_EXPR_DECLS (sub_catch_clause);
11651
11652           if (inherits_from_p (carg_type, TREE_TYPE (TREE_TYPE (decl))))
11653             {
11654               EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
11655               parse_error_context 
11656                 (wfl_operator, "`catch' not reached because of the catch "
11657                  "clause at line %d", EXPR_WFL_LINENO (sub_current));
11658               unreachable = error_found = 1;
11659               break;
11660             }
11661         }
11662       /* Complete the catch clause block */
11663       catch_block = java_complete_tree (TREE_OPERAND (current, 0));
11664       if (catch_block == error_mark_node)
11665         {
11666           error_found = 1;
11667           continue;
11668         }
11669       if (CAN_COMPLETE_NORMALLY (catch_block))
11670         CAN_COMPLETE_NORMALLY (node) = 1;
11671       TREE_OPERAND (current, 0) = catch_block;
11672
11673       if (unreachable)
11674         continue;
11675
11676       /* Things to do here: the exception must be thrown */
11677
11678       /* Link this type to the caught type list */
11679       caught_type_list = tree_cons (NULL_TREE, carg_type, caught_type_list);
11680     }
11681
11682   PUSH_EXCEPTIONS (caught_type_list);
11683   if ((try = java_complete_tree (try)) == error_mark_node)
11684     error_found = 1;
11685   if (CAN_COMPLETE_NORMALLY (try))
11686     CAN_COMPLETE_NORMALLY (node) = 1;
11687   POP_EXCEPTIONS ();
11688
11689   /* Verification ends here */
11690   if (error_found) 
11691     return error_mark_node;
11692
11693   TREE_OPERAND (node, 0) = try;
11694   TREE_OPERAND (node, 1) = catch;
11695   TREE_TYPE (node) = void_type_node;
11696   return node;
11697 }
11698
11699 /* 14.17 The synchronized Statement */
11700
11701 static tree
11702 patch_synchronized_statement (node, wfl_op1)
11703     tree node, wfl_op1;
11704 {
11705   tree expr = java_complete_tree (TREE_OPERAND (node, 0));
11706   tree block = TREE_OPERAND (node, 1);
11707
11708   tree enter, exit, expr_decl, assignment;
11709
11710   if (expr == error_mark_node)
11711     {
11712       block = java_complete_tree (block);
11713       return expr;
11714     }
11715
11716   /* The TYPE of expr must be a reference type */
11717   if (!JREFERENCE_TYPE_P (TREE_TYPE (expr)))
11718     {
11719       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
11720       parse_error_context (wfl_operator, "Incompatible type for `synchronized'"
11721                            ". Can't convert `%s' to `java.lang.Object'",
11722                            lang_printable_name (TREE_TYPE (expr), 0));
11723       return error_mark_node;
11724     }
11725
11726   if (flag_emit_xref)
11727     {
11728       TREE_OPERAND (node, 0) = expr;
11729       TREE_OPERAND (node, 1) = java_complete_tree (block);
11730       CAN_COMPLETE_NORMALLY (node) = 1;
11731       return node;
11732     }
11733
11734   /* Generate a try-finally for the synchronized statement, except
11735      that the handler that catches all throw exception calls
11736      _Jv_MonitorExit and then rethrow the exception.
11737      The synchronized statement is then implemented as:
11738      TRY 
11739        {
11740          _Jv_MonitorEnter (expression)
11741          synchronized_block
11742          _Jv_MonitorExit (expression)
11743        }
11744      CATCH_ALL
11745        {
11746          e = _Jv_exception_info ();
11747          _Jv_MonitorExit (expression)
11748          Throw (e);
11749        } */
11750
11751   expr_decl = build_decl (VAR_DECL, generate_name (), TREE_TYPE (expr));
11752   BUILD_MONITOR_ENTER (enter, expr_decl);
11753   BUILD_MONITOR_EXIT (exit, expr_decl);
11754   CAN_COMPLETE_NORMALLY (enter) = 1;
11755   CAN_COMPLETE_NORMALLY (exit) = 1;
11756   assignment = build (MODIFY_EXPR, NULL_TREE, expr_decl, expr);
11757   TREE_SIDE_EFFECTS (assignment) = 1;
11758   node = build1 (CLEANUP_POINT_EXPR, NULL_TREE,
11759                  build (COMPOUND_EXPR, NULL_TREE,
11760                         build (WITH_CLEANUP_EXPR, NULL_TREE,
11761                                build (COMPOUND_EXPR, NULL_TREE,
11762                                       assignment, enter),
11763                                NULL_TREE, exit),
11764                         block));
11765   node = build_expr_block (node, expr_decl);
11766
11767   return java_complete_tree (node);
11768 }
11769
11770 /* 14.16 The throw Statement */
11771
11772 static tree
11773 patch_throw_statement (node, wfl_op1)
11774     tree node, wfl_op1;
11775 {
11776   tree expr = TREE_OPERAND (node, 0);
11777   tree type = TREE_TYPE (expr);
11778   int unchecked_ok = 0, tryblock_throws_ok = 0;
11779
11780   /* Thrown expression must be assignable to java.lang.Throwable */
11781   if (!try_reference_assignconv (throwable_type_node, expr))
11782     {
11783       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
11784       parse_error_context (wfl_operator, "Can't throw `%s'; it must be a "
11785                            "subclass of class `java.lang.Throwable'",
11786                            lang_printable_name (type, 0));
11787       /* If the thrown expression was a reference, we further the
11788          compile-time check. */
11789       if (!JREFERENCE_TYPE_P (type))
11790         return error_mark_node;
11791     }
11792
11793   /* At least one of the following must be true */
11794
11795   /* The type of the throw expression is a not checked exception,
11796      i.e. is a unchecked expression. */
11797   unchecked_ok = IS_UNCHECKED_EXCEPTION_P (TREE_TYPE (type));
11798
11799   /* Throw is contained in a try statement and at least one catch
11800      clause can receive the thrown expression or the current method is
11801      declared to throw such an exception. Or, the throw statement is
11802      contained in a method or constructor declaration and the type of
11803      the Expression is assignable to at least one type listed in the
11804      throws clause the declaration. */
11805   SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
11806   if (!unchecked_ok)
11807     tryblock_throws_ok = check_thrown_exceptions_do (TREE_TYPE (expr));
11808   if (!(unchecked_ok || tryblock_throws_ok))
11809     {
11810       /* If there is a surrounding try block that has no matching
11811          clatch clause, report it first. A surrounding try block exits
11812          only if there is something after the list of checked
11813          exception thrown by the current function (if any). */
11814       if (IN_TRY_BLOCK_P ())
11815         parse_error_context (wfl_operator, "Checked exception `%s' can't be "
11816                              "caught by any of the catch clause(s) "
11817                              "of the surrounding `try' block",
11818                              lang_printable_name (type, 0));
11819       /* If we have no surrounding try statement and the method doesn't have
11820          any throws, report it now. FIXME */
11821
11822       /* We report that the exception can't be throw from a try block
11823          in all circumstances but when the `throw' is inside a static
11824          block. */
11825       else if (!EXCEPTIONS_P (currently_caught_type_list) 
11826                && !tryblock_throws_ok)
11827         {
11828           if (IS_CLINIT (current_function_decl))
11829             parse_error_context (wfl_operator, "Checked exception `%s' can't "
11830                                  "be thrown in initializer",
11831                                  lang_printable_name (type, 0));
11832           else
11833             parse_error_context (wfl_operator, "Checked exception `%s' isn't "
11834                                  "thrown from a `try' block", 
11835                                  lang_printable_name (type, 0));
11836         }
11837       /* Otherwise, the current method doesn't have the appropriate
11838          throws declaration */
11839       else
11840         parse_error_context (wfl_operator, "Checked exception `%s' doesn't "
11841                              "match any of current method's `throws' "
11842                              "declaration(s)", 
11843                              lang_printable_name (type, 0));
11844       return error_mark_node;
11845     }
11846
11847   if (! flag_emit_class_files && ! flag_emit_xref)
11848     BUILD_THROW (node, expr);
11849
11850   /* If doing xrefs, keep the location where the `throw' was seen. */
11851   if (flag_emit_xref)
11852     EXPR_WFL_LINECOL (node) = EXPR_WFL_LINECOL (wfl_op1);
11853   return node;
11854 }
11855
11856 /* Check that exception said to be thrown by method DECL can be
11857    effectively caught from where DECL is invoked.  */
11858
11859 static void
11860 check_thrown_exceptions (location, decl)
11861      int location;
11862      tree decl;
11863 {
11864   tree throws;
11865   /* For all the unchecked exceptions thrown by DECL */
11866   for (throws = DECL_FUNCTION_THROWS (decl); throws; 
11867        throws = TREE_CHAIN (throws)) 
11868     if (!check_thrown_exceptions_do (TREE_VALUE (throws)))
11869       {
11870 #if 1
11871         /* Temporary hack to suppresses errors about cloning arrays. FIXME */
11872         if (DECL_NAME (decl) == get_identifier ("clone"))
11873           continue;
11874 #endif
11875         EXPR_WFL_LINECOL (wfl_operator) = location;
11876         if (DECL_NAME (current_function_decl) == finit_identifier_node)
11877           parse_error_context
11878             (wfl_operator, "Exception `%s' can't be thrown in initializer",
11879              lang_printable_name (TREE_VALUE (throws), 0));
11880         else 
11881           {
11882             parse_error_context 
11883               (wfl_operator, "Exception `%s' must be caught, or it must be "
11884                "declared in the `throws' clause of `%s'", 
11885                lang_printable_name (TREE_VALUE (throws), 0),
11886                (DECL_NAME (current_function_decl) == init_identifier_node ?
11887                 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))) :
11888                 IDENTIFIER_POINTER (DECL_NAME (current_function_decl))));
11889           }
11890       }
11891 }
11892
11893 /* Return 1 if checked EXCEPTION is caught at the current nesting level of
11894    try-catch blocks, OR is listed in the `throws' clause of the
11895    current method.  */
11896
11897 static int
11898 check_thrown_exceptions_do (exception)
11899      tree exception;
11900 {
11901   tree list = currently_caught_type_list;
11902   resolve_and_layout (exception, NULL_TREE);
11903   /* First, all the nested try-catch-finally at that stage. The
11904      last element contains `throws' clause exceptions, if any. */
11905   if (IS_UNCHECKED_EXCEPTION_P (exception))
11906     return 1;
11907   while (list)
11908     {
11909       tree caught;
11910       for (caught = TREE_VALUE (list); caught; caught = TREE_CHAIN (caught))
11911         if (valid_ref_assignconv_cast_p (exception, TREE_VALUE (caught), 0))
11912           return 1;
11913       list = TREE_CHAIN (list);
11914     }
11915   return 0;
11916 }
11917
11918 static void
11919 purge_unchecked_exceptions (mdecl)
11920      tree mdecl;
11921 {
11922   tree throws = DECL_FUNCTION_THROWS (mdecl);
11923   tree new = NULL_TREE;
11924
11925   while (throws)
11926     {
11927       tree next = TREE_CHAIN (throws);
11928       if (!IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (throws)))
11929         {
11930           TREE_CHAIN (throws) = new;
11931           new = throws;
11932         }
11933       throws = next;
11934     }
11935   /* List is inverted here, but it doesn't matter */
11936   DECL_FUNCTION_THROWS (mdecl) = new;
11937 }
11938
11939 /* 15.24 Conditional Operator ?: */
11940
11941 static tree
11942 patch_conditional_expr (node, wfl_cond, wfl_op1)
11943      tree node, wfl_cond, wfl_op1;
11944 {
11945   tree cond = TREE_OPERAND (node, 0);
11946   tree op1 = TREE_OPERAND (node, 1);
11947   tree op2 = TREE_OPERAND (node, 2);
11948   tree resulting_type = NULL_TREE;
11949   tree t1, t2, patched;
11950   int error_found = 0;
11951
11952   /* Operands of ?: might be StringBuffers crafted as a result of a
11953      string concatenation. Obtain a descent operand here.  */
11954   if ((patched = patch_string (op1)))
11955     TREE_OPERAND (node, 1) = op1 = patched;
11956   if ((patched = patch_string (op2)))
11957     TREE_OPERAND (node, 2) = op2 = patched;
11958
11959   t1 = TREE_TYPE (op1);
11960   t2 = TREE_TYPE (op2);
11961
11962   /* The first expression must be a boolean */
11963   if (TREE_TYPE (cond) != boolean_type_node)
11964     {
11965       SET_WFL_OPERATOR (wfl_operator, node, wfl_cond);
11966       parse_error_context (wfl_operator, "Incompatible type for `?:'. Can't "
11967                            "convert `%s' to `boolean'",
11968                            lang_printable_name (TREE_TYPE (cond), 0));
11969       error_found = 1;
11970     }
11971
11972   /* Second and third can be numeric, boolean (i.e. primitive),
11973      references or null. Anything else results in an error */
11974   if (!((JNUMERIC_TYPE_P (t1) && JNUMERIC_TYPE_P (t2))
11975         || ((JREFERENCE_TYPE_P (t1) || op1 == null_pointer_node) 
11976             && (JREFERENCE_TYPE_P (t2) || op2 == null_pointer_node))
11977         || (t1 == boolean_type_node && t2 == boolean_type_node)))
11978     error_found = 1;
11979
11980   /* Determine the type of the conditional expression. Same types are
11981      easy to deal with */
11982   else if (t1 == t2)
11983     resulting_type = t1;
11984
11985   /* There are different rules for numeric types */
11986   else if (JNUMERIC_TYPE_P (t1))
11987     {
11988       /* if byte/short found, the resulting type is short */
11989       if ((t1 == byte_type_node && t2 == short_type_node)
11990           || (t1 == short_type_node && t2 == byte_type_node))
11991         resulting_type = short_type_node;
11992
11993       /* If t1 is a constant int and t2 is of type byte, short or char
11994          and t1's value fits in t2, then the resulting type is t2 */
11995       else if ((t1 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 1)))
11996           && JBSC_TYPE_P (t2) && int_fits_type_p (TREE_OPERAND (node, 1), t2))
11997         resulting_type = t2;
11998
11999       /* If t2 is a constant int and t1 is of type byte, short or char
12000          and t2's value fits in t1, then the resulting type is t1 */
12001       else if ((t2 == int_type_node && TREE_CONSTANT (TREE_OPERAND (node, 2)))
12002           && JBSC_TYPE_P (t1) && int_fits_type_p (TREE_OPERAND (node, 2), t1))
12003         resulting_type = t1;
12004
12005       /* Otherwise, binary numeric promotion is applied and the
12006          resulting type is the promoted type of operand 1 and 2 */
12007       else 
12008         resulting_type = binary_numeric_promotion (t1, t2, 
12009                                                    &TREE_OPERAND (node, 1), 
12010                                                    &TREE_OPERAND (node, 2));
12011     }
12012
12013   /* Cases of a reference and a null type */
12014   else if (JREFERENCE_TYPE_P (t1) && op2 == null_pointer_node)
12015     resulting_type = t1;
12016
12017   else if (JREFERENCE_TYPE_P (t2) && op1 == null_pointer_node)
12018     resulting_type = t2;
12019
12020   /* Last case: different reference types. If a type can be converted
12021      into the other one by assignment conversion, the latter
12022      determines the type of the expression */
12023   else if ((resulting_type = try_reference_assignconv (t1, op2)))
12024     resulting_type = promote_type (t1);
12025
12026   else if ((resulting_type = try_reference_assignconv (t2, op1)))
12027     resulting_type = promote_type (t2);
12028
12029   /* If we don't have any resulting type, we're in trouble */
12030   if (!resulting_type)
12031     {
12032       char *t = xstrdup (lang_printable_name (t1, 0));
12033       SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
12034       parse_error_context (wfl_operator, "Incompatible type for `?:'. Can't "
12035                            "convert `%s' to `%s'", t,
12036                            lang_printable_name (t2, 0));
12037       free (t);
12038       error_found = 1;
12039     }
12040
12041   if (error_found)
12042     {
12043       TREE_TYPE (node) = error_mark_node;
12044       return error_mark_node;
12045     }
12046
12047   TREE_TYPE (node) = resulting_type;
12048   TREE_SET_CODE (node, COND_EXPR);
12049   CAN_COMPLETE_NORMALLY (node) = 1;
12050   return node;
12051 }
12052
12053 /* Try to constant fold NODE.
12054    If NODE is not a constant expression, return NULL_EXPR.
12055    CONTEXT is a static final VAR_DECL whose initializer we are folding. */
12056
12057 static tree
12058 fold_constant_for_init (node, context)
12059      tree node;
12060      tree context;
12061 {
12062   tree op0, op1, val;
12063   enum tree_code code = TREE_CODE (node);
12064
12065   if (code == STRING_CST)
12066     return node;
12067
12068   if (code == INTEGER_CST || code == REAL_CST)
12069     return convert (TREE_TYPE (context), node);
12070   if (TREE_TYPE (node) != NULL_TREE && code != VAR_DECL && code != FIELD_DECL)
12071     return NULL_TREE;
12072
12073   switch (code)
12074     {
12075     case PLUS_EXPR:
12076     case MINUS_EXPR:
12077     case MULT_EXPR:
12078     case TRUNC_MOD_EXPR:
12079     case RDIV_EXPR:
12080     case LSHIFT_EXPR:
12081     case RSHIFT_EXPR:
12082     case URSHIFT_EXPR:
12083     case BIT_AND_EXPR:
12084     case BIT_XOR_EXPR:
12085     case BIT_IOR_EXPR:
12086     case TRUTH_ANDIF_EXPR:
12087     case TRUTH_ORIF_EXPR:
12088     case EQ_EXPR: 
12089     case NE_EXPR:
12090     case GT_EXPR:
12091     case GE_EXPR:
12092     case LT_EXPR:
12093     case LE_EXPR:
12094       op0 = TREE_OPERAND (node, 0);
12095       op1 = TREE_OPERAND (node, 1);
12096       val = fold_constant_for_init (op0, context);
12097       if (val == NULL_TREE || ! TREE_CONSTANT (val))
12098         return NULL_TREE;
12099       TREE_OPERAND (node, 0) = val;
12100       val = fold_constant_for_init (op1, context);
12101       if (val == NULL_TREE || ! TREE_CONSTANT (val))
12102         return NULL_TREE;
12103       TREE_OPERAND (node, 1) = val;
12104       return patch_binop (node, op0, op1);
12105
12106     case UNARY_PLUS_EXPR:
12107     case NEGATE_EXPR:
12108     case TRUTH_NOT_EXPR:
12109     case BIT_NOT_EXPR:
12110     case CONVERT_EXPR:
12111       op0 = TREE_OPERAND (node, 0);
12112       val = fold_constant_for_init (op0, context);
12113       if (val == NULL_TREE || ! TREE_CONSTANT (val))
12114         return NULL_TREE;
12115       TREE_OPERAND (node, 0) = val;
12116       return patch_unaryop (node, op0);
12117       break;
12118
12119     case COND_EXPR:
12120       val = fold_constant_for_init (TREE_OPERAND (node, 0), context);
12121       if (val == NULL_TREE || ! TREE_CONSTANT (val))
12122         return NULL_TREE;
12123       TREE_OPERAND (node, 0) = val;
12124       val = fold_constant_for_init (TREE_OPERAND (node, 1), context);
12125       if (val == NULL_TREE || ! TREE_CONSTANT (val))
12126         return NULL_TREE;
12127       TREE_OPERAND (node, 1) = val;
12128       val = fold_constant_for_init (TREE_OPERAND (node, 2), context);
12129       if (val == NULL_TREE || ! TREE_CONSTANT (val))
12130         return NULL_TREE;
12131       TREE_OPERAND (node, 2) = val;
12132       return integer_zerop (TREE_OPERAND (node, 0)) ? TREE_OPERAND (node, 1)
12133         : TREE_OPERAND (node, 2);
12134
12135     case VAR_DECL:
12136     case FIELD_DECL:
12137       if (! FIELD_FINAL (node)
12138           || DECL_INITIAL (node) == NULL_TREE)
12139         return NULL_TREE;
12140       val = DECL_INITIAL (node);
12141       /* Guard against infinite recursion. */
12142       DECL_INITIAL (node) = NULL_TREE;
12143       val = fold_constant_for_init (val, node);
12144       DECL_INITIAL (node) = val;
12145       return val;
12146
12147     case EXPR_WITH_FILE_LOCATION:
12148       /* Compare java_complete_tree and resolve_expression_name. */
12149       if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
12150           || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
12151         {
12152           tree name = EXPR_WFL_NODE (node);
12153           tree decl;
12154           if (PRIMARY_P (node))
12155             return NULL_TREE;
12156           else if (! QUALIFIED_P (name))
12157             {
12158               decl = lookup_field_wrapper (DECL_CONTEXT (context), name);
12159               if (decl == NULL_TREE 
12160                   || (! FIELD_STATIC (decl) && ! FIELD_FINAL (decl)))
12161                 return NULL_TREE;
12162               return fold_constant_for_init (decl, decl);
12163             }
12164           else
12165             {
12166               /* Wait until the USE_COMPONENT_REF re-write.  FIXME. */
12167               qualify_ambiguous_name (node);
12168               if (resolve_field_access (node, &decl, NULL)
12169                   && decl != NULL_TREE)
12170                 return fold_constant_for_init (decl, decl);
12171               return NULL_TREE;
12172             }
12173         }
12174       else
12175         {
12176           op0 = TREE_OPERAND (node, 0);
12177           val = fold_constant_for_init (op0, context);
12178           if (val == NULL_TREE || ! TREE_CONSTANT (val))
12179             return NULL_TREE;
12180           TREE_OPERAND (node, 0) = val;
12181           return val;
12182         }
12183
12184 #ifdef USE_COMPONENT_REF
12185     case IDENTIFIER:
12186     case COMPONENT_REF:
12187       ?;
12188 #endif
12189
12190     default:
12191       return NULL_TREE;
12192     }
12193 }
12194
12195 #ifdef USE_COMPONENT_REF
12196 /* Context is 'T' for TypeName, 'P' for PackageName,
12197    'M' for MethodName, 'E' for ExpressionName, and 'A' for AmbiguousName. */
12198
12199 tree
12200 resolve_simple_name (name, context)
12201      tree name;
12202      int context;
12203 {
12204 }
12205
12206 tree
12207 resolve_qualified_name (name, context)
12208      tree name;
12209      int context;
12210 {
12211 }
12212 #endif