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