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