OSDN Git Service

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