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