OSDN Git Service

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