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