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