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