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