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