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)
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
23 Java and all Java-based marks are trademarks or registered trademarks
24 of Sun Microsystems, Inc. in the United States and other countries.
25 The Free Software Foundation is independent of Sun Microsystems, Inc. */
27 /* This file parses java source code and issues a tree node image
28 suitable for code generation (byte code and targeted CPU assembly
31 The grammar conforms to the Java grammar described in "The Java(TM)
32 Language Specification. J. Gosling, B. Joy, G. Steele. Addison Wesley
33 1996, ISBN 0-201-63451-1"
35 The following modifications were brought to the original grammar:
37 method_body: added the rule '| block SC_TK'
38 constructor_declaration: added two rules to accept SC_TK.
39 static_initializer: added the rule 'static block SC_TK'.
41 Note: All the extra rules described above should go away when the
42 empty_statement rule will work.
44 statement_nsi: 'nsi' should be read no_short_if.
46 Some rules have been modified to support JDK1.1 inner classes
47 definitions and other extensions. */
54 #include <setjmp.h> /* set_float_handler argument uses it */
67 #include "java-tree.h"
73 /* Number of error found so far. */
75 /* Number of warning found so far. */
76 int java_warning_count;
78 /* The current parser context */
79 static struct parser_ctxt *ctxp;
81 /* binop_lookup maps token to tree_code. It is used where binary
82 operations are involved and required by the parser. RDIV_EXPR
83 covers both integral/floating point division. The code is changed
84 once the type of both operator is worked out. */
86 static enum tree_code binop_lookup[19] =
88 PLUS_EXPR, MINUS_EXPR, MULT_EXPR, RDIV_EXPR, TRUNC_MOD_EXPR,
89 LSHIFT_EXPR, RSHIFT_EXPR, URSHIFT_EXPR,
90 BIT_AND_EXPR, BIT_XOR_EXPR, BIT_IOR_EXPR,
91 TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR,
92 EQ_EXPR, NE_EXPR, GT_EXPR, GE_EXPR, LT_EXPR, LE_EXPR,
94 #define BINOP_LOOKUP(VALUE) \
95 binop_lookup [((VALUE) - PLUS_TK)% \
96 (sizeof (binop_lookup) / sizeof (binop_lookup[0]))]
98 /* Fake WFL used to report error message. It is initialized once if
99 needed and reused with it's location information is overriden. */
100 static tree wfl_operator = NULL_TREE;
102 /* The "$L" identifier we use to create labels. */
103 static tree label_id = NULL_TREE;
105 /* The "StringBuffer" identifier used for the String `+' operator. */
106 static tree wfl_string_buffer = NULL_TREE;
108 /* The "append" identifier used for String `+' operator. */
109 static tree wfl_append = NULL_TREE;
111 /* The "toString" identifier used for String `+' operator. */
112 static tree wfl_to_string = NULL_TREE;
127 /* Things defined here have to match the order of what's in the
128 binop_lookup table. */
130 %token PLUS_TK MINUS_TK MULT_TK DIV_TK REM_TK
131 %token LS_TK SRS_TK ZRS_TK
132 %token AND_TK XOR_TK OR_TK
133 %token BOOL_AND_TK BOOL_OR_TK
134 %token EQ_TK NEQ_TK GT_TK GTE_TK LT_TK LTE_TK
136 /* This maps to the same binop_lookup entry than the token above */
138 %token PLUS_ASSIGN_TK MINUS_ASSIGN_TK MULT_ASSIGN_TK DIV_ASSIGN_TK
140 %token LS_ASSIGN_TK SRS_ASSIGN_TK ZRS_ASSIGN_TK
141 %token AND_ASSIGN_TK XOR_ASSIGN_TK OR_ASSIGN_TK
144 /* Modifier TOKEN have to be kept in this order. Don't scramble it */
146 %token PUBLIC_TK PRIVATE_TK PROTECTED_TK
147 %token STATIC_TK FINAL_TK SYNCHRONIZED_TK
148 %token VOLATILE_TK TRANSIENT_TK NATIVE_TK
149 %token PAD_TK ABSTRACT_TK MODIFIER_TK
151 /* Keep those two in order, too */
152 %token DECR_TK INCR_TK
154 /* From now one, things can be in any order */
156 %token DEFAULT_TK IF_TK THROW_TK
157 %token BOOLEAN_TK DO_TK IMPLEMENTS_TK
158 %token THROWS_TK BREAK_TK IMPORT_TK
159 %token ELSE_TK INSTANCEOF_TK RETURN_TK
160 %token VOID_TK CATCH_TK INTERFACE_TK
161 %token CASE_TK EXTENDS_TK FINALLY_TK
162 %token SUPER_TK WHILE_TK CLASS_TK
163 %token SWITCH_TK CONST_TK TRY_TK
164 %token FOR_TK NEW_TK CONTINUE_TK
165 %token GOTO_TK PACKAGE_TK THIS_TK
167 %token BYTE_TK SHORT_TK INT_TK LONG_TK
168 %token CHAR_TK INTEGRAL_TK
170 %token FLOAT_TK DOUBLE_TK FP_TK
174 %token REL_QM_TK REL_CL_TK NOT_TK NEG_TK
176 %token ASSIGN_ANY_TK ASSIGN_TK
177 %token OP_TK CP_TK OCB_TK CCB_TK OSB_TK CSB_TK SC_TK C_TK DOT_TK
179 %token STRING_LIT_TK CHAR_LIT_TK INT_LIT_TK FP_LIT_TK
180 %token TRUE_TK FALSE_TK BOOL_LIT_TK NULL_TK
182 %type <value> modifiers MODIFIER_TK
184 %type <node> super ID_TK identifier
185 %type <node> name simple_name qualified_name
186 %type <node> class_declaration type_declaration compilation_unit
187 field_declaration method_declaration extends_interfaces
188 interfaces interface_type_list
189 interface_declaration class_member_declaration
190 import_declarations package_declaration
191 type_declarations interface_body
192 interface_member_declaration constant_declaration
193 interface_member_declarations interface_type
194 abstract_method_declaration interface_type_list
195 %type <node> class_body_declaration class_member_declaration
196 static_initializer constructor_declaration block
197 %type <node> class_body_declarations
198 %type <node> class_or_interface_type class_type class_type_list
199 constructor_declarator explicit_constructor_invocation
200 %type <node> dim_expr dim_exprs this_or_super throws
202 %type <node> variable_declarator_id variable_declarator
203 variable_declarators variable_initializer
204 variable_initializers
206 %type <node> class_body
207 %type <node> block_statement local_variable_declaration_statement
208 block_statements local_variable_declaration
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
233 switch_statement synchronized_statement throw_statement
234 try_statement switch_expression switch_block
235 switch_block_statement_groups switch_labels
236 switch_block_statement_group switch_label
237 group_of_labels catches catch_clause
238 catch_clause_parameter finally
239 %type <node> return_statement break_statement continue_statement
241 %type <operator> ASSIGN_TK MULT_ASSIGN_TK DIV_ASSIGN_TK
242 %type <operator> REM_ASSIGN_TK PLUS_ASSIGN_TK MINUS_ASSIGN_TK
243 %type <operator> LS_ASSIGN_TK SRS_ASSIGN_TK ZRS_ASSIGN_TK
244 %type <operator> AND_ASSIGN_TK XOR_ASSIGN_TK OR_ASSIGN_TK
245 %type <operator> ASSIGN_ANY_TK assignment_operator
246 %token <operator> EQ_TK GTE_TK ZRS_TK SRS_TK GT_TK LTE_TK LS_TK
247 %token <operator> BOOL_AND_TK AND_TK BOOL_OR_TK OR_TK INCR_TK PLUS_TK
248 %token <operator> DECR_TK MINUS_TK MULT_TK DIV_TK XOR_TK REM_TK NEQ_TK
249 %token <operator> NEG_TK REL_QM_TK REL_CL_TK NOT_TK LT_TK
250 %token <operator> OP_TK OSB_TK DOT_TK THROW_TK
251 %type <operator> THIS_TK SUPER_TK RETURN_TK BREAK_TK CONTINUE_TK
252 %type <operator> CASE_TK DEFAULT_TK TRY_TK CATCH_TK SYNCHRONIZED_TK
254 %type <node> method_body
256 %type <node> literal INT_LIT_TK FP_LIT_TK BOOL_LIT_TK CHAR_LIT_TK
257 STRING_LIT_TK NULL_TK VOID_TK
259 %type <node> IF_TK WHILE_TK FOR_TK
261 %type <node> formal_parameter_list formal_parameter
262 method_declarator method_header
264 %type <node> primitive_type reference_type type
265 BOOLEAN_TK INTEGRAL_TK FP_TK
268 /* 19.2 Production from 2.3: The Syntactic Grammar */
274 /* 19.3 Productions from 3: Lexical structure */
284 /* 19.4 Productions from 4: Types, Values and Variables */
297 class_or_interface_type
301 class_or_interface_type:
306 class_or_interface_type /* Default rule */
310 class_or_interface_type
314 primitive_type OSB_TK CSB_TK
316 $$ = build_java_array_type ($1, -1);
317 CLASS_LOADED_P ($$) = 1;
320 { $$ = build_unresolved_array_type ($1); }
321 | array_type OSB_TK CSB_TK
322 { $$ = build_unresolved_array_type ($1); }
323 | primitive_type OSB_TK error
324 {RULE ("']' expected"); RECOVER;}
325 | array_type OSB_TK error
326 {RULE ("']' expected"); RECOVER;}
329 /* 19.5 Productions from 6: Names */
331 simple_name /* Default rule */
332 | qualified_name /* Default rule */
336 identifier /* Default rule */
340 name DOT_TK identifier
341 { $$ = make_qualified_name ($1, $3, $2.location); }
348 /* 19.6: Production from 7: Packages */
351 | package_declaration
352 | import_declarations
354 | package_declaration import_declarations
355 | package_declaration type_declarations
356 | import_declarations type_declarations
357 | package_declaration import_declarations type_declarations
365 | import_declarations import_declaration
373 | type_declarations type_declaration
377 PACKAGE_TK name SC_TK
378 { ctxp->package = EXPR_WFL_NODE ($2); }
380 {yyerror ("Missing name"); RECOVER;}
381 | PACKAGE_TK name error
382 {yyerror ("';' expected"); RECOVER;}
386 single_type_import_declaration
387 | type_import_on_demand_declaration
390 single_type_import_declaration:
393 tree name = EXPR_WFL_NODE ($2), node, last_name;
394 int i = IDENTIFIER_LENGTH (name)-1;
395 char *last = &IDENTIFIER_POINTER (name)[i];
396 while (last != IDENTIFIER_POINTER (name))
402 last_name = get_identifier (++last);
403 if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (last_name))
405 tree err = find_name_in_single_imports (last_name);
406 if (err && err != name)
408 ($2, "Ambiguous class: `%s' and `%s'",
409 IDENTIFIER_POINTER (name),
410 IDENTIFIER_POINTER (err));
414 IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (last_name) = 1;
415 node = build_tree_list ($2, last_name);
416 TREE_CHAIN (node) = ctxp->import_list;
417 ctxp->import_list = node;
421 {yyerror ("Missing name"); RECOVER;}
422 | IMPORT_TK name error
423 {yyerror ("';' expected"); RECOVER;}
426 type_import_on_demand_declaration:
427 IMPORT_TK name DOT_TK MULT_TK SC_TK
429 tree name = EXPR_WFL_NODE ($2);
430 tree node = build_tree_list ($2, NULL_TREE);
431 if (!IS_AN_IMPORT_ON_DEMAND_P (name))
433 read_import_dir ($2);
434 IS_AN_IMPORT_ON_DEMAND_P (name) = 1;
436 TREE_CHAIN (node) = ctxp->import_demand_list;
437 ctxp->import_demand_list = node;
439 | IMPORT_TK name DOT_TK error
440 {yyerror ("'*' expected"); RECOVER;}
441 | IMPORT_TK name DOT_TK MULT_TK error
442 {yyerror ("';' expected"); RECOVER;}
448 maybe_generate_clinit ();
451 | interface_declaration
457 yyerror ("Class or interface declaration expected");
461 /* 19.7 Shortened from the original:
462 modifiers: modifier | modifiers modifier
463 modifier: any of public... */
469 | modifiers MODIFIER_TK
474 (ctxp->modifier_ctx [$2], "Modifier `%s' declared twice",
475 java_accstring_lookup (acc));
483 /* 19.8.1 Production from $8.1: Class Declaration */
485 modifiers CLASS_TK identifier super interfaces
486 { create_class ($1, $3, $4, $5); }
491 | CLASS_TK identifier super interfaces
492 { create_class (0, $2, $3, $4); }
497 | modifiers CLASS_TK error
498 {yyerror ("Missing class name"); RECOVER;}
500 {yyerror ("Missing class name"); RECOVER;}
501 | CLASS_TK identifier error
502 {if (!ctxp->class_err) yyerror ("'{' expected"); DRECOVER(class1);}
503 | modifiers CLASS_TK identifier error
504 {if (!ctxp->class_err) yyerror ("'{' expected"); RECOVER;}
509 | EXTENDS_TK class_type
511 | EXTENDS_TK class_type error
512 {yyerror ("'{' expected"); ctxp->class_err=1;}
514 {yyerror ("Missing super class name"); ctxp->class_err=1;}
519 | IMPLEMENTS_TK interface_type_list
521 | IMPLEMENTS_TK error
524 yyerror ("Missing interface name");
531 ctxp->interface_number = 1;
532 $$ = build_tree_list ($1, NULL_TREE);
534 | interface_type_list C_TK interface_type
536 ctxp->interface_number++;
537 $$ = chainon ($1, build_tree_list ($3, NULL_TREE));
539 | interface_type_list C_TK error
540 {yyerror ("Missing interface name"); RECOVER;}
545 { $$ = ctxp->current_parsed_class; }
546 | OCB_TK class_body_declarations CCB_TK
547 { $$ = ctxp->current_parsed_class; }
550 class_body_declarations:
551 class_body_declaration
552 | class_body_declarations class_body_declaration
555 class_body_declaration:
556 class_member_declaration
558 | constructor_declaration
559 | block /* Added, JDK1.1, instance initializer */
560 { $$ = parse_jdk1_1_error ("instance initializer"); }
563 class_member_declaration:
566 | class_declaration /* Added, JDK1.1 inner classes */
567 { $$ = parse_jdk1_1_error ("inner classe declaration"); }
568 | interface_declaration /* Added, JDK1.1 inner classes */
569 { $$ = parse_jdk1_1_error ("inner interface declaration"); }
572 /* 19.8.2 Productions from 8.3: Field Declarations */
574 type variable_declarators SC_TK
575 { register_fields (0, $1, $2); }
576 | modifiers type variable_declarators SC_TK
579 ("Illegal modifier `%s' for field declaration",
580 $1, FIELD_MODIFIERS);
581 check_modifiers_consistency ($1);
582 register_fields ($1, $2, $3);
586 variable_declarators:
587 /* Should we use build_decl_list () instead ? FIXME */
588 variable_declarator /* Default rule */
589 | variable_declarators C_TK variable_declarator
590 { $$ = chainon ($1, $3); }
591 | variable_declarators C_TK error
592 {yyerror ("Missing term"); RECOVER;}
596 variable_declarator_id
597 { $$ = build_tree_list ($1, NULL_TREE); }
598 | variable_declarator_id ASSIGN_TK variable_initializer
600 if (java_error_count)
603 ($1, build_assignment ($2.token, $2.location, $1, $3));
605 | variable_declarator_id ASSIGN_TK error
607 yyerror ("Missing variable initializer");
608 $$ = build_tree_list ($1, NULL_TREE);
611 | variable_declarator_id ASSIGN_TK variable_initializer error
613 yyerror ("';' expected");
614 $$ = build_tree_list ($1, NULL_TREE);
619 variable_declarator_id:
621 | variable_declarator_id OSB_TK CSB_TK
623 $$ = NULL; /* FIXME */
626 {yyerror ("Invalid declaration"); DRECOVER(vdi);}
627 | variable_declarator_id OSB_TK error
628 {yyerror ("']' expected"); DRECOVER(vdi);}
629 | variable_declarator_id CSB_TK error
630 {yyerror ("Unbalanced ']'"); DRECOVER(vdi);}
633 variable_initializer:
639 /* 19.8.3 Productions from 8.4: Method Declarations */
643 current_function_decl = $1;
644 source_start_java_method (current_function_decl);
649 (DECL_FUNCTION_BODY (current_function_decl)) = $3;
650 maybe_absorb_scoping_blocks ();
651 exit_block (); /* Exit function's body. */
653 /* Merge last line of the function with first line,
654 directly in the function decl. It will be used to
655 emit correct debug info. */
656 DECL_SOURCE_LINE_MERGE (current_function_decl,
657 ctxp->last_ccb_indent1);
659 | method_header error
660 {YYNOT_TWICE yyerror ("'{' expected"); RECOVER;}
664 type method_declarator throws
665 { $$ = method_header (0, $1, $2, $3); }
666 | VOID_TK method_declarator throws
667 { $$ = method_header (0, void_type_node, $2, $3); }
668 | modifiers type method_declarator throws
669 { $$ = method_header ($1, $2, $3, $4); }
670 | modifiers VOID_TK method_declarator throws
671 { $$ = method_header ($1, void_type_node, $3, $4); }
674 | modifiers type error
677 {yyerror ("Identifier expected"); RECOVER;}
678 | modifiers VOID_TK error
679 {yyerror ("Identifier expected"); RECOVER;}
682 yyerror ("Invalid method declaration, return type required");
688 identifier OP_TK CP_TK
689 { $$ = method_declarator ($1, NULL_TREE); }
690 | identifier OP_TK formal_parameter_list CP_TK
691 { $$ = method_declarator ($1, $3); }
692 | method_declarator OSB_TK CSB_TK
694 /* Issue a warning here: obsolete declaration. FIXME */
695 $$ = NULL; /* FIXME */
697 | identifier OP_TK error
698 {yyerror ("')' expected"); DRECOVER(method_declarator);}
699 | method_declarator OSB_TK error
700 {yyerror ("']' expected"); RECOVER;}
703 formal_parameter_list:
706 ctxp->formal_parameter_number = 1;
708 | formal_parameter_list C_TK formal_parameter
710 ctxp->formal_parameter_number += 1;
711 $$ = chainon ($1, $3);
713 | formal_parameter_list C_TK error
714 {yyerror ("Missing formal parameter term"); RECOVER;}
718 type variable_declarator_id
720 $$ = build_tree_list ($2, $1);
722 | modifiers type variable_declarator_id /* Added, JDK1.1 final locals */
723 { $$ = parse_jdk1_1_error ("final local"); }
725 {yyerror ("Missing identifier"); RECOVER;}
726 | modifiers type error
728 SOURCE_FRONTEND_DEBUG (("Modifiers: %d", $1));
729 yyerror ("Missing identifier"); RECOVER;
735 | THROWS_TK class_type_list
738 {yyerror ("Missing class type term"); RECOVER;}
743 { $$ = build_tree_list (NULL_TREE, $1); }
744 | class_type_list C_TK class_type
745 { $$ = tree_cons (NULL_TREE, $3, $1); }
746 | class_type_list C_TK error
747 {yyerror ("Missing class type term"); RECOVER;}
754 { $$ = NULL_TREE; } /* Probably not the right thing to do. */
757 /* 19.8.4 Productions from 8.5: Static Initializers */
761 RULE ("STATIC_INITIALIZER");
763 | static block SC_TK /* Shouldn't be here. FIXME */
765 RULE ("STATIC_INITIALIZER");
769 static: /* Test lval.sub_token here */
772 SOURCE_FRONTEND_DEBUG (("Modifiers: %d", $1));
776 /* 19.8.5 Productions from 8.6: Constructor Declarations */
777 /* NOTE FOR FURTHER WORK ON CONSTRUCTORS:
778 - If a forbidded modifier is found, the the error is either the use of
779 a forbidded modifier for a constructor OR bogus attempt to declare a
780 method without having specified the return type. FIXME */
781 constructor_declaration:
782 constructor_declarator throws constructor_body
784 RULE ("CONSTRUCTOR_DECLARATION");
786 | modifiers constructor_declarator throws constructor_body
788 SOURCE_FRONTEND_DEBUG (("Modifiers: %d", $1));
789 RULE ("CONSTRUCTOR_DECLARATION (modifier)");
791 /* extra SC_TK, FIXME */
792 | constructor_declarator throws constructor_body SC_TK
794 RULE ("CONSTRUCTOR_DECLARATION");
796 /* extra SC_TK, FIXME */
797 | modifiers constructor_declarator throws constructor_body SC_TK
799 SOURCE_FRONTEND_DEBUG (("Modifiers: %d", $1));
800 RULE ("CONSTRUCTOR_DECLARATION (modifier)");
802 /* I'm not happy with the SC_TK addition. It isn't in the grammer and should
803 probably be matched by and empty statement. But it doesn't work. FIXME */
806 constructor_declarator:
807 simple_name OP_TK CP_TK
808 | simple_name OP_TK formal_parameter_list CP_TK
813 | OCB_TK explicit_constructor_invocation CCB_TK
814 | OCB_TK block_statements CCB_TK
815 | OCB_TK explicit_constructor_invocation block_statements CCB_TK
818 /* Error recovery for that rule moved down expression_statement: rule. */
819 explicit_constructor_invocation:
820 this_or_super OP_TK CP_TK SC_TK
821 | this_or_super OP_TK argument_list CP_TK SC_TK
822 /* Added, JDK1.1 inner classes. Modified because the rule
823 'primary' couldn't work. */
824 | name DOT_TK SUPER_TK OP_TK argument_list CP_TK SC_TK
825 {$$ = parse_jdk1_1_error ("explicit constructor invocation"); }
826 | name DOT_TK SUPER_TK OP_TK CP_TK SC_TK
827 {$$ = parse_jdk1_1_error ("explicit constructor invocation"); }
830 this_or_super: /* Added, simplifies error diagnostics */
833 tree wfl = build_wfl_node (this_identifier_node,
834 input_filename, 0, 0);
835 EXPR_WFL_LINECOL (wfl) = $1.location;
840 tree wfl = build_wfl_node (super_identifier_node,
841 input_filename, 0, 0);
842 EXPR_WFL_LINECOL (wfl) = $1.location;
847 /* 19.9 Productions from 9: Interfaces */
848 /* 19.9.1 Productions from 9.1: Interfaces Declarations */
849 interface_declaration:
850 INTERFACE_TK identifier
851 { create_interface (0, $2, NULL_TREE); }
856 | modifiers INTERFACE_TK identifier
857 { create_interface ($1, $3, NULL_TREE); }
862 | INTERFACE_TK identifier extends_interfaces
863 { create_interface (0, $2, $3); }
868 | modifiers INTERFACE_TK identifier extends_interfaces
869 { create_interface ($1, $3, $4); }
874 | INTERFACE_TK identifier error
875 {yyerror ("(here)'{' expected"); RECOVER;}
876 | modifiers INTERFACE_TK identifier error
877 {yyerror ("(there)'{' expected"); RECOVER;}
881 EXTENDS_TK interface_type
883 ctxp->interface_number = 1;
884 $$ = build_tree_list ($2, NULL_TREE);
886 | extends_interfaces C_TK interface_type
888 ctxp->interface_number++;
889 $$ = chainon ($1, build_tree_list ($3, NULL_TREE));
892 {yyerror ("Invalid interface type"); RECOVER;}
893 | extends_interfaces C_TK error
894 {yyerror ("Missing term"); RECOVER;}
900 | OCB_TK interface_member_declarations CCB_TK
904 interface_member_declarations:
905 interface_member_declaration
906 | interface_member_declarations interface_member_declaration
909 interface_member_declaration:
911 | abstract_method_declaration
912 | class_declaration /* Added, JDK1.1 inner classes */
913 { $$ = parse_jdk1_1_error ("inner class declaration"); }
914 | interface_declaration /* Added, JDK1.1 inner classes */
915 { $$ = parse_jdk1_1_error ("inner interface declaration"); }
918 constant_declaration:
922 abstract_method_declaration:
925 check_abstract_method_header ($1);
926 current_function_decl = NULL_TREE; /* FIXME ? */
928 | method_header error
929 {yyerror ("';' expected"); RECOVER;}
932 /* 19.10 Productions from 10: Arrays */
936 RULE ("ARRAY_INITIALIZER (empty)");
938 | OCB_TK variable_initializers CCB_TK
940 RULE ("ARRAY_INITIALIZER (variable)");
944 RULE ("ARRAY_INITIALIZER (,)");
946 | OCB_TK variable_initializers C_TK CCB_TK
948 RULE ("ARRAY_INITIALIZER (variable, ,)");
952 variable_initializers:
954 | variable_initializers C_TK variable_initializer
955 | variable_initializers C_TK error
956 {yyerror ("Missing term"); RECOVER;}
959 /* 19.11 Production from 14: Blocks and Statements */
962 { $$ = size_zero_node; }
968 maybe_absorb_scoping_blocks ();
975 | block_statements block_statement
979 local_variable_declaration_statement
981 { $$ = java_method_add_stmt (current_function_decl, $1); }
982 | class_declaration /* Added, JDK1.1 inner classes */
983 { $$ = parse_jdk1_1_error ("inner class declaration"); }
986 local_variable_declaration_statement:
987 local_variable_declaration SC_TK /* Can't catch missing ';' here */
990 local_variable_declaration:
991 type variable_declarators
992 { declare_local_variables (0, $1, $2); }
993 | modifiers type variable_declarators /* Added, JDK1.1 final locals */
994 { declare_local_variables ($1, $2, $3); }
998 statement_without_trailing_substatement
1001 | if_then_else_statement
1005 /* If the for loop is unlabeled, we must return the
1006 block it was defined it. It our last chance to
1007 get a hold on it. */
1008 if (!LOOP_HAS_LABEL_P ($$))
1014 statement_without_trailing_substatement
1015 | labeled_statement_nsi
1016 | if_then_else_statement_nsi
1017 | while_statement_nsi
1021 statement_without_trailing_substatement:
1024 | expression_statement
1028 | continue_statement
1030 | synchronized_statement
1037 { $$ = size_zero_node; }
1041 identifier REL_CL_TK
1043 $$ = build_labeled_block (EXPR_WFL_LINECOL ($1),
1044 EXPR_WFL_NODE ($1));
1046 push_labeled_block ($$);
1047 PUSH_LABELED_BLOCK ($$);
1052 label_decl statement
1054 $$ = complete_labeled_statement ($1, $2);
1055 pop_labeled_block ();
1056 POP_LABELED_BLOCK ();
1059 {yyerror ("':' expected"); RECOVER;}
1062 labeled_statement_nsi:
1063 label_decl statement_nsi
1065 $$ = complete_labeled_statement ($1, $2);
1066 pop_labeled_block ();
1067 POP_LABELED_BLOCK ();
1071 /* We concentrate here a bunch of error handling rules that we couldn't write
1072 earlier, because expression_statement catches a missing ';'. */
1073 expression_statement:
1074 statement_expression SC_TK
1076 /* We have a statement. Generate a WFL around it so
1078 $$ = build_expr_wfl ($1, input_filename, lineno, 0);
1079 /* We know we have a statement, so set the debug
1080 info to be eventually generate here. */
1081 $$ = JAVA_MAYBE_GENERATE_DEBUG_INFO ($$);
1085 if (ctxp->prevent_ese != lineno)
1086 yyerror ("Invalid expression statement");
1087 DRECOVER (expr_stmt);
1091 if (ctxp->prevent_ese != lineno)
1092 yyerror ("Invalid expression statement");
1093 DRECOVER (expr_stmt);
1097 if (ctxp->prevent_ese != lineno)
1098 yyerror ("Invalid expression statement");
1099 DRECOVER (expr_stmt);
1101 | this_or_super OP_TK error
1102 {yyerror ("')' expected"); RECOVER;}
1103 | this_or_super OP_TK CP_TK error
1104 {yyerror ("';' expected"); RECOVER;}
1105 | this_or_super OP_TK argument_list error
1106 {yyerror ("')' expected"); RECOVER;}
1107 | this_or_super OP_TK argument_list CP_TK error
1108 {yyerror ("';' expected"); RECOVER;}
1109 | name DOT_TK SUPER_TK error
1110 {yyerror ("'(' expected"); RECOVER;}
1111 | name DOT_TK SUPER_TK OP_TK error
1112 {yyerror ("')' expected"); RECOVER;}
1113 | name DOT_TK SUPER_TK OP_TK argument_list error
1114 {yyerror ("')' expected"); RECOVER;}
1115 | name DOT_TK SUPER_TK OP_TK argument_list CP_TK error
1116 {yyerror ("';' expected"); RECOVER;}
1117 | name DOT_TK SUPER_TK OP_TK CP_TK error
1118 {yyerror ("';' expected"); RECOVER;}
1121 statement_expression:
1123 | pre_increment_expression
1124 | pre_decrement_expression
1125 | post_increment_expression
1126 | post_decrement_expression
1128 | class_instance_creation_expression
1132 IF_TK OP_TK expression CP_TK statement
1133 { $$ = build_if_else_statement ($2.location, $3, $5, NULL_TREE); }
1135 {yyerror ("'(' expected"); RECOVER;}
1137 {yyerror ("Missing term"); RECOVER;}
1138 | IF_TK OP_TK expression error
1139 {yyerror ("')' expected"); RECOVER;}
1142 if_then_else_statement:
1143 IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement
1144 { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
1147 if_then_else_statement_nsi:
1148 IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement_nsi
1149 { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
1153 switch_expression switch_block
1155 TREE_OPERAND ($1, 1) = $2;
1156 $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $1);
1161 SWITCH_TK OP_TK expression CP_TK
1163 $$ = build (SWITCH_EXPR, NULL_TREE, $3, NULL_TREE);
1164 EXPR_WFL_LINECOL ($$) = $2.location;
1167 {yyerror ("'(' expected"); RECOVER;}
1168 | SWITCH_TK OP_TK error
1169 {yyerror ("Missing term or ')'"); DRECOVER(switch_statement);}
1170 | SWITCH_TK OP_TK expression CP_TK error
1171 {yyerror ("'{' expected"); RECOVER;}
1177 | OCB_TK switch_labels CCB_TK
1178 { $$ = build_tree_list ($2, NULL_TREE); }
1179 | OCB_TK switch_block_statement_groups CCB_TK
1181 | OCB_TK switch_block_statement_groups switch_labels CCB_TK
1183 /* Switch labels alone are empty switch statements */
1184 tree sl = build_tree_list ($3, NULL_TREE);
1185 TREE_CHAIN (sl) = $2;
1190 switch_block_statement_groups:
1191 switch_block_statement_group
1192 | switch_block_statement_groups switch_block_statement_group
1194 TREE_CHAIN ($2) = $1;
1199 switch_block_statement_group:
1200 group_of_labels block_statements
1201 { $$ = build_tree_list ($1, exit_block ()); }
1207 /* All statements attached to this group of cases
1208 will be stored in a block */
1215 | switch_labels switch_label
1217 TREE_CHAIN ($2) = $1;
1223 CASE_TK constant_expression REL_CL_TK
1225 $$ = build1 (CASE_EXPR, NULL_TREE, $2);
1226 EXPR_WFL_LINECOL ($$) = $1.location;
1228 | DEFAULT_TK REL_CL_TK
1230 $$ = build1 (DEFAULT_EXPR, NULL_TREE, NULL_TREE);
1231 EXPR_WFL_LINECOL ($$) = $1.location;
1234 {yyerror ("Missing or invalid constant expression"); RECOVER;}
1235 | CASE_TK constant_expression error
1236 {yyerror ("':' expected"); RECOVER;}
1238 {yyerror ("':' expected"); RECOVER;}
1242 WHILE_TK OP_TK expression CP_TK
1244 tree body = build_loop_body ($2.location, $3, 0);
1245 $$ = build_new_loop (body);
1250 while_expression statement
1251 { $$ = complete_loop_body (0, NULL_TREE, $2, 0); }
1253 {YYERROR_NOW; yyerror ("'(' expected"); RECOVER;}
1254 | WHILE_TK OP_TK error
1255 {yyerror ("Missing term and ')' expected"); RECOVER;}
1256 | WHILE_TK OP_TK expression error
1257 {yyerror ("')' expected"); RECOVER;}
1260 while_statement_nsi:
1261 while_expression statement_nsi
1262 { $$ = complete_loop_body (0, NULL_TREE, $2, 0); }
1268 tree body = build_loop_body (0, NULL_TREE, 1);
1269 $$ = build_new_loop (body);
1271 /* Need error handing here. FIXME */
1275 do_statement_begin statement WHILE_TK OP_TK expression CP_TK SC_TK
1276 { $$ = complete_loop_body ($4.location, $5, $2, 1); }
1280 for_begin SC_TK expression SC_TK for_update CP_TK statement
1281 { $$ = complete_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7);}
1282 | for_begin SC_TK SC_TK for_update CP_TK statement
1284 $$ = complete_for_loop (0, NULL_TREE, $4, $6);
1285 /* We have not condition, so we get rid of the EXIT_EXPR */
1286 LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) =
1289 | for_begin SC_TK error
1290 {yyerror ("Invalid control expression"); RECOVER;}
1291 | for_begin SC_TK expression SC_TK error
1292 {yyerror ("Invalid update expression"); RECOVER;}
1293 | for_begin SC_TK SC_TK error
1294 {yyerror ("Invalid update expression"); RECOVER;}
1298 for_begin SC_TK expression SC_TK for_update CP_TK statement_nsi
1299 { $$ = complete_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7);}
1300 | for_begin SC_TK SC_TK for_update CP_TK statement_nsi
1302 $$ = complete_for_loop (0, NULL_TREE, $4, $6);
1303 /* We have not condition, so we get rid of the EXIT_EXPR */
1304 LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) =
1312 /* This scope defined for local variable that may be
1313 defined within the scope of the for loop */
1317 {yyerror ("'(' expected"); DRECOVER(for_1);}
1318 | FOR_TK OP_TK error
1319 {yyerror ("Invalid init statement"); RECOVER;}
1325 /* We now declare the loop body. The loop is
1326 declared as a for loop. */
1327 tree body = build_loop_body (0, NULL_TREE, 0);
1328 $$ = build_new_loop (body);
1329 IS_FOR_LOOP_P ($$) = 1;
1330 /* The loop is added to the current block the for
1331 statement is defined within */
1332 java_method_add_stmt (current_function_decl, $$);
1335 for_init: /* Can be empty */
1336 { $$ = size_zero_node; }
1337 | statement_expression_list
1339 /* Init statement recorded within the previously
1340 defined block scope */
1341 $$ = java_method_add_stmt (current_function_decl, $1);
1343 | local_variable_declaration
1345 /* Local variable are recorded within the previously
1346 defined block scope */
1349 | statement_expression_list error
1350 {yyerror ("';' expected"); DRECOVER(for_init_1);}
1353 for_update: /* Can be empty */
1354 {$$ = size_zero_node;}
1355 | statement_expression_list
1356 { $$ = build_debugable_stmt (BUILD_LOCATION (), $1); }
1359 statement_expression_list:
1360 statement_expression
1361 { $$ = add_stmt_to_compound (NULL_TREE, NULL_TREE, $1); }
1362 | statement_expression_list C_TK statement_expression
1363 { $$ = add_stmt_to_compound ($1, NULL_TREE, $3); }
1364 | statement_expression_list C_TK error
1365 {yyerror ("Missing term"); RECOVER;}
1370 { $$ = build_bc_statement ($1.location, 1, NULL_TREE); }
1371 | BREAK_TK identifier SC_TK
1372 { $$ = build_bc_statement ($1.location, 1, $2); }
1374 {yyerror ("Missing term"); RECOVER;}
1375 | BREAK_TK identifier error
1376 {yyerror ("';' expected"); RECOVER;}
1381 { $$ = build_bc_statement ($1.location, 0, NULL_TREE); }
1382 | CONTINUE_TK identifier SC_TK
1383 { $$ = build_bc_statement ($1.location, 0, $2); }
1385 {yyerror ("Missing term"); RECOVER;}
1386 | CONTINUE_TK identifier error
1387 {yyerror ("';' expected"); RECOVER;}
1392 { $$ = build_return ($1.location, NULL_TREE); }
1393 | RETURN_TK expression SC_TK
1394 { $$ = build_return ($1.location, $2); }
1396 {yyerror ("Missing term"); RECOVER;}
1397 | RETURN_TK expression error
1398 {yyerror ("';' expected"); RECOVER;}
1402 THROW_TK expression SC_TK
1404 $$ = build1 (THROW_EXPR, NULL_TREE, $2);
1405 EXPR_WFL_LINECOL ($$) = $1.location;
1408 {yyerror ("Missing term"); RECOVER;}
1409 | THROW_TK expression error
1410 {yyerror ("';' expected"); RECOVER;}
1413 synchronized_statement:
1414 synchronized OP_TK expression CP_TK block
1416 $$ = build (SYNCHRONIZED_EXPR, NULL_TREE, $3, $5);
1417 EXPR_WFL_LINECOL ($$) =
1418 EXPR_WFL_LINECOL (MODIFIER_WFL (SYNCHRONIZED_TK));
1420 | synchronized OP_TK expression CP_TK error
1421 {yyerror ("'{' expected"); RECOVER;}
1422 | synchronized error
1423 {yyerror ("'(' expected"); RECOVER;}
1424 | synchronized OP_TK error CP_TK
1425 {yyerror ("Missing term"); RECOVER;}
1426 | synchronized OP_TK error
1427 {yyerror ("Missing term"); RECOVER;}
1433 if ((1 << $1) != ACC_SYNCHRONIZED)
1434 fatal ("synchronized was '%d' - yyparse", (1 << $1));
1439 TRY_TK block catches
1440 { $$ = build_try_statement ($1.location, $2, $3, NULL_TREE); }
1441 | TRY_TK block finally
1442 { $$ = build_try_statement ($1.location, $2, NULL_TREE, $3); }
1443 | TRY_TK block catches finally
1444 { $$ = build_try_statement ($1.location, $2, $3, $4); }
1446 {yyerror ("'{' expected"); DRECOVER (try_statement);}
1451 | catches catch_clause
1453 TREE_CHAIN ($2) = $1;
1459 catch_clause_parameter block
1461 java_method_add_stmt (current_function_decl, $2);
1466 catch_clause_parameter:
1467 CATCH_TK OP_TK formal_parameter CP_TK
1469 /* We add a block to define a scope for
1470 formal_parameter (CCBP). The formal parameter is
1471 declared initialized by the appropriate function
1473 tree ccpb = enter_block ();
1474 tree init = build_assignment (ASSIGN_TK, $2.location,
1476 soft_exceptioninfo_call_node);
1477 declare_local_variables (0, TREE_VALUE ($3),
1478 build_tree_list (TREE_PURPOSE ($3),
1480 $$ = build1 (CATCH_EXPR, NULL_TREE, ccpb);
1481 EXPR_WFL_LINECOL ($$) = $1.location;
1484 {yyerror ("'(' expected"); RECOVER;}
1485 | CATCH_TK OP_TK error
1486 {yyerror ("Missing term or ')' expected"); DRECOVER (2);}
1487 | CATCH_TK OP_TK error CP_TK /* That's for () */
1488 {yyerror ("')' expected"); DRECOVER (1);}
1494 $$ = build (FINALLY_EXPR, NULL_TREE,
1495 create_label_decl (generate_name ()), $2);
1498 {yyerror ("'{' expected"); RECOVER; }
1501 /* 19.12 Production from 15: Expressions */
1503 primary_no_new_array
1504 | array_creation_expression
1507 primary_no_new_array:
1510 { $$ = build_this ($1.location); }
1511 | OP_TK expression CP_TK
1513 | class_instance_creation_expression
1517 /* type DOT_TK CLASS_TK doens't work. So we split the rule
1518 'type' into its components. Missing is something for array,
1519 which will complete the reference_type part. FIXME */
1520 | name DOT_TK CLASS_TK /* Added, JDK1.1 class literals */
1521 { $$ = parse_jdk1_1_error ("class literals"); }
1522 | primitive_type DOT_TK CLASS_TK /* Added, JDK1.1 class literals */
1523 { $$ = parse_jdk1_1_error ("class literals"); }
1524 | VOID_TK DOT_TK CLASS_TK /* Added, JDK1.1 class literals */
1525 { $$ = parse_jdk1_1_error ("class literals"); }
1526 /* Added, JDK1.1 inner classes. Documentation is wrong
1527 refering to a 'ClassName' (class_name) rule that doesn't
1528 exist. Used name instead. */
1529 | name DOT_TK THIS_TK
1530 { $$ = parse_jdk1_1_error ("class literals"); }
1531 | OP_TK expression error
1532 {yyerror ("')' expected"); RECOVER;}
1534 {yyerror ("'class' or 'this' expected" ); RECOVER;}
1535 | primitive_type DOT_TK error
1536 {yyerror ("'class' expected" ); RECOVER;}
1537 | VOID_TK DOT_TK error
1538 {yyerror ("'class' expected" ); RECOVER;}
1541 class_instance_creation_expression:
1542 NEW_TK class_type OP_TK argument_list CP_TK
1543 { $$ = build_new_invocation ($2, $4); }
1544 | NEW_TK class_type OP_TK CP_TK
1545 { $$ = build_new_invocation ($2, NULL_TREE); }
1546 /* Added, JDK1.1 inner classes but modified to use
1547 'class_type' instead of 'TypeName' (type_name) mentionned
1548 in the documentation but doesn't exist. */
1549 | NEW_TK class_type OP_TK argument_list CP_TK class_body
1550 { $$ = parse_jdk1_1_error ("inner class instance creation"); }
1551 | NEW_TK class_type OP_TK CP_TK class_body
1552 { $$ = parse_jdk1_1_error ("inner class instance creation"); }
1553 /* Added, JDK1.1 inner classes, modified to use name or
1554 primary instead of primary solely which couldn't work in
1556 | something_dot_new identifier OP_TK CP_TK
1557 | something_dot_new identifier OP_TK CP_TK class_body
1558 | something_dot_new identifier OP_TK argument_list CP_TK
1559 | something_dot_new identifier OP_TK argument_list CP_TK class_body
1560 | NEW_TK error SC_TK
1561 {yyerror ("'(' expected"); DRECOVER(new_1);}
1562 | NEW_TK class_type error
1563 {yyerror ("'(' expected"); RECOVER;}
1564 | NEW_TK class_type OP_TK error
1565 {yyerror ("')' or term expected"); RECOVER;}
1566 | NEW_TK class_type OP_TK argument_list error
1567 {yyerror ("')' expected"); RECOVER;}
1568 | something_dot_new error
1569 {YYERROR_NOW; yyerror ("Identifier expected"); RECOVER;}
1570 | something_dot_new identifier error
1571 {yyerror ("'(' expected"); RECOVER;}
1574 something_dot_new: /* Added, not part of the specs. */
1576 | primary DOT_TK NEW_TK
1582 $$ = tree_cons (NULL_TREE, $1, NULL_TREE);
1583 ctxp->formal_parameter_number = 1;
1585 | argument_list C_TK expression
1587 ctxp->formal_parameter_number += 1;
1588 $$ = tree_cons (NULL_TREE, $3, $1);
1590 | argument_list C_TK error
1591 {yyerror ("Missing term"); RECOVER;}
1594 array_creation_expression:
1595 NEW_TK primitive_type dim_exprs
1596 { $$ = build_newarray_node ($2, $3, 0); }
1597 | NEW_TK class_or_interface_type dim_exprs
1598 { $$ = build_newarray_node ($2, $3, 0); }
1599 | NEW_TK primitive_type dim_exprs dims
1600 { $$ = build_newarray_node ($2, $3, ctxp->osb_number); }
1601 | NEW_TK class_or_interface_type dim_exprs dims
1602 { $$ = build_newarray_node ($2, $3, ctxp->osb_number); }
1603 /* Added, JDK1.1 anonymous array. Initial documentation rule
1605 | NEW_TK class_or_interface_type dims array_initializer
1606 { $$ = parse_jdk1_1_error ("anonymous array"); }
1607 | NEW_TK primitive_type dims array_initializer
1608 { $$ = parse_jdk1_1_error ("anonymous array"); }
1609 | NEW_TK error CSB_TK
1610 {yyerror ("'[' expected"); DRECOVER ("]");}
1611 | NEW_TK error OSB_TK
1612 {yyerror ("']' expected"); RECOVER;}
1617 { $$ = build_tree_list (NULL_TREE, $1); }
1618 | dim_exprs dim_expr
1619 { $$ = tree_cons (NULL_TREE, $2, $$); }
1623 OSB_TK expression CSB_TK
1625 EXPR_WFL_LINECOL ($2) = $1.location;
1628 | OSB_TK expression error
1629 {yyerror ("']' expected"); RECOVER;}
1632 yyerror ("Missing term");
1633 yyerror ("']' expected");
1640 { ctxp->osb_number = 1; }
1641 | dims OSB_TK CSB_TK
1642 { ctxp->osb_number++; }
1644 { yyerror ("']' expected"); RECOVER;}
1648 primary DOT_TK identifier
1649 { $$ = make_qualified_primary ($1, $3, $2.location); }
1650 | SUPER_TK DOT_TK identifier
1653 build_wfl_node (super_identifier_node,
1654 input_filename, 0, 0);
1655 EXPR_WFL_LINECOL (super_wfl) = $1.location;
1656 $$ = make_qualified_name (super_wfl, $3, $2.location);
1659 {yyerror ("Field expected"); DRECOVER (super_field_acces);}
1664 { $$ = build_method_invocation ($1, NULL_TREE); }
1665 | name OP_TK argument_list CP_TK
1666 { $$ = build_method_invocation ($1, $3); }
1667 | primary DOT_TK identifier OP_TK CP_TK
1669 tree invok = build_method_invocation ($3, NULL_TREE);
1670 $$ = make_qualified_primary ($1, invok, $2.location);
1672 | primary DOT_TK identifier OP_TK argument_list CP_TK
1674 tree invok = build_method_invocation ($3, $5);
1675 $$ = make_qualified_primary ($1, invok, $2.location);
1677 | SUPER_TK DOT_TK identifier OP_TK CP_TK
1680 tree wfl = build_wfl_node (super_identifier_node,
1681 input_filename, 0, 0);
1682 EXPR_WFL_LINECOL (wfl) = $1.location;
1683 invok = build_method_invocation ($3, NULL_TREE);
1684 $$ = make_qualified_primary (wfl, invok, $2.location);
1686 | SUPER_TK DOT_TK identifier OP_TK argument_list CP_TK
1689 tree wfl = build_wfl_node (super_identifier_node,
1690 input_filename, 0, 0);
1691 EXPR_WFL_LINECOL (wfl) = $1.location;
1692 invok = build_method_invocation ($3, $5);
1693 $$ = make_qualified_primary (wfl, invok, $2.location);
1695 /* Screws up thing. I let it here until I'm convinced it can
1697 | primary DOT_TK error
1698 {yyerror ("'(' expected"); DRECOVER(bad);} */
1699 | SUPER_TK DOT_TK error CP_TK
1700 { yyerror ("'(' expected"); DRECOVER (method_invocation); }
1701 | SUPER_TK DOT_TK error DOT_TK
1702 { yyerror ("'(' expected"); DRECOVER (method_invocation); }
1706 name OSB_TK expression CSB_TK
1707 { $$ = build_array_ref ($2.location, $1, $3); }
1708 | primary_no_new_array OSB_TK expression CSB_TK
1709 { $$ = build_array_ref ($2.location, $1, $3); }
1712 yyerror ("Missing term and ']' expected");
1713 DRECOVER(array_access);
1715 | name OSB_TK expression error
1717 yyerror ("']' expected");
1718 DRECOVER(array_access);
1720 | primary_no_new_array OSB_TK error
1722 yyerror ("Missing term and ']' expected");
1723 DRECOVER(array_access);
1725 | primary_no_new_array OSB_TK expression error
1727 yyerror ("']' expected");
1728 DRECOVER(array_access);
1735 | post_increment_expression
1736 | post_decrement_expression
1739 post_increment_expression:
1740 postfix_expression INCR_TK
1741 { $$ = build_incdec ($2.token, $2.location, $1, 1); }
1744 post_decrement_expression:
1745 postfix_expression DECR_TK
1746 { $$ = build_incdec ($2.token, $2.location, $1, 1); }
1750 pre_increment_expression
1751 | pre_decrement_expression
1752 | PLUS_TK unary_expression
1753 {$$ = build_unaryop ($1.token, $1.location, $2); }
1754 | MINUS_TK unary_expression
1755 {$$ = build_unaryop ($1.token, $1.location, $2); }
1756 | unary_expression_not_plus_minus
1758 {yyerror ("Missing term"); RECOVER}
1760 {yyerror ("Missing term"); RECOVER}
1763 pre_increment_expression:
1764 INCR_TK unary_expression
1765 {$$ = build_incdec ($1.token, $1.location, $2, 0); }
1767 {yyerror ("Missing term"); RECOVER}
1770 pre_decrement_expression:
1771 DECR_TK unary_expression
1772 {$$ = build_incdec ($1.token, $1.location, $2, 0); }
1774 {yyerror ("Missing term"); RECOVER}
1777 unary_expression_not_plus_minus:
1779 | NOT_TK unary_expression
1780 {$$ = build_unaryop ($1.token, $1.location, $2); }
1781 | NEG_TK unary_expression
1782 {$$ = build_unaryop ($1.token, $1.location, $2); }
1785 {yyerror ("Missing term"); RECOVER}
1787 {yyerror ("Missing term"); RECOVER}
1790 cast_expression: /* Error handling here is potentially weak */
1791 OP_TK primitive_type dims CP_TK unary_expression
1794 while (ctxp->osb_number--)
1795 type = build_java_array_type (type, -1);
1796 $$ = build_cast ($1.location, type, $5);
1798 | OP_TK primitive_type CP_TK unary_expression
1799 { $$ = build_cast ($1.location, $2, $4); }
1800 | OP_TK expression CP_TK unary_expression_not_plus_minus
1801 { $$ = build_cast ($1.location, $2, $4); }
1802 | OP_TK name dims CP_TK unary_expression_not_plus_minus
1805 while (ctxp->osb_number--)
1806 obstack_1grow (&temporary_obstack, '[');
1807 obstack_grow0 (&temporary_obstack,
1808 IDENTIFIER_POINTER (EXPR_WFL_NODE ($2)),
1809 IDENTIFIER_LENGTH (EXPR_WFL_NODE ($2)));
1810 ptr = obstack_finish (&temporary_obstack);
1811 EXPR_WFL_NODE ($2) = get_identifier (ptr);
1812 $$ = build_cast ($1.location, $2, $5);
1814 | OP_TK primitive_type OSB_TK error
1815 {yyerror ("']' expected, invalid type expression");}
1818 if (ctxp->prevent_ese != lineno)
1819 yyerror ("Invalid type expression"); RECOVER;
1822 | OP_TK primitive_type dims CP_TK error
1823 {yyerror ("Missing term"); RECOVER;}
1824 | OP_TK primitive_type CP_TK error
1825 {yyerror ("Missing term"); RECOVER;}
1826 | OP_TK name dims CP_TK error
1827 {yyerror ("Missing term"); RECOVER;}
1830 multiplicative_expression:
1832 | multiplicative_expression MULT_TK unary_expression
1834 $$ = build_binop (BINOP_LOOKUP ($2.token),
1835 $2.location, $1, $3);
1837 | multiplicative_expression DIV_TK unary_expression
1839 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
1842 | multiplicative_expression REM_TK unary_expression
1844 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
1847 | multiplicative_expression MULT_TK error
1848 {yyerror ("Missing term"); RECOVER;}
1849 | multiplicative_expression DIV_TK error
1850 {yyerror ("Missing term"); RECOVER;}
1851 | multiplicative_expression REM_TK error
1852 {yyerror ("Missing term"); RECOVER;}
1855 additive_expression:
1856 multiplicative_expression
1857 | additive_expression PLUS_TK multiplicative_expression
1859 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
1862 | additive_expression MINUS_TK multiplicative_expression
1864 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
1867 | additive_expression PLUS_TK error
1868 {yyerror ("Missing term"); RECOVER;}
1869 | additive_expression MINUS_TK error
1870 {yyerror ("Missing term"); RECOVER;}
1875 | shift_expression LS_TK additive_expression
1877 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
1880 | shift_expression SRS_TK additive_expression
1882 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
1885 | shift_expression ZRS_TK additive_expression
1887 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
1890 | shift_expression LS_TK error
1891 {yyerror ("Missing term"); RECOVER;}
1892 | shift_expression SRS_TK error
1893 {yyerror ("Missing term"); RECOVER;}
1894 | shift_expression ZRS_TK error
1895 {yyerror ("Missing term"); RECOVER;}
1898 relational_expression:
1900 | relational_expression LT_TK shift_expression
1902 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
1905 | relational_expression GT_TK shift_expression
1907 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
1910 | relational_expression LTE_TK shift_expression
1912 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
1915 | relational_expression GTE_TK shift_expression
1917 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
1920 | relational_expression INSTANCEOF_TK reference_type
1921 | relational_expression LT_TK error
1922 {yyerror ("Missing term"); RECOVER;}
1923 | relational_expression GT_TK error
1924 {yyerror ("Missing term"); RECOVER;}
1925 | relational_expression LTE_TK error
1926 {yyerror ("Missing term"); RECOVER;}
1927 | relational_expression GTE_TK error
1928 {yyerror ("Missing term"); RECOVER;}
1929 | relational_expression INSTANCEOF_TK error
1930 {yyerror ("Invalid reference type"); RECOVER;}
1933 equality_expression:
1934 relational_expression
1935 | equality_expression EQ_TK relational_expression
1937 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
1940 | equality_expression NEQ_TK relational_expression
1942 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
1945 | equality_expression EQ_TK error
1946 {yyerror ("Missing term"); RECOVER;}
1947 | equality_expression NEQ_TK error
1948 {yyerror ("Missing term"); RECOVER;}
1953 | and_expression AND_TK equality_expression
1955 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
1958 | and_expression AND_TK error
1959 {yyerror ("Missing term"); RECOVER;}
1962 exclusive_or_expression:
1964 | exclusive_or_expression XOR_TK and_expression
1966 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
1969 | exclusive_or_expression XOR_TK error
1970 {yyerror ("Missing term"); RECOVER;}
1973 inclusive_or_expression:
1974 exclusive_or_expression
1975 | inclusive_or_expression OR_TK exclusive_or_expression
1977 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
1980 | inclusive_or_expression OR_TK error
1981 {yyerror ("Missing term"); RECOVER;}
1984 conditional_and_expression:
1985 inclusive_or_expression
1986 | conditional_and_expression BOOL_AND_TK inclusive_or_expression
1988 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
1991 | conditional_and_expression BOOL_AND_TK error
1992 {yyerror ("Missing term"); RECOVER;}
1995 conditional_or_expression:
1996 conditional_and_expression
1997 | conditional_or_expression BOOL_OR_TK conditional_and_expression
1999 $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
2002 | conditional_or_expression BOOL_OR_TK error
2003 {yyerror ("Missing term"); RECOVER;}
2006 conditional_expression: /* Error handling here is weak */
2007 conditional_or_expression
2008 | conditional_or_expression REL_QM_TK expression REL_CL_TK conditional_expression
2009 | conditional_or_expression REL_QM_TK REL_CL_TK error
2012 yyerror ("Missing term");
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);}
2021 assignment_expression:
2022 conditional_expression
2027 left_hand_side assignment_operator assignment_expression
2028 { $$ = build_assignment ($2.token, $2.location, $1, $3); }
2029 | left_hand_side assignment_operator error
2031 if (ctxp->prevent_ese != lineno)
2032 yyerror ("Missing term");
2043 assignment_operator:
2049 assignment_expression
2052 constant_expression:
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
2065 static int force_error = 0;
2067 /* Create a new parser context and make it the current one. */
2070 java_push_parser_context ()
2072 struct parser_ctxt *new =
2073 (struct parser_ctxt *)malloc(sizeof (struct parser_ctxt));
2075 bzero (new, sizeof (struct parser_ctxt));
2079 ctxp->incomplete_class = ctxp->next->incomplete_class;
2083 java_parser_context_save_global ()
2085 ctxp->finput = finput;
2086 ctxp->lineno = lineno;
2087 ctxp->current_class = current_class;
2088 ctxp->filename = input_filename;
2089 ctxp->current_function_decl = current_function_decl;
2093 java_parser_context_restore_global ()
2095 finput = ctxp->finput;
2096 lineno = ctxp->lineno;
2097 current_class = ctxp->current_class;
2098 input_filename = ctxp->filename;
2099 current_function_decl = ctxp->current_function_decl;
2103 java_pop_parser_context ()
2106 struct parser_ctxt *toFree = ctxp;
2107 struct parser_ctxt *next = ctxp->next;
2111 next->incomplete_class = ctxp->incomplete_class;
2112 lineno = ctxp->lineno;
2113 finput = ctxp->finput;
2114 current_class = ctxp->current_class;
2117 /* Set the single import class file flag to 0 for the current list
2118 of imported things */
2119 for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
2120 IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_PURPOSE (current)) = 0;
2122 /* And restore those of the previous context */
2123 if ((ctxp = next)) /* Assignment is really meant here */
2124 for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
2125 IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_PURPOSE (current)) = 1;
2130 /* Reporting JDK1.1 features not implemented */
2133 parse_jdk1_1_error (msg)
2136 sorry (": `%s' JDK1.1(TM) feature", msg);
2138 return size_zero_node;
2141 static int do_warning = 0;
2148 static int prev_lineno;
2149 static char *prev_msg;
2152 char *remainder, *code_from_source;
2153 extern struct obstack temporary_obstack;
2155 if (!force_error && prev_lineno == lineno)
2158 /* Save current error location but report latter, when the context is
2160 if (ctxp->java_error_flag == 0)
2162 ctxp->java_error_flag = 1;
2164 /* Do something to use the previous line if we're reaching the
2165 end of the file... */
2166 #ifdef VERBOSE_SKELETON
2167 printf ("* Error detected (%s)\n", (msg ? msg : "(null)"));
2172 /* Ignore duplicate message on the same line. BTW, this is dubious. FIXME */
2173 if (!force_error && msg == prev_msg && prev_lineno == elc.line)
2176 ctxp->java_error_flag = 0;
2178 java_warning_count++;
2182 if (elc.col == 0 && msg[1] == ';')
2184 elc.col = ctxp->p_line->char_col-1;
2185 elc.line = ctxp->p_line->lineno;
2188 save_lineno = lineno;
2189 prev_lineno = lineno = elc.line;
2192 code_from_source = java_get_line_col (ctxp->filename, elc.line, elc.col);
2193 obstack_grow0 (&temporary_obstack,
2194 code_from_source, strlen (code_from_source));
2195 remainder = obstack_finish (&temporary_obstack);
2197 warning ("%s.\n%s", msg, remainder);
2199 error ("%s.\n%s", msg, remainder);
2201 /* This allow us to cheaply avoid an extra 'Invalid expression
2202 statement' error report when errors have been already reported on
2203 the same line. This occurs when we report an error but don't have
2204 a synchronization point other than ';', which
2205 expression_statement is the only one to take care of. */
2206 ctxp->prevent_ese = lineno = save_lineno;
2217 /* Issue an error message at a current source line CL */
2220 parse_error_context VPROTO ((tree cl, char *msg, ...))
2231 cl = va_arg (ap, tree);
2232 msg = va_arg (ap, char *);
2234 vsprintf (buffer, msg, ap);
2237 ctxp->elc.line = EXPR_WFL_LINENO (cl);
2238 ctxp->elc.col = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 : EXPR_WFL_COLNO (cl));
2240 parse_error (buffer);
2244 /* Issue a warning at a current source line CL */
2247 parse_warning_context VPROTO ((tree cl, char *msg, ...))
2258 cl = va_arg (ap, tree);
2259 msg = va_arg (ap, char *);
2261 vsprintf (buffer, msg, ap);
2263 force_error = do_warning = 1;
2264 ctxp->elc.line = EXPR_WFL_LINENO (cl);
2265 ctxp->elc.col = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 : EXPR_WFL_COLNO (cl));
2267 parse_error (buffer);
2268 do_warning = force_error = 0;
2272 java_report_errors ()
2274 if (java_error_count)
2275 fprintf (stderr, "%d error%s",
2276 java_error_count, (java_error_count == 1 ? "" : "s"));
2277 if (java_warning_count)
2278 fprintf (stderr, "%s%d warning%s", (java_error_count ? ", " : ""),
2279 java_warning_count, (java_warning_count == 1 ? "" : "s"));
2280 if (java_error_count || java_warning_count)
2281 putc ('\n', stderr);
2285 java_accstring_lookup (flags)
2288 static char buffer [80];
2289 #define COPY_RETURN(S) {strcpy (buffer, S); return buffer;}
2291 /* Access modifier looked-up first for easier report on forbidden
2293 if (flags & ACC_PUBLIC) COPY_RETURN ("public");
2294 if (flags & ACC_PRIVATE) COPY_RETURN ("private");
2295 if (flags & ACC_PROTECTED) COPY_RETURN ("protected");
2296 if (flags & ACC_STATIC) COPY_RETURN ("static");
2297 if (flags & ACC_FINAL) COPY_RETURN ("final");
2298 if (flags & ACC_SYNCHRONIZED) COPY_RETURN ("synchronized");
2299 if (flags & ACC_VOLATILE) COPY_RETURN ("volatile");
2300 if (flags & ACC_TRANSIENT) COPY_RETURN ("transient");
2301 if (flags & ACC_NATIVE) COPY_RETURN ("native");
2302 if (flags & ACC_INTERFACE) COPY_RETURN ("interface");
2303 if (flags & ACC_ABSTRACT) COPY_RETURN ("abstract");
2310 /* Issuing error messages upon redefinition of classes, interfaces or
2314 classitf_redefinition_error (context, id, decl, cl)
2318 parse_error_context (cl, "%s `%s' already defined in %s:%d",
2319 context, IDENTIFIER_POINTER (id),
2320 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
2321 /* Here we should point out where its redefined. It's a unicode. FIXME */
2325 variable_redefinition_error (context, name, type, line)
2326 tree context, name, type;
2331 /* Figure a proper name for type. We might haven't resolved it */
2332 if (TREE_CODE (type) == TREE_LIST)
2333 type_name = IDENTIFIER_POINTER (TYPE_NAME (TREE_PURPOSE (type)));
2335 type_name = lang_printable_name (type, 0);
2337 parse_error_context (context,
2338 "Variable `%s' is already defined in this method and "
2339 "was declared `%s %s' at line %d",
2340 IDENTIFIER_POINTER (name),
2341 type_name, IDENTIFIER_POINTER (name), line);
2344 /* Build something that the type identifier resolver will identify as
2345 being an array to an unresolved type. TYPE_WFL is a WFL on a
2349 build_unresolved_array_type (type_or_wfl)
2354 /* TYPE_OR_WFL might be an array on a primitive type. In this case,
2355 just create a array type */
2356 if (TREE_CODE (type_or_wfl) == RECORD_TYPE)
2358 tree type = build_java_array_type (type_or_wfl, -1);
2359 CLASS_LOADED_P (type) = CLASS_LOADED_P (type_or_wfl);
2363 obstack_1grow (&temporary_obstack, '[');
2364 obstack_grow0 (&temporary_obstack,
2365 IDENTIFIER_POINTER (EXPR_WFL_NODE (type_or_wfl)),
2366 IDENTIFIER_LENGTH (EXPR_WFL_NODE (type_or_wfl)));
2367 ptr = obstack_finish (&temporary_obstack);
2368 return build_expr_wfl (get_identifier (ptr),
2369 EXPR_WFL_FILENAME (type_or_wfl),
2370 EXPR_WFL_LINENO (type_or_wfl),
2371 EXPR_WFL_COLNO (type_or_wfl));
2374 /* Check modifiers. If one doesn't fit, retrieve it in its declaration line
2375 and point it out. */
2378 check_modifiers (message, value, mask)
2383 /* Should point out the one that don't fit. ASCII/unicode,
2384 going backward. FIXME */
2387 int i, remainder = value & ~mask;
2388 for (i = 0; i <= 10; i++)
2389 if ((1 << i) & remainder)
2390 parse_error_context (ctxp->modifier_ctx [i], message,
2391 java_accstring_lookup (1 << i));
2396 parser_add_interface (class_decl, interface_decl, wfl)
2397 tree class_decl, interface_decl, wfl;
2399 if (maybe_add_interface (TREE_TYPE (class_decl), TREE_TYPE (interface_decl)))
2400 parse_error_context (wfl, "Interface `%s' repeated",
2401 IDENTIFIER_POINTER (DECL_NAME (interface_decl)));
2404 /* Bulk of common class/interface checks. Return 1 if an error was
2405 encountered. TAG is 0 for a class, 1 for an interface. */
2408 check_class_interface_creation (is_interface, flags, raw_name, qualified_name, decl, cl)
2409 int is_interface, flags;
2410 tree raw_name, qualified_name, decl, cl;
2415 fprintf (stderr, " %s %s", (is_interface ? "interface" : "class"),
2416 IDENTIFIER_POINTER (qualified_name));
2418 /* Scope of an interface/class type name:
2419 - Can't be imported by a single type import
2420 - Can't already exists in the package */
2421 if (IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (raw_name)
2422 && (node = find_name_in_single_imports (raw_name)))
2425 (cl, "%s name `%s' clashes with imported type `%s'",
2426 (is_interface ? "Interface" : "Class"),
2427 IDENTIFIER_POINTER (raw_name), IDENTIFIER_POINTER (node));
2430 if (decl && CLASS_COMPLETE_P (decl))
2432 classitf_redefinition_error ((is_interface ? "Interface" : "Class"),
2433 qualified_name, decl, cl);
2437 /* If public, file name should match class/interface name */
2438 if (flags & ACC_PUBLIC)
2442 /* Contains OS dependent assumption on path separator. FIXME */
2443 for (f = &input_filename [strlen (input_filename)];
2444 f != input_filename && f[0] != '/'; f--);
2447 if (strncmp (IDENTIFIER_POINTER (raw_name),
2448 f , IDENTIFIER_LENGTH (raw_name)) ||
2449 f [IDENTIFIER_LENGTH (raw_name)] != '.')
2450 parse_error_context (cl, "Public %s `%s' must be defined in a file "
2452 (is_interface ? "interface" : "class"),
2453 IDENTIFIER_POINTER (qualified_name),
2454 IDENTIFIER_POINTER (raw_name));
2457 check_modifiers ((is_interface ?
2458 "Illegal modifier `%s' for interface declaration" :
2459 "Illegal modifier `%s' for class declaration"), flags,
2460 (is_interface ? INTERFACE_MODIFIERS : CLASS_MODIFIERS));
2464 /* If DECL is NULL, create and push a new DECL, record the current
2465 line CL and do other maintenance things. */
2468 maybe_create_class_interface_decl (decl, qualified_name, cl)
2469 tree decl, qualified_name, cl;
2472 DECL_ARTIFICIAL (decl) = 1; /* FIXME */
2474 decl = push_class (make_class (), qualified_name);
2476 /* Take care of the file and line business */
2477 DECL_SOURCE_FILE (decl) = EXPR_WFL_FILENAME (cl);
2478 DECL_SOURCE_LINE (decl) = EXPR_WFL_LINENO (cl);
2479 CLASS_FROM_SOURCE_P (TREE_TYPE (decl)) = 1;
2481 ctxp->current_parsed_class = decl;
2483 /* Link the declaration to the already seen ones */
2484 TREE_CHAIN (decl) = ctxp->class_list;
2485 ctxp->class_list = decl;
2486 /* Install a new dependency list element */
2487 create_jdep_list (ctxp);
2489 SOURCE_FRONTEND_DEBUG (("Defining class/interface %s",
2490 IDENTIFIER_POINTER (qualified_name)));
2495 add_superinterfaces (decl, interface_list)
2496 tree decl, interface_list;
2499 /* Superinterface(s): if present and defined, parser_check_super_interface ()
2500 takes care of ensuring that:
2501 - This is an accessible interface type,
2502 - Circularity detection.
2503 parser_add_interface is then called. If present but not defined,
2504 the check operation is delayed until the super interface gets
2506 for (node = interface_list; node; node = TREE_CHAIN (node))
2508 tree current = TREE_PURPOSE (node), interface_decl;
2509 if ((interface_decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (current))))
2511 if (!parser_check_super_interface (interface_decl, decl, current))
2512 parser_add_interface (decl, interface_decl, current);
2515 register_incomplete_type (JDEP_INTERFACE,
2516 current, decl, NULL_TREE);
2520 /* Create an interface in pass1 and return its decl. Return the
2521 interface's decl in pass 2. */
2524 create_interface (flags, id, super)
2528 tree raw_name = EXPR_WFL_NODE (id);
2529 tree q_name = parser_qualified_classname (id);
2530 tree decl = IDENTIFIER_CLASS_VALUE (q_name);
2532 EXPR_WFL_NODE (id) = q_name; /* Keep source location, even if refined. */
2534 /* Basic checks: scope, redefinition, modifiers */
2535 if (check_class_interface_creation (1, flags, raw_name, q_name, decl, id))
2538 /* Interface modifiers check
2539 - public/abstract allowed (already done at that point)
2540 - abstract is obsolete (comes first, it's a warning, or should be)
2541 - Can't use twice the same (checked in the modifier rule) */
2542 if (flags & ACC_ABSTRACT)
2543 parse_warning_context
2544 (MODIFIER_WFL (ABSTRACT_TK),
2545 "Obsolete use of `abstract' modifier. Interface `%s' is implicitely "
2546 "abstract", IDENTIFIER_POINTER (raw_name));
2547 if (flags & ACC_PUBLIC && flags & ACC_ABSTRACT)
2549 (MODIFIER_WFL (ABSTRACT_TK),
2550 "Can't specify both `public' and `abstract' modifiers in the "
2551 "definition of interface `%s'", IDENTIFIER_POINTER (raw_name));
2553 /* Create a new decl if DECL is NULL, otherwise fix it */
2554 decl = maybe_create_class_interface_decl (decl, q_name, id);
2556 /* Set super info and mark the class a complete */
2557 set_super_info (ACC_ABSTRACT | ACC_INTERFACE | flags, TREE_TYPE (decl),
2558 object_type_node, ctxp->interface_number);
2559 ctxp->interface_number = 0;
2560 CLASS_COMPLETE_P (decl) = 1;
2561 add_superinterfaces (decl, super);
2566 /* Create an class in pass1 and return its decl. Return class
2567 interface's decl in pass 2. */
2570 create_class (flags, id, super, interfaces)
2572 tree id, super, interfaces;
2574 tree raw_name = EXPR_WFL_NODE (id);
2575 tree class_id, decl;
2576 tree super_decl = NULL, super_decl_type;
2578 class_id = parser_qualified_classname (id);
2579 decl = IDENTIFIER_CLASS_VALUE (class_id);
2580 EXPR_WFL_NODE (id) = class_id;
2582 /* Basic check: scope, redefinition, modifiers */
2583 if (check_class_interface_creation (0, flags, raw_name, class_id, decl, id))
2586 /* Class modifier check:
2587 - Allowed modifier (already done at that point)
2588 - abstract AND final forbidden
2589 - Public classes defined in the correct file */
2590 if ((flags & ACC_ABSTRACT) && (flags & ACC_FINAL))
2591 parse_error_context (id, "Class `%s' can't be declared both abstract "
2592 "and final", IDENTIFIER_POINTER (raw_name));
2594 /* Create a new decl if DECL is NULL, otherwise fix it */
2595 decl = maybe_create_class_interface_decl (decl, class_id, id);
2597 /* If SUPER exists, use it, otherwise use Object */
2600 /* Can't extend java.lang.Object */
2601 if (TREE_TYPE (IDENTIFIER_CLASS_VALUE (class_id)) == object_type_node)
2603 parse_error_context (id, "Can't extend `java.lang.Object'");
2607 /* The class is known and exists if there is a decl. Otherwise,
2608 postpone the operation and do it later. */
2609 super_decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (super));
2612 parser_check_super (super_decl, decl, id);
2613 super_decl_type = TREE_TYPE (super_decl);
2617 register_incomplete_type (JDEP_SUPER, super, decl, NULL_TREE);
2619 else if (TREE_TYPE (decl) != object_type_node)
2620 super_decl_type = object_type_node;
2621 /* We're defining java.lang.Object */
2623 super_decl_type = NULL_TREE;
2625 /* Set super info and mark the class a complete */
2626 set_super_info (flags, TREE_TYPE (decl), super_decl_type,
2627 ctxp->interface_number);
2628 ctxp->interface_number = 0;
2629 CLASS_COMPLETE_P (decl) = 1;
2630 add_superinterfaces (decl, interfaces);
2635 /* Can't use lookup_field () since we don't want to load the class and
2636 can't set the CLASS_LOADED_P flag */
2639 find_field (class, name)
2644 for (decl = TYPE_FIELDS (class); decl; decl = TREE_CHAIN (decl))
2646 if (DECL_NAME (decl) == name)
2652 /* Wrap around lookup_field that doesn't potentially upset the value
2656 lookup_field_wrapper (class, name)
2660 return lookup_field (&type, name);
2663 /* Find duplicate field within the same class declarations and report
2667 duplicate_declaration_error (new_field_name, new_type, cl)
2668 tree new_field_name, new_type, cl;
2670 /* This might be modified to work with method decl as well */
2671 tree decl = find_field (TREE_TYPE (ctxp->current_parsed_class),
2675 char *t1 = strdup (lang_printable_name (new_type, 1));
2677 strdup ((TREE_CODE (TREE_TYPE (decl)) == TREE_LIST ?
2678 IDENTIFIER_POINTER (TYPE_NAME
2679 (TREE_PURPOSE (TREE_TYPE (decl)))) :
2680 lang_printable_name (TREE_TYPE (decl), 1)));
2682 (cl , "Duplicate variable declaration: `%s %s' was `%s %s' (%s:%d)",
2683 t1, IDENTIFIER_POINTER (new_field_name),
2684 t2, IDENTIFIER_POINTER (DECL_NAME (decl)),
2685 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
2693 /* Field registration routine. If TYPE doesn't exist, field
2694 declarations are linked to the undefined TYPE dependency list, to
2695 be later resolved in java_complete_class () */
2698 register_fields (flags, type, variable_list)
2700 tree type, variable_list;
2702 tree current, returned_type;
2703 tree class_type = TREE_TYPE (ctxp->current_parsed_class);
2704 int saved_lineno = lineno;
2706 tree wfl = NULL_TREE;
2708 /* If we're adding fields to interfaces, those fields are public,
2710 if (CLASS_INTERFACE (TYPE_NAME (class_type)))
2712 OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (PUBLIC_TK),
2714 "%s", "interface field(s)");
2715 OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (STATIC_TK),
2717 "%s", "interface field(s)");
2718 OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (FINAL_TK),
2719 flags, ACC_FINAL, "%s", "interface field(s)");
2720 check_modifiers ("Illegal interface member modifier `%s'", flags,
2721 INTERFACE_FIELD_MODIFIERS);
2722 flags |= (ACC_PUBLIC | ACC_STATIC | ACC_FINAL);
2725 if (unresolved_type_p (type, &returned_type))
2728 type = returned_type;
2732 type = obtain_incomplete_type (type);
2736 if (!must_chain && TREE_CODE (type) == RECORD_TYPE)
2737 type = promote_type (type);
2739 for (current = variable_list; current; current = TREE_CHAIN (current))
2741 tree cl = TREE_PURPOSE (current);
2742 tree init = TREE_VALUE (current);
2743 tree current_name = EXPR_WFL_NODE (cl);
2745 if (duplicate_declaration_error (current_name, type, cl))
2748 lineno = EXPR_WFL_LINENO (cl);
2749 field_decl = add_field (class_type, current_name, type, flags);
2751 /* Check if we must chain. */
2753 register_incomplete_type (JDEP_FIELD, wfl, field_decl, type);
2755 /* Default value of a static field is 0 and it is considered
2757 if (flags & ACC_STATIC)
2758 INITIALIZED_P (field_decl) = 1;
2760 /* If we have an initialization value tied to the field */
2763 /* The field is declared static */
2764 if (flags & ACC_STATIC)
2767 if (flags & ACC_FINAL)
2769 /* Otherwise, the field should be initialized in
2770 <clinit>. This field is remembered so we can
2771 generate <clinit> later. */
2774 INITIALIZED_P (field_decl) = 1;
2775 TREE_CHAIN (init) = ctxp->static_initialized;
2776 ctxp->static_initialized = init;
2779 /* A non-static field declared with an immediate
2780 initialization is to be initialized in <init>, if
2781 any. This field is remembered to be processed at the
2782 time of the generation of <init>. */
2785 TREE_CHAIN (init) = ctxp->non_static_initialized;
2786 ctxp->non_static_initialized = init;
2791 lineno = saved_lineno;
2794 /* Check whether it is necessary to generate a <clinit> for the class
2798 maybe_generate_clinit ()
2801 tree meth, mdecl, c;
2802 tree cclass, class_wfl;
2804 if (!ctxp->static_initialized || java_error_count)
2807 cclass = TREE_TYPE (ctxp->current_parsed_class);
2808 class_wfl = build_expr_wfl (DECL_NAME (TYPE_NAME (cclass)),
2809 input_filename, 0, 0);
2811 saved_lineno = lineno;
2813 meth = make_node (FUNCTION_TYPE);
2814 TREE_TYPE (meth) = void_type_node;
2815 TYPE_ARG_TYPES (meth) = NULL_TREE;
2816 mdecl = add_method (cclass, ACC_STATIC, clinit_identifier_node,
2817 build_java_signature (meth));
2818 lineno = saved_lineno;
2820 DECL_SOURCE_LINE (mdecl) = 1;
2821 DECL_SOURCE_LINE_MERGE (mdecl, 1);
2822 source_start_java_method (mdecl);
2825 /* Keep initialization in order to enforce 8.5 */
2826 ctxp->static_initialized = nreverse (ctxp->static_initialized);
2828 /* We process the list of assignment we produced as the result of
2829 the declaration of initialized static field and add them as
2830 statement to the <clinit> method. */
2831 for (c = ctxp->static_initialized; c; c = TREE_CHAIN (c))
2833 /* We build the assignment expression that will initialize the
2834 field to its value. There are strict rules on static
2835 initializers (8.5). FIXME */
2836 java_method_add_stmt (mdecl, c);
2839 BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)) = exit_block ();
2841 ctxp->static_initialized = NULL_TREE;
2844 /* Shared accros method_declarator and method_header to remember the
2845 patch stage that was reached during the declaration of the method.
2846 A method DECL is built differently is there is no patch
2847 (JDEP_NO_PATCH) or a patch (JDEP_METHOD or JDEP_METHOD_RETURN)
2848 pending on the currently defined method. */
2850 static int patch_stage;
2852 /* Check the method declaration and add the method to its current
2853 class. If the argument list is known to contain incomplete types,
2854 the method is partially added and the registration will be resume
2855 once the method arguments resolved */
2858 method_header (flags, type, mdecl, throws)
2860 tree type, mdecl, throws;
2862 tree meth = TREE_VALUE (mdecl);
2863 tree id = TREE_PURPOSE (mdecl);
2864 tree this_class = TREE_TYPE (ctxp->current_parsed_class);
2865 tree meth_name, returned_type, current;
2868 check_modifiers_consistency (flags);
2870 /* There are some forbidden modifiers for an abstract method and its
2871 class must be abstract as well. */
2872 if (flags & ACC_ABSTRACT)
2874 ABSTRACT_CHECK (flags, ACC_PRIVATE, id, "Private");
2875 ABSTRACT_CHECK (flags, ACC_STATIC, id, "Static");
2876 ABSTRACT_CHECK (flags, ACC_FINAL, id, "Final");
2877 ABSTRACT_CHECK (flags, ACC_NATIVE, id, "Native");
2878 ABSTRACT_CHECK (flags, ACC_SYNCHRONIZED,id, "Synchronized");
2879 if (!CLASS_ABSTRACT (TYPE_NAME (this_class)))
2881 (id, "Class `%s' must be declared abstract to define abstract "
2883 IDENTIFIER_POINTER (DECL_NAME (ctxp->current_parsed_class)),
2884 IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
2888 /* Method declared within the scope of an interface are implicitly
2889 abstract and public. Conflicts with other erroneously provided
2890 modifiers are check right after. */
2892 if (CLASS_INTERFACE (TYPE_NAME (this_class)))
2894 /* If FLAGS isn't set because of a modifier, turn the
2895 corresponding modifier WFL to NULL so we issue a warning on
2896 the obsolete use of the modifier */
2897 if (!(flags & ACC_PUBLIC))
2898 MODIFIER_WFL (PUBLIC_TK) = NULL;
2899 if (!(flags & ACC_ABSTRACT))
2900 MODIFIER_WFL (ABSTRACT_TK) = NULL;
2901 flags |= ACC_PUBLIC;
2902 flags |= ACC_ABSTRACT;
2905 /* Modifiers context reset moved up, so abstract method declaration
2906 modifiers can be later checked. */
2908 meth_name = EXPR_WFL_NODE (id);
2910 if (unresolved_type_p (type, &returned_type))
2913 TREE_TYPE (meth) = returned_type;
2916 patch_stage = JDEP_METHOD_RETURN;
2918 register_incomplete_type (patch_stage, type, id, NULL_TREE);
2922 TREE_TYPE (meth) = type;
2924 saved_lineno = lineno;
2925 /* When defining an abstract or interface method, the curly
2926 bracket at level 1 doesn't exist because there is no function
2928 lineno = (ctxp->first_ccb_indent1 ? ctxp->first_ccb_indent1 :
2929 EXPR_WFL_LINENO (id));
2931 if (patch_stage) /* includes ret type and/or all args */
2934 meth = add_method_1 (this_class, flags, meth_name, meth);
2935 /* Patch for the return type */
2936 if (patch_stage == JDEP_METHOD_RETURN)
2938 jdep = CLASSD_LAST (ctxp->classd_list);
2939 JDEP_GET_PATCH (jdep) = &TREE_TYPE (TREE_TYPE (meth));
2941 /* This is the stop JDEP. METH allows the function's signature
2943 register_incomplete_type (JDEP_METHOD_END, NULL_TREE, meth, NULL_TREE);
2947 tree signature = build_java_signature (meth);
2949 /* Save original argument list, including argument's names */
2950 orig_arg = TYPE_ARG_TYPES (meth);
2951 /* Add the method to its class */
2952 meth = add_method (this_class, flags, meth_name, signature);
2953 /* Fix the method argument list so we have the argument name
2955 arg = TYPE_ARG_TYPES (TREE_TYPE (meth));
2956 if (TREE_CODE (TREE_TYPE (meth)) == METHOD_TYPE)
2958 TREE_PURPOSE (arg) = this_identifier_node;
2959 arg = TREE_CHAIN (arg);
2963 TREE_PURPOSE (arg) = TREE_PURPOSE (orig_arg);
2964 orig_arg = TREE_CHAIN (orig_arg);
2965 arg = TREE_CHAIN (arg);
2968 DECL_MAX_LOCALS (meth) = ctxp->formal_parameter_number+1;
2969 lineno = saved_lineno;
2971 /* Register exception specified by the `throws' keyword for
2972 resolution and set the method decl appropriate field to the list.
2973 Note: the grammar ensures that what we get here are class
2977 throws = nreverse (throws);
2978 for (current = throws; current; current = TREE_CHAIN (current))
2980 register_incomplete_type (JDEP_EXCEPTION, TREE_VALUE (current),
2981 NULL_TREE, NULL_TREE);
2982 JDEP_GET_PATCH (CLASSD_LAST (ctxp->classd_list)) =
2983 &TREE_VALUE (current);
2985 DECL_FUNCTION_THROWS (meth) = throws;
2988 /* We set the DECL_NAME to ID so we can track the location where
2989 the function was declared. This allow us to report
2990 redefinition error accurately. When method are verified,
2991 DECL_NAME is reinstalled properly (using the content of the
2992 WFL node ID) (see check_method_redefinition). We don't do that
2993 when Object is being defined. */
2994 if (TREE_TYPE (ctxp->current_parsed_class) != object_type_node)
2995 DECL_NAME (meth) = id;
2999 /* Check modifiers that can be declared but exclusively */
3002 check_modifiers_consistency (flags)
3006 tree cl = NULL_TREE;
3008 THIS_MODIFIER_ONLY (flags, ACC_PUBLIC, 0, acc_count, cl);
3009 THIS_MODIFIER_ONLY (flags, ACC_PRIVATE, 1, acc_count, cl);
3010 THIS_MODIFIER_ONLY (flags, ACC_PROTECTED, 2, acc_count, cl);
3013 (cl, "Inconsistent member declaration. At most one of `public', "
3014 "`private', or `protected' may be specified");
3017 /* Check the methode header METH for abstract specifics features */
3020 check_abstract_method_header (meth)
3023 int flags = get_access_flags_from_decl (meth);
3024 /* DECL_NAME might still be a WFL node */
3025 tree name = (TREE_CODE (DECL_NAME (meth)) == EXPR_WITH_FILE_LOCATION ?
3026 EXPR_WFL_NODE (DECL_NAME (meth)) : DECL_NAME (meth));
3028 OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (ABSTRACT_TK), flags,
3029 ACC_ABSTRACT, "abstract method `%s'",
3030 IDENTIFIER_POINTER (name));
3031 OBSOLETE_MODIFIER_WARNING (MODIFIER_WFL (PUBLIC_TK), flags,
3032 ACC_PUBLIC, "abstract method `%s'",
3033 IDENTIFIER_POINTER (name));
3035 check_modifiers ("Illegal modifier `%s' for interface method",
3036 flags, INTERFACE_METHOD_MODIFIERS);
3039 /* Create a FUNCTION_TYPE node and start augmenting it with the
3040 declared function arguments. Arguments type that can't be resolved
3041 are left as they are, but the returned node is marked as containing
3042 incomplete types. */
3045 method_declarator (id, list)
3048 tree arg_types = NULL_TREE, current, node;
3049 tree meth = make_node (FUNCTION_TYPE);
3052 patch_stage = JDEP_NO_PATCH;
3054 for (current = list; current; current = TREE_CHAIN (current))
3056 tree wfl_name = TREE_PURPOSE (current);
3057 tree type = TREE_VALUE (current);
3058 tree name = EXPR_WFL_NODE (wfl_name);
3059 tree already, arg_node, returned_type;
3061 /* Check redefinition */
3062 for (already = arg_types; already; already = TREE_CHAIN (already))
3063 if (TREE_PURPOSE (already) == name)
3066 (wfl_name, "Variable `%s' is used more than once in the "
3067 "argument list of method `%s'", IDENTIFIER_POINTER (name),
3068 IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
3072 /* If we've an incomplete argument type, we know there is a location
3073 to patch when the type get resolved, later. */
3075 if (unresolved_type_p (type, &returned_type))
3078 type = returned_type;
3081 patch_stage = JDEP_METHOD;
3082 type = register_incomplete_type (patch_stage, type,
3083 wfl_name, NULL_TREE);
3084 jdep = CLASSD_LAST (ctxp->classd_list);
3085 JDEP_MISC (jdep) = id;
3088 /* The argument node: a name and a (possibly) incomplete type */
3089 arg_node = build_tree_list (name, type);
3091 JDEP_GET_PATCH (jdep) = &TREE_VALUE (arg_node);
3092 TREE_CHAIN (arg_node) = arg_types;
3093 arg_types = arg_node;
3095 TYPE_ARG_TYPES (meth) = nreverse (arg_types);
3096 node = build_tree_list (id, meth);
3101 unresolved_type_p (wfl, returned)
3106 if (TREE_CODE (wfl) == EXPR_WITH_FILE_LOCATION)
3108 tree decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (wfl));
3110 *returned = (decl ? TREE_TYPE (decl) : NULL_TREE);
3118 /* From NAME, build a qualified identifier node using the
3119 qualification from the current package definition. */
3122 parser_qualified_classname (name)
3126 return merge_qualified_name (ctxp->package, EXPR_WFL_NODE (name));
3128 return EXPR_WFL_NODE (name);
3131 /* Called once the type a interface extends is resolved. Returns 0 if
3132 everything is OK. */
3135 parser_check_super_interface (super_decl, this_decl, this_wfl)
3136 tree super_decl, this_decl, this_wfl;
3138 tree super_type = TREE_TYPE (super_decl);
3140 /* Has to be an interface */
3141 if (!CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (super_decl))))
3144 (this_wfl, "Can't use %s `%s' to implement/extend %s `%s'",
3145 (TYPE_ARRAY_P (super_type) ? "array" : "class"),
3146 IDENTIFIER_POINTER (DECL_NAME (super_decl)),
3147 (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (this_decl))) ?
3148 "interface" : "class"),
3149 IDENTIFIER_POINTER (DECL_NAME (this_decl)));
3153 /* Check scope: same package OK, other package: OK if public */
3154 if (check_pkg_class_access (DECL_NAME (super_decl), lookup_cl (this_decl)))
3157 SOURCE_FRONTEND_DEBUG (("Completing interface %s with %s",
3158 IDENTIFIER_POINTER (DECL_NAME (this_decl)),
3159 IDENTIFIER_POINTER (DECL_NAME (super_decl))));
3163 /* Makes sure that SUPER_DECL is suitable to extend THIS_DECL. Returns
3164 0 if everthing is OK. */
3167 parser_check_super (super_decl, this_decl, wfl)
3168 tree super_decl, this_decl, wfl;
3170 tree super_type = TREE_TYPE (super_decl);
3172 /* SUPER should be a CLASS (neither an array nor an interface) */
3173 if (TYPE_ARRAY_P (super_type) || CLASS_INTERFACE (TYPE_NAME (super_type)))
3176 (wfl, "Class `%s' can't subclass %s `%s'",
3177 IDENTIFIER_POINTER (DECL_NAME (this_decl)),
3178 (CLASS_INTERFACE (TYPE_NAME (super_type)) ? "interface" : "array"),
3179 IDENTIFIER_POINTER (DECL_NAME (super_decl)));
3183 if (CLASS_FINAL (TYPE_NAME (super_type)))
3185 parse_error_context (wfl, "Can't subclass final classes: %s",
3186 IDENTIFIER_POINTER (DECL_NAME (super_decl)));
3190 /* Check scope: same package OK, other package: OK if public */
3191 if (check_pkg_class_access (DECL_NAME (super_decl), wfl))
3194 SOURCE_FRONTEND_DEBUG (("Completing class %s with %s",
3195 IDENTIFIER_POINTER (DECL_NAME (this_decl)),
3196 IDENTIFIER_POINTER (DECL_NAME (super_decl))));
3200 /* Create a new dependency list and link it (in a LIFO manner) to the
3201 CTXP list of type dependency list. */
3204 create_jdep_list (ctxp)
3205 struct parser_ctxt *ctxp;
3207 jdeplist *new = malloc (sizeof (jdeplist));
3210 fatal ("Can't alloc jdeplist - create_jdep_list");
3212 new->first = new->last = NULL;
3213 new->next = ctxp->classd_list;
3214 ctxp->classd_list = new;
3218 reverse_jdep_list (ctxp)
3219 struct parser_ctxt *ctxp;
3221 register jdeplist *prev = NULL, *current, *next;
3222 for (current = ctxp->classd_list; current; current = next)
3224 next = current->next;
3225 current->next = prev;
3231 /* Create a fake pointer based on the ID stored in the WFL */
3234 obtain_incomplete_type (wfl)
3238 tree name = EXPR_WFL_NODE (wfl);
3240 for (ptr = ctxp->incomplete_class; ptr; ptr = TREE_CHAIN (ptr))
3241 if (TYPE_NAME (TREE_PURPOSE (ptr)) == name)
3247 push_obstacks (&permanent_obstack, &permanent_obstack);
3248 BUILD_PTR_FROM_NAME (core, name);
3249 ptr = build_tree_list (core, NULL_TREE);
3251 TREE_CHAIN (ptr) = ctxp->incomplete_class;
3252 ctxp->incomplete_class = ptr;
3258 /* Register a incomplete type whose name is WFL. Reuse PTR if PTR is
3259 non NULL instead of computing a new fake type based on WFL. The new
3260 dependency is inserted in the current type dependency list, in FIFO
3264 register_incomplete_type (kind, wfl, decl, ptr)
3266 tree wfl, decl, ptr;
3268 jdep *new = malloc (sizeof (jdep));
3271 fatal ("Can't allocate new jdep - register_incomplete_type");
3272 if (!ptr && kind != JDEP_METHOD_END) /* JDEP_METHOD_END is a mere marker */
3273 ptr = obtain_incomplete_type (wfl);
3275 JDEP_KIND (new) = kind;
3276 JDEP_DECL (new) = decl;
3277 JDEP_SOLV (new) = ptr;
3278 JDEP_WFL (new) = wfl;
3279 JDEP_CHAIN (new) = NULL;
3280 JDEP_MISC (new) = NULL_TREE;
3281 JDEP_GET_PATCH (new) = (tree *)NULL;
3283 JDEP_INSERT (ctxp->classd_list, new);
3289 java_check_circular_reference ()
3292 for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
3294 tree type = TREE_TYPE (current);
3295 if (CLASS_INTERFACE (TYPE_NAME (type)))
3297 /* Check all interfaces this class extends */
3298 tree basetype_vec = TYPE_BINFO_BASETYPES (type);
3303 n = TREE_VEC_LENGTH (basetype_vec);
3304 for (i = 0; i < n; i++)
3306 tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
3307 if (vec_elt && BINFO_TYPE (vec_elt) != object_type_node
3308 && interface_of_p (type, BINFO_TYPE (vec_elt)))
3309 parse_error_context (lookup_cl (current),
3310 "Cyclic interface inheritance");
3314 if (inherits_from_p (CLASSTYPE_SUPER (type), type))
3315 parse_error_context (lookup_cl (current),
3316 "Cyclic class inheritance");
3321 safe_layout_class (class)
3324 tree save_current_class = current_class;
3325 char *save_input_filename = input_filename;
3326 int save_lineno = lineno;
3328 push_obstacks (&permanent_obstack, &permanent_obstack);
3329 layout_class (class);
3332 current_class = save_current_class;
3333 input_filename = save_input_filename;
3334 lineno = save_lineno;
3335 CLASS_LOADED_P (class) = 1;
3339 jdep_resolve_class (dep)
3344 if (!JDEP_RESOLVED_P (dep))
3347 resolve_class (JDEP_TO_RESOLVE (dep), JDEP_DECL (dep), JDEP_WFL (dep));
3348 JDEP_RESOLVED (dep, decl);
3351 decl = JDEP_RESOLVED_DECL (dep);
3355 complete_class_report_errors (dep);
3361 /* Complete unsatisfied class declaration and their dependencies */
3364 java_complete_class ()
3371 push_obstacks (&permanent_obstack, &permanent_obstack);
3373 /* Process imports and reverse the import on demand list */
3375 if (ctxp->import_demand_list)
3376 ctxp->import_demand_list = nreverse (ctxp->import_demand_list);
3378 /* Rever things so we have the right order */
3379 ctxp->class_list = nreverse (ctxp->class_list);
3380 ctxp->classd_list = reverse_jdep_list (ctxp);
3382 for (cclassd = ctxp->classd_list, cclass = ctxp->class_list;
3384 cclass = TREE_CHAIN (cclass), cclassd = CLASSD_CHAIN (cclassd))
3387 for (dep = CLASSD_FIRST (cclassd); dep; dep = JDEP_CHAIN (dep))
3391 if (!(decl = jdep_resolve_class (dep)))
3394 /* Now it's time to patch */
3395 switch (JDEP_KIND (dep))
3398 /* Simply patch super */
3399 if (parser_check_super (decl, JDEP_DECL (dep), JDEP_WFL (dep)))
3401 BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO
3402 (TREE_TYPE (JDEP_DECL (dep)))), 0)) = TREE_TYPE (decl);
3407 /* We do part of the job done in add_field */
3408 tree field_decl = JDEP_DECL (dep);
3409 tree field_type = TREE_TYPE (decl);
3410 push_obstacks (&permanent_obstack, &permanent_obstack);
3411 if (TREE_CODE (field_type) == RECORD_TYPE)
3412 field_type = promote_type (field_type);
3414 TREE_TYPE (field_decl) = field_type;
3415 SOURCE_FRONTEND_DEBUG
3416 (("Completed field/var decl `%s' with `%s'",
3417 IDENTIFIER_POINTER (DECL_NAME (field_decl)),
3418 IDENTIFIER_POINTER (DECL_NAME (decl))));
3421 case JDEP_METHOD: /* We start patching a method */
3422 case JDEP_METHOD_RETURN:
3428 type = TREE_TYPE(decl);
3429 if (TREE_CODE (type) == RECORD_TYPE)
3430 type = promote_type (type);
3431 JDEP_APPLY_PATCH (dep, type);
3432 SOURCE_FRONTEND_DEBUG
3433 (((JDEP_KIND (dep) == JDEP_METHOD_RETURN ?
3434 "Completing fct `%s' with ret type `%s'":
3435 "Completing arg `%s' with type `%s'"),
3436 IDENTIFIER_POINTER (EXPR_WFL_NODE
3437 (JDEP_DECL_WFL (dep))),
3438 IDENTIFIER_POINTER (DECL_NAME (decl))));
3442 dep = JDEP_CHAIN (dep);
3443 if (JDEP_KIND (dep) == JDEP_METHOD_END)
3446 decl = jdep_resolve_class (dep);
3450 tree mdecl = JDEP_DECL (dep), signature;
3451 push_obstacks (&permanent_obstack, &permanent_obstack);
3452 /* Recompute and reset the signature */
3453 signature = build_java_signature (TREE_TYPE (mdecl));
3454 set_java_signature (TREE_TYPE (mdecl), signature);
3461 case JDEP_INTERFACE:
3462 if (parser_check_super_interface (decl, JDEP_DECL (dep),
3465 parser_add_interface (JDEP_DECL (dep), decl, JDEP_WFL (dep));
3470 type = TREE_TYPE(decl);
3471 if (TREE_CODE (type) == RECORD_TYPE)
3472 type = promote_type (type);
3473 JDEP_APPLY_PATCH (dep, type);
3477 JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
3478 SOURCE_FRONTEND_DEBUG
3479 (("Completing a random type dependency on a '%s' node",
3480 tree_code_name [TREE_CODE (JDEP_DECL (dep))]));
3483 case JDEP_EXCEPTION:
3484 /* Check for righteous inheritance here */
3485 if (!inherits_from_p (TREE_TYPE (decl), throwable_type_node))
3488 (JDEP_WFL (dep), "Class `%s' in `throws' clause must be "
3489 "a subclass of class `java.lang.Throwable'",
3490 IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))));
3494 JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
3495 SOURCE_FRONTEND_DEBUG
3496 (("Completing `%s' `throws' argument node",
3497 IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)))));
3502 fatal ("Can't handle patch code %d - java_complete_class",
3511 /* Resolve class CLASS_TYPE. Handle the case of trying to resolve an
3515 resolve_class (class_type, decl, cl)
3516 tree class_type, decl, cl;
3518 char *name = IDENTIFIER_POINTER (TYPE_NAME (class_type));
3520 tree resolved_type, resolved_type_decl;
3522 /* 1- Check to see if we have an array. If true, find what we really
3524 while (name[0] == '[')
3527 TYPE_NAME (class_type) = get_identifier (name);
3529 /* 2- Resolve the bare type */
3530 if (!(resolved_type_decl = do_resolve_class (class_type, decl, cl)))
3532 resolved_type = TREE_TYPE (resolved_type_decl);
3534 /* 3- If we have and array, reconstruct the array down to its nesting */
3537 while (base != name)
3539 if (TREE_CODE (resolved_type) == RECORD_TYPE)
3540 resolved_type = promote_type (resolved_type);
3541 resolved_type = build_java_array_type (resolved_type, -1);
3544 /* Build a fake decl for this, since this is what is expected to
3546 resolved_type_decl =
3547 build_decl (TYPE_DECL, TYPE_NAME (resolved_type), resolved_type);
3548 /* Figure how those two things are important for error report. FIXME */
3549 DECL_SOURCE_LINE (resolved_type_decl) = 0;
3550 DECL_SOURCE_FILE (resolved_type_decl) = input_filename;
3552 return resolved_type_decl;
3555 /* Effectively perform the resolution of class CLASS_TYPE. DECL or CL
3556 are used to report error messages. */
3559 do_resolve_class (class_type, decl, cl)
3564 tree new_class_decl;
3565 tree original_name = NULL_TREE;
3567 /* Do not try to replace TYPE_NAME (class_type) by a variable, since
3568 its is changed by find_in_imports{_on_demand} */
3570 /* 1- Check for the type in single imports */
3571 if (find_in_imports (class_type))
3574 /* 2- And check for the type in the current compilation unit. If it fails,
3575 try with a name qualified with the package name if appropriate. */
3577 if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
3579 if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
3580 !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
3581 load_class (TYPE_NAME (class_type), 0);
3582 return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
3585 original_name = TYPE_NAME (class_type);
3586 if (!QUALIFIED_P (TYPE_NAME (class_type)) && ctxp->package)
3587 TYPE_NAME (class_type) = merge_qualified_name (ctxp->package,
3588 TYPE_NAME (class_type));
3589 if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
3591 if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
3592 !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
3593 load_class (TYPE_NAME (class_type), 0);
3594 return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
3596 TYPE_NAME (class_type) = original_name;
3598 /* 3- Check an other compilation unit that bears the name of type */
3599 load_class (TYPE_NAME (class_type), 0);
3600 if (check_pkg_class_access (TYPE_NAME (class_type),
3601 (cl ? cl : lookup_cl (decl))))
3604 if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
3605 return new_class_decl;
3607 /* 4- Check the import on demands. Don't allow bar.baz to be
3608 imported from foo.* */
3609 if (!QUALIFIED_P (TYPE_NAME (class_type)))
3610 if (find_in_imports_on_demand (class_type))
3613 /* 5- Last call for a resolution */
3614 return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
3617 /* Resolve NAME and lay it out (if not done and if not the current
3618 parsed class). Return a decl node. */
3621 resolve_and_layout (name, cl)
3625 tree decl = resolve_no_layout (name, cl);
3626 if (decl && TREE_TYPE (decl) != current_class
3627 && !CLASS_LOADED_P (TREE_TYPE (decl)))
3628 safe_layout_class (TREE_TYPE (decl));
3632 /* Resolve a class, returns its decl but doesn't perform any
3633 layout. The current parsing context is saved and restored */
3636 resolve_no_layout (name, cl)
3640 BUILD_PTR_FROM_NAME (ptr, name);
3641 java_parser_context_save_global ();
3642 decl = resolve_class (ptr, NULL_TREE, cl);
3643 java_parser_context_restore_global ();
3648 /* Called to report errors. Skip leader '[' in a complex array type
3649 description that failed to be resolved. */
3652 purify_type_name (name)
3655 while (*name && *name == '[')
3660 /* The type CURRENT refers to can't be found. We print error messages. */
3663 complete_class_report_errors (dep)
3666 switch (JDEP_KIND (dep))
3670 (JDEP_WFL (dep), "Superclass `%s' of class `%s' not found",
3671 IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))),
3672 IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
3676 (JDEP_WFL (dep), "Type `%s' not found in declaration of field `%s'",
3677 IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))),
3678 IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
3680 case JDEP_METHOD: /* Covers arguments */
3682 (JDEP_WFL (dep), "Type `%s' not found in the declaration of the "
3683 "argument `%s' of method `%s'",
3684 IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))),
3685 IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))),
3686 IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_MISC (dep))));
3688 case JDEP_METHOD_RETURN: /* Covers return type */
3690 (JDEP_WFL (dep), "Type `%s' not found in the declaration of the "
3691 "return type of method `%s'",
3692 IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))),
3693 IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))));
3695 case JDEP_INTERFACE:
3697 (JDEP_WFL (dep), "Superinterface `%s' of %s `%s' not found",
3698 IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))),
3699 (CLASS_OR_INTERFACE (JDEP_DECL (dep), "class", "interface")),
3700 IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
3704 (JDEP_WFL (dep), "Type `%s' not found in the declaration of the "
3705 "local variable `%s'",
3706 purify_type_name (IDENTIFIER_POINTER
3707 (EXPR_WFL_NODE (JDEP_WFL (dep)))),
3708 IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
3710 case JDEP_EXCEPTION: /* As specified by `throws' */
3712 (JDEP_WFL (dep), "Class `%s' not found in `throws'",
3713 IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))));
3716 /* Fix for -Wall. Just break doing nothing. The error will be
3722 /* Check uninitialized final. */
3730 check_method_redefinition (class, method)
3734 tree cl = DECL_NAME (method);
3735 tree sig = TYPE_LANG_SPECIFIC (TREE_TYPE (method))->signature;
3736 /* decl name of generated <clinit> doesn't need to be fixed and
3738 if (DECL_NAME (method) != clinit_identifier_node)
3740 /* NAME is just the plain name when Object is being defined */
3741 if (class != object_type_node)
3742 name = DECL_NAME (method) = EXPR_WFL_NODE (DECL_NAME (method));
3744 name = DECL_NAME (method);
3749 for (redef = TYPE_METHODS (class); redef; redef = TREE_CHAIN (redef))
3751 struct lang_type *t = TYPE_LANG_SPECIFIC (TREE_TYPE (redef));
3753 if (! t || (redef == method))
3755 if (DECL_NAME (redef) == name && sig == t->signature)
3757 parse_error_context (cl, "Duplicate method declaration");
3764 /* Check all the methods of CLASS. Methods are first completed then
3765 checked according to regular method existance rules.
3766 If no constructor were encountered, then build its declaration. */
3769 java_check_regular_methods (class_decl)
3773 tree class = CLASS_TO_HANDLE_TYPE (TREE_TYPE (class_decl));
3774 tree super_class = CLASSTYPE_SUPER (class);
3775 int seen_constructor = 0;
3777 TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
3779 /* Should take interfaces into account. FIXME */
3780 for (method = TYPE_METHODS (class); method; method = TREE_CHAIN (method))
3783 tree method_wfl = DECL_NAME (method);
3786 if (DECL_CONSTRUCTOR_P (method))
3787 seen_constructor = 1;
3789 /* Check for redefinitions */
3790 if (check_method_redefinition (class, method))
3793 sig = build_java_argument_signature (TREE_TYPE (method));
3795 found = lookup_argument_method (super_class, DECL_NAME (method), sig);
3797 /* Nothing overrides or it's a private method */
3798 if (!found || (found && METHOD_PRIVATE (found)))
3800 /* Can't override a method with the same name and different return
3802 if (TREE_TYPE (TREE_TYPE (found)) != TREE_TYPE (TREE_TYPE (method)))
3804 char *t = strdup (lang_printable_name (TREE_TYPE (TREE_TYPE (found)),
3808 "Method `%s' was defined with return type `%s' in class `%s'",
3809 lang_printable_name (found, 0), t,
3811 (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
3815 /* Can't override final. Can't override static. */
3816 if (METHOD_FINAL (found) || METHOD_STATIC (found))
3818 /* Static *can* override static */
3819 if (METHOD_STATIC (found) && METHOD_STATIC (method))
3823 "%s methods can't be overriden. Method `%s' is %s in class `%s'",
3824 (METHOD_FINAL (found) ? "Final" : "Static"),
3825 lang_printable_name (found, 0),
3826 (METHOD_FINAL (found) ? "final" : "static"),
3828 (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
3831 /* Static method can't override instance method. */
3832 if (METHOD_STATIC (method))
3836 "Instance methods can't be overriden by a static method. Method "
3837 "`%s' is an instance method in class `%s'",
3838 lang_printable_name (found, 0),
3840 (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
3843 /* Overriding/hiding public must be public or
3844 overriding/hiding protected must be protected or public */
3845 if ((METHOD_PUBLIC (found) && !METHOD_PUBLIC (method)) ||
3846 (METHOD_PROTECTED (found)
3847 && !(METHOD_PUBLIC (method) || METHOD_PROTECTED (method))))
3851 "Methods can't be overridden to be more private. Method `%s' is "
3852 "%s in class `%s'", lang_printable_name (found, 0),
3853 (METHOD_PUBLIC (found) ? "public" : "protected"),
3855 (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
3859 /* Overriding methods must have compatible `throws' clauses on checked
3860 exceptions, if any */
3861 check_throws_clauses (method, method_wfl, found);
3863 /* If the method has default access in an other package, then
3864 issue a warning that the current method doesn't override the
3865 one that was found elsewhere */
3866 aflags = get_access_flags_from_decl (found);
3867 if ((!aflags || (aflags > ACC_PROTECTED))
3868 && !class_in_current_package (DECL_CONTEXT (found)))
3869 parse_warning_context
3870 (method_wfl, "Method `%s' in class `%s' does not "
3871 "override the corresponding method in class `%s', which is "
3872 "private to a different package",
3873 lang_printable_name (found, 0),
3874 IDENTIFIER_POINTER (DECL_NAME (class_decl)),
3875 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
3877 /* Check on (default) package access. FIXME. */
3878 /* Inheriting multiple methods with the same signature. FIXME */
3881 TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
3883 if (!seen_constructor)
3885 /* No constructor seen, we craft one, at line 0 */
3886 int saved_lineno = lineno;
3889 meth = make_node (FUNCTION_TYPE);
3890 TREE_TYPE (meth) = void_type_node;
3891 TYPE_ARG_TYPES (meth) = NULL_TREE;
3892 decl = add_method (class, 0, init_identifier_node,
3893 build_java_signature (meth));
3894 DECL_CONSTRUCTOR_P (decl) = 1;
3895 lineno = saved_lineno;
3899 /* Return a non zero value if the `throws' clause of METHOD (if any)
3900 is incompatible with the `throws' clause of FOUND (if any). */
3903 check_throws_clauses (method, method_wfl, found)
3904 tree method, method_wfl, found;
3906 tree mthrows, fthrows;
3908 for (mthrows = DECL_FUNCTION_THROWS (method);
3909 mthrows; mthrows = TREE_CHAIN (mthrows))
3911 /* We don't verify unchecked expressions */
3912 if (IS_UNCHECKED_EXPRESSION_P (TREE_VALUE (mthrows)))
3914 /* Checked expression must be compatible */
3915 for (fthrows = DECL_FUNCTION_THROWS (found);
3916 fthrows; fthrows = TREE_CHAIN (fthrows))
3917 if (inherits_from_p (TREE_VALUE (mthrows), TREE_VALUE (fthrows)))
3922 (method_wfl, "Invalid checked exception class `%s' in "
3923 "`throws' clause. The exception must be a subclass of an "
3924 "exception thrown by `%s' from class `%s'",
3925 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))),
3926 lang_printable_name (found, 0),
3928 (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
3933 /* Check abstract method of interface INTERFACE */
3936 java_check_abstract_methods (interface)
3940 tree method, basetype_vec, found;
3942 for (method = TYPE_METHODS (interface); method; method = TREE_CHAIN (method))
3944 tree method_wfl = DECL_NAME (method);
3946 /* 2- Check for double definition inside the defining interface */
3947 if (check_method_redefinition (interface, method))
3950 /* 3- Overriding is OK as far as we preserve the return type and
3951 the thrown exceptions (FIXME) */
3952 found = lookup_java_interface_method2 (interface, method);
3955 char *t = strdup (lang_printable_name (TREE_TYPE (TREE_TYPE (found)),
3959 "Method `%s' was defined with return type `%s' in class `%s ",
3960 lang_printable_name (found, 0), t,
3962 (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
3968 /* 4- Inherited methods can't differ by their returned types */
3969 if (!(basetype_vec = TYPE_BINFO_BASETYPES (interface)))
3971 n = TREE_VEC_LENGTH (basetype_vec);
3972 for (i = 0; i < n; i++)
3974 tree sub_interface_method, sub_interface;
3975 tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
3978 sub_interface = BINFO_TYPE (vec_elt);
3979 for (sub_interface_method = TYPE_METHODS (sub_interface);
3980 sub_interface_method;
3981 sub_interface_method = TREE_CHAIN (sub_interface_method))
3983 found = lookup_java_interface_method2 (interface,
3984 sub_interface_method);
3985 if (found && (found != sub_interface_method))
3987 (lookup_cl (sub_interface_method),
3988 "Interface `%s' inherits method `%s' from interface `%s'. This "
3989 "method is redefined with a different return "
3990 "type in interface `%s'",
3991 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (interface))),
3992 lang_printable_name (found, 0),
3994 (DECL_NAME (TYPE_NAME (DECL_CONTEXT (sub_interface_method)))),
3996 (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
4001 /* Check the method on all the defined classes. Should be done to the
4002 classes declared in the compilation unit only. FIXME */
4005 java_check_methods ()
4009 for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
4010 if (CLASS_FROM_SOURCE_P (TREE_TYPE (current)))
4012 tree class = CLASS_TO_HANDLE_TYPE (TREE_TYPE (current));
4014 if (CLASS_INTERFACE (TYPE_NAME (class)))
4015 java_check_abstract_methods (class);
4017 java_check_regular_methods (current);
4021 /* Lookup methods in interfaces using their name and partial
4022 signature. Return a matching method only if their types differ. */
4025 lookup_java_interface_method2 (class, method_decl)
4026 tree class, method_decl;
4029 tree basetype_vec = TYPE_BINFO_BASETYPES (class), to_return;
4034 n = TREE_VEC_LENGTH (basetype_vec);
4035 for (i = 0; i < n; i++)
4037 tree vec_elt = TREE_VEC_ELT (basetype_vec, i), to_return;
4038 if ((BINFO_TYPE (vec_elt) != object_type_node)
4040 lookup_java_method2 (BINFO_TYPE (vec_elt), method_decl, 1)))
4043 for (i = 0; i < n; i++)
4045 to_return = lookup_java_interface_method2
4046 (BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i)), method_decl);
4054 /* Lookup method using their name and partial signature. Return a
4055 matching method only if their types differ. */
4058 lookup_java_method2 (clas, method_decl, do_interface)
4059 tree clas, method_decl;
4062 tree method, method_signature, method_name, method_type;
4063 method_signature = build_java_argument_signature (TREE_TYPE (method_decl));
4064 method_name = DECL_NAME (method_decl);
4065 method_type = TREE_TYPE (TREE_TYPE (method_decl));
4067 while (clas != NULL_TREE)
4069 for (method = TYPE_METHODS (clas);
4070 method != NULL_TREE; method = TREE_CHAIN (method))
4072 tree method_sig = build_java_argument_signature (TREE_TYPE (method));
4073 if (DECL_NAME (method) == method_name
4074 && method_sig == method_signature
4075 && TREE_TYPE (TREE_TYPE (method)) != method_type)
4080 clas = (do_interface ? NULL_TREE : CLASSTYPE_SUPER (clas));
4085 /* Return the line that matches DECL line number. Used during error
4092 static tree cl = NULL_TREE;
4097 if (cl == NULL_TREE)
4098 cl = build_expr_wfl (NULL_TREE, NULL, 0, 0);
4100 EXPR_WFL_FILENAME_NODE (cl) = get_identifier (DECL_SOURCE_FILE (decl));
4101 EXPR_WFL_SET_LINECOL (cl, DECL_SOURCE_LINE_FIRST (decl), -1);
4106 /* Look for a simple name in the single-type import list */
4109 find_name_in_single_imports (name)
4114 for (node = ctxp->import_list; node; node = TREE_CHAIN (node))
4115 if (TREE_VALUE (node) == name)
4116 return (EXPR_WFL_NODE (TREE_PURPOSE (node)));
4121 /* Process all single-type import. */
4129 for (import = ctxp->import_list; import; import = TREE_CHAIN (import))
4131 tree to_be_found = EXPR_WFL_NODE (TREE_PURPOSE (import));
4133 /* Don't load twice something already defined. */
4134 if (IDENTIFIER_CLASS_VALUE (to_be_found))
4136 QUALIFIED_P (to_be_found) = 1;
4137 load_class (to_be_found, 0);
4139 check_pkg_class_access (to_be_found, TREE_PURPOSE (import));
4140 if (!IDENTIFIER_CLASS_VALUE (to_be_found))
4142 parse_error_context (TREE_PURPOSE (import),
4143 "Class or interface `%s' not found in import",
4144 IDENTIFIER_POINTER (to_be_found));
4153 /* Possibly find a class imported by a single-type import statement. Return
4154 1 if an error occured, 0 otherwise. */
4157 find_in_imports (class_type)
4162 for (import = ctxp->import_list; import; import = TREE_CHAIN (import))
4163 if (TREE_VALUE (import) == TYPE_NAME (class_type))
4165 TYPE_NAME (class_type) = EXPR_WFL_NODE (TREE_PURPOSE (import));
4166 QUALIFIED_P (TYPE_NAME (class_type)) = 1;
4167 return check_pkg_class_access (TYPE_NAME (class_type),
4168 TREE_PURPOSE (import));
4173 /* Process a import on demand statement (lazy) */
4176 read_import_entry (jcf, dirp, returned_name)
4179 char **returned_name;
4183 struct dirent *direntp = readdir (dirp);
4186 *returned_name = NULL;
4191 *returned_name = direntp->d_name;
4192 return (strlen (direntp->d_name));
4197 int current_dir_len = strlen (jcf->classname);
4198 char *current_entry;
4199 int current_entry_len;
4201 /* Here we read a zip directory as a file directory. The files
4202 we're selecting must have the same root than the directory
4205 ZipDirectory *zipd = (ZipDirectory *)jcf->zipd;
4209 current_entry = ZIPDIR_FILENAME (zipd);
4210 current_entry_len = zipd->filename_length;
4211 while (current_entry_len && current_entry [current_entry_len] != '/')
4212 current_entry_len--;
4213 /* If the path of the current file doesn't match the directory we're
4214 scanning, that the end of the search */
4215 current_entry_len++;
4216 if (strncmp (jcf->classname, current_entry, current_dir_len))
4218 *returned_name = NULL;
4221 /* Ok, we have at least the same path. The position of the last '/'
4222 of the current file we're examining should match the size of
4223 name of the directory we're browsing, otherwise that an entry
4224 belonging to a sub directory, we want to skip it. */
4225 if (current_entry_len != current_dir_len)
4226 zipd = ZIPDIR_NEXT (zipd);
4229 jcf->zipd = ZIPDIR_NEXT (zipd); /* Prepare next read */
4230 *returned_name = ¤t_entry [current_entry_len];
4231 return (zipd->filename_length - current_entry_len);
4234 *returned_name = NULL;
4239 /* Read a import directory, gathering potential match for further type
4240 references. Indifferently reads a filesystem or a ZIP archive
4244 read_import_dir (wfl)
4247 char *name = IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl));
4248 int name_len = IDENTIFIER_LENGTH (EXPR_WFL_NODE (wfl)), reclen;
4250 JCF jcfr, *jcf, *saved_jcf = current_jcf;
4251 char *founddirname, *d_name;
4256 if (!(founddirname = find_class (name, name_len, jcf, 0)))
4257 fatal ("Can't import `%s'", name);
4258 if (jcf->outofsynch)
4259 jcf_out_of_synch (jcf);
4260 if (jcf->seen_in_zip)
4261 jcf->zipd = ZIPDIR_NEXT ((ZipDirectory *)jcf->zipd);
4263 else if (founddirname && (dirp = opendir (founddirname)))
4265 readdir (dirp); readdir (dirp);
4268 if (!founddirname && !dirp)
4270 static int first = 1;
4274 sprintf (buffer, "Can't find default package `%s'. Check "
4275 "the CLASSPATH environment variable and the access to the "
4282 parse_error_context (wfl, "Package `%s' not found in import", name);
4283 current_jcf = saved_jcf;
4287 /* Here we should have a unified way of retrieving an entry, to be
4289 while ((reclen = read_import_entry (jcf, dirp, &d_name)))
4291 int java_or_class = 0;
4294 && !strcmp (&d_name [reclen-5], ".java"))
4300 if (!java_or_class && (reclen > 6) &&
4301 !strcmp (&d_name [reclen-6], ".class"))
4312 obstack_grow (&temporary_obstack, name, name_len);
4313 obstack_1grow (&temporary_obstack, '/');
4314 obstack_grow0 (&temporary_obstack, d_name, len);
4315 id_name = obstack_finish (&temporary_obstack);
4317 node = get_identifier (id_name);
4318 IS_A_CLASSFILE_NAME (node) = 1; /* Or soon to be */
4319 QUALIFIED_P (node) = 1; /* As soon as we turn / into . */
4325 current_jcf = saved_jcf;
4328 /* Possibly find a type in the import on demands specified
4329 types. Returns 1 if an error occured, 0 otherwise. Run throught the
4330 entire list, to detected potential double definitions. */
4333 find_in_imports_on_demand (class_type)
4336 tree node, import, node_to_use;
4340 for (import = ctxp->import_demand_list; import; import = TREE_CHAIN (import))
4343 obstack_grow (&temporary_obstack,
4344 IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))),
4345 IDENTIFIER_LENGTH (EXPR_WFL_NODE (TREE_PURPOSE (import))));
4346 obstack_1grow (&temporary_obstack, '/');
4347 obstack_grow0 (&temporary_obstack,
4348 IDENTIFIER_POINTER (TYPE_NAME (class_type)),
4349 IDENTIFIER_LENGTH (TYPE_NAME (class_type)));
4350 id_name = obstack_finish (&temporary_obstack);
4352 node = maybe_get_identifier (id_name);
4353 if (node && IS_A_CLASSFILE_NAME (node))
4357 cl = TREE_PURPOSE (import);
4365 (import, "Type `%s' also potentially defined in package `%s'",
4366 IDENTIFIER_POINTER (TYPE_NAME (class_type)),
4367 IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))));
4374 /* Setup lineno so that it refers to the line of the import (in
4375 case we parse a class file and encounter errors */
4377 int saved_lineno = lineno;
4378 lineno = EXPR_WFL_LINENO (cl);
4379 TYPE_NAME (class_type) = ident_subst (IDENTIFIER_POINTER (node_to_use),
4380 IDENTIFIER_LENGTH (node_to_use),
4382 QUALIFIED_P (TYPE_NAME (class_type)) = 1;
4383 decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
4384 /* If there is no DECL set for the class or if the class isn't
4385 loaded and not seen in source yet, the load */
4386 if (!decl || (!CLASS_LOADED_P (TREE_TYPE (decl))
4387 && !CLASS_FROM_SOURCE_P (TREE_TYPE (decl))))
4388 load_class (node_to_use, 0);
4389 lineno = saved_lineno;
4390 return check_pkg_class_access (TYPE_NAME (class_type), cl);
4393 return (seen_once < 0 ? 0 : seen_once); /* It's ok not to have found */
4396 /* Check that CLASS_NAME refers to a PUBLIC class. Return 0 if no
4397 access violations were found, 1 otherwise. */
4400 check_pkg_class_access (class_name, cl)
4406 if (!QUALIFIED_P (class_name) || !IDENTIFIER_CLASS_VALUE (class_name))
4409 if (!(type = TREE_TYPE (IDENTIFIER_CLASS_VALUE (class_name))))
4412 if (!CLASS_PUBLIC (TYPE_NAME (type)))
4415 (cl, "Can't access %s `%s'. Only public classes and interfaces in "
4416 "other packages can be accessed",
4417 (CLASS_INTERFACE (TYPE_NAME (type)) ? "interface" : "class"),
4418 IDENTIFIER_POINTER (class_name));
4424 /* Local variable declaration. */
4427 declare_local_variables (modifier, type, vlist)
4432 tree decl, current, returned_type, type_wfl;
4435 /* Push a new block if statement were seen between the last time we
4436 pushed a block and now. Keep a cound of block to close */
4437 if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (current_function_decl)))
4439 tree body = DECL_FUNCTION_BODY (current_function_decl);
4440 tree b = enter_block ();
4441 BLOCK_EXPR_ORIGIN(b) = body;
4447 for (i = 0; i <= 10; i++) if (1 << i & modifier) break;
4449 (ctxp->modifier_ctx [i],
4450 (modifier == ACC_FINAL ?
4451 "Unsupported JDK1.1 `final' locals" :
4452 "Only `final' is allowed as a local variables modifier"));
4456 if (unresolved_type_p (type, &returned_type))
4459 type = returned_type;
4463 type = obtain_incomplete_type (type);
4467 if (!must_chain && TREE_CODE (type) == RECORD_TYPE)
4468 type = promote_type (type);
4470 for (current = vlist; current; current = TREE_CHAIN (current))
4472 tree wfl = TREE_PURPOSE (current);
4473 tree name = EXPR_WFL_NODE (wfl);
4474 tree init = TREE_VALUE (current);
4475 tree other = lookup_name_in_blocks (name);
4477 /* Don't try to use an INIT statement when an error was found */
4478 if (init && java_error_count)
4482 variable_redefinition_error (wfl, name, TREE_TYPE (other),
4483 DECL_SOURCE_LINE (other));
4486 /* Never layout this decl. This will be done when its scope
4488 decl = build_decl_no_layout (VAR_DECL, name, type);
4489 BLOCK_CHAIN_DECL (decl);
4491 /* Add the initialization function to the current function's code */
4494 MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
4495 java_method_add_stmt
4496 (current_function_decl,
4497 build_debugable_stmt (EXPR_WFL_LINECOL (init), init));
4503 register_incomplete_type (JDEP_VARIABLE, type_wfl, decl, type);
4504 dep = CLASSD_LAST (ctxp->classd_list);
4505 JDEP_GET_PATCH (dep) = &TREE_TYPE (decl);
4509 SOURCE_FRONTEND_DEBUG (("Defined locals"));
4512 /* Called during parsing. Build decls from argument list. */
4515 source_start_java_method (fndecl)
4522 current_function_decl = fndecl;
4524 /* New scope for the function */
4526 for (tem = TYPE_ARG_TYPES (TREE_TYPE (fndecl)), i = 0;
4527 tem != NULL_TREE; tem = TREE_CHAIN (tem), i++)
4529 tree type = TREE_VALUE (tem);
4530 tree name = TREE_PURPOSE (tem);
4532 /* If type is incomplete. Layout can't take place
4533 now. Create an incomplete decl and ask for the decl to be
4535 if (INCOMPLETE_TYPE_P (type))
4538 parm_decl = build_decl_no_layout (PARM_DECL, name, type);
4540 register_incomplete_type (JDEP_PARM, NULL_TREE, NULL_TREE, type);
4541 jdep = CLASSD_LAST (ctxp->classd_list);
4542 JDEP_MISC (jdep) = name;
4543 JDEP_GET_PATCH (jdep) = &TREE_TYPE (parm_decl);
4546 parm_decl = build_decl (PARM_DECL, name, type);
4548 BLOCK_CHAIN_DECL (parm_decl);
4550 tem = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
4551 BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl)) =
4553 DECL_ARG_SLOT_COUNT (current_function_decl) = i;
4556 /* Called during expansion. Push decls formerly built from argument
4557 list so they're usable during expansion. */
4560 expand_start_java_method (fndecl)
4565 current_function_decl = fndecl;
4567 announce_function (fndecl);
4568 pushlevel (1); /* Push parameters */
4569 ptr = &DECL_ARGUMENTS (fndecl);
4570 tem = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (current_function_decl));
4573 tree next = TREE_CHAIN (tem);
4574 tree type = TREE_TYPE (tem);
4575 #ifdef PROMOTE_PROTOTYPES
4576 if (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
4577 && INTEGRAL_TYPE_P (type))
4578 type = integer_type_node;
4580 DECL_ARG_TYPE (tem) = type;
4581 layout_decl (tem, 0);
4583 INITIALIZED_P (tem) = 1; /* Parms are initialized */
4585 ptr = &TREE_CHAIN (tem);
4589 pushdecl_force_head (DECL_ARGUMENTS (fndecl));
4590 lineno = DECL_SOURCE_LINE_FIRST (fndecl);
4591 complete_start_java_method (fndecl);
4594 /* Terminate a function and expand its body. */
4597 source_end_java_method ()
4599 tree fndecl = current_function_decl;
4601 java_parser_context_save_global ();
4602 lineno = ctxp->last_ccb_indent1;
4604 /* Set EH language codes */
4605 java_set_exception_lang_code ();
4607 /* Generate function's code */
4608 if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl))
4609 && ! flag_emit_class_files)
4610 expand_expr_stmt (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)));
4612 /* pop out of its parameters */
4613 pushdecl_force_head (DECL_ARGUMENTS (fndecl));
4615 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
4617 /* Generate rtl for function exit. */
4618 if (! flag_emit_class_files)
4620 lineno = DECL_SOURCE_LINE_LAST (fndecl);
4621 /* Emit catch-finally clauses */
4623 expand_function_end (input_filename, lineno, 0);
4625 /* Run the optimizers and output assembler code for this function. */
4626 rest_of_compilation (fndecl);
4629 current_function_decl = NULL_TREE;
4630 /* permanent_allocation (1); */
4631 java_parser_context_restore_global ();
4634 /* Record EXPR in the current function block. Complements compound
4635 expression second operand if necessary. */
4638 java_method_add_stmt (fndecl, expr)
4641 return add_stmt_to_block (DECL_FUNCTION_BODY (fndecl), NULL_TREE, expr);
4645 add_stmt_to_block (b, type, stmt)
4648 tree body = BLOCK_EXPR_BODY (b), c;
4650 if (java_error_count)
4653 if ((c = add_stmt_to_compound (body, type, stmt)) == body)
4656 BLOCK_EXPR_BODY (b) = c;
4657 TREE_SIDE_EFFECTS (c) = 1;
4661 /* Add STMT to EXISTING if possible, otherwise create a new
4662 COMPOUND_EXPR and add STMT to it. */
4665 add_stmt_to_compound (existing, type, stmt)
4666 tree existing, type, stmt;
4670 if (existing && (TREE_CODE (existing) == COMPOUND_EXPR)
4671 && TREE_OPERAND (existing, 1) == size_zero_node)
4673 TREE_OPERAND (existing, 1) = stmt;
4674 TREE_TYPE (existing) = type;
4678 node = build (COMPOUND_EXPR, type, existing, stmt);
4680 node = build (COMPOUND_EXPR, type, stmt, size_zero_node);
4685 /* Hold THIS for the scope of the current public method decl. */
4686 static tree current_this;
4688 /* Layout all class found during parsing */
4691 java_layout_classes ()
4694 for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
4696 current_class = TREE_TYPE (current);
4697 TYPE_FIELDS (current_class) = nreverse (TYPE_FIELDS (current_class));
4698 if (!TYPE_SIZE (current_class))
4699 safe_layout_class (current_class);
4703 /* Expand all methods in all registered classes. */
4706 java_complete_expand_methods ()
4710 for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
4712 tree class_type = CLASS_TO_HANDLE_TYPE (TREE_TYPE (current));
4715 current_class = TREE_TYPE (current);
4717 /* Initialize a new constant pool */
4718 init_outgoing_cpool ();
4720 /* Don't process function bodies in interfaces */
4721 if (!CLASS_INTERFACE (TYPE_NAME (current_class)))
4722 for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
4724 current_function_decl = decl;
4725 /* Don't generate debug info on line zero when expanding a
4726 generated constructor. */
4727 if (DECL_CONSTRUCTOR_P (decl) && !DECL_FUNCTION_BODY (decl))
4729 /* If we found errors, it's too dangerous to try to generate
4730 and expand a constructor */
4731 if (!java_error_count)
4733 restore_line_number_status (1);
4734 java_complete_expand_method (decl);
4735 restore_line_number_status (0);
4739 java_complete_expand_method (decl);
4742 /* Make the class data, register it and run the rest of decl
4743 compilation on it */
4744 if (!java_error_count && ! flag_emit_class_files)
4746 make_class_data (current_class);
4748 rest_of_decl_compilation (TYPE_NAME (current_class), (char*) 0, 1, 0);
4753 /* Hold a list of catch clauses list. The first element of this list is
4754 the list of the catch clauses of the currently analysed try block. */
4755 static tree currently_caught_type_list;
4757 /* Complete and expand a method. */
4760 java_complete_expand_method (mdecl)
4763 int no_ac_found = 1;
4765 /* We generate some code for an empty constructor */
4766 if (DECL_CONSTRUCTOR_P (mdecl) && !DECL_FUNCTION_BODY (mdecl))
4768 tree arg_list, func, call;
4769 tree method_type = TREE_TYPE (mdecl);
4770 tree class_type = CLASS_TO_HANDLE_TYPE (current_class);
4771 tree self_type = (CLASSTYPE_SUPER (class_type) ?
4772 CLASSTYPE_SUPER (class_type) : class_type);
4773 tree method_signature =
4774 TYPE_LANG_SPECIFIC (method_type)->signature;
4776 lookup_java_constructor (CLASS_TO_HANDLE_TYPE (self_type),
4778 tree block, compound;
4780 /* Fixe the begining/ending lines of the method so that with
4781 no_line_numbers set to 1 it doesn't generate debug info at
4782 line 1 for this artificial constructor. */
4783 DECL_SOURCE_LINE (mdecl) = 1;
4784 DECL_SOURCE_LINE_MERGE (mdecl, 1);
4785 source_start_java_method (mdecl);
4786 arg_list = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl));
4788 func = build_known_method_ref (method, method_type, self_type,
4789 method_signature, arg_list);
4791 if (! flag_emit_class_files)
4792 func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
4793 call = build (CALL_EXPR, TREE_TYPE (method_type), func,
4794 build_tree_list (NULL_TREE, arg_list), NULL_TREE);
4795 TREE_SIDE_EFFECTS (call) = 1;
4796 call = build_class_init (self_type, call);
4797 compound = java_method_add_stmt (mdecl, call);
4798 block = exit_block ();
4799 BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)) = block;
4800 /* The function decl, its block and the compound statement
4801 within this block are all of void type. */
4802 TREE_TYPE (block) = TREE_TYPE (compound) =
4803 TREE_TYPE (DECL_FUNCTION_BODY (mdecl)) = void_type_node;
4808 if (DECL_FUNCTION_BODY (mdecl))
4810 expand_start_java_method (mdecl);
4813 = (!METHOD_STATIC (mdecl) ?
4814 BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl)) : NULL_TREE);
4816 /* Purge the `throws' list of unchecked exceptions */
4817 purge_unchecked_exceptions (mdecl);
4819 /* Install exceptions thrown with `throws' */
4820 PUSH_EXCEPTIONS (DECL_FUNCTION_THROWS (mdecl));
4822 if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)) && no_ac_found)
4823 java_complete_tree (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)));
4824 /* Don't go any further if we've found error(s) during the
4826 if (!java_error_count)
4827 source_end_java_method ();
4829 /* Pop the exceptions and sanity check */
4831 if (currently_caught_type_list)
4832 fatal ("Exception list non empty - java_complete_expand_method");
4836 /* Expand finals. */
4839 java_expand_finals ()
4843 /* Wrap non WFL PRIMARY around a WFL and set EXPR_WFL_QUALIFICATION to
4844 a tree list node containing RIGHT. Fore coming RIGHTs will be
4845 chained to this hook. LOCATION contains the location of the
4846 separating `.' operator. */
4849 make_qualified_primary (primary, right, location)
4850 tree primary, right;
4855 /* We want to process THIS . xxx symbolicaly, to keep it consistent
4856 with the way we're processing SUPER. A THIS from a primary as a
4857 different form than a SUPER. Turn THIS into something symbolic */
4858 if (TREE_CODE (primary) == THIS_EXPR)
4860 wfl = build_wfl_node (this_identifier_node, input_filename, 0, 0);
4861 EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (primary);
4862 wfl = make_qualified_name (wfl, right, location);
4863 PRIMARY_P (wfl) = 1;
4866 /* Other non WFL node are wrapped around a WFL */
4867 else if (TREE_CODE (primary) != EXPR_WITH_FILE_LOCATION)
4869 wfl = build_expr_wfl (NULL_TREE, ctxp->filename, 0, 0);
4870 EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (primary);
4871 EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (primary, NULL_TREE);
4876 if (!EXPR_WFL_QUALIFICATION (primary))
4877 EXPR_WFL_QUALIFICATION (primary) =
4878 build_tree_list (primary, NULL_TREE);
4881 EXPR_WFL_LINECOL (right) = location;
4882 chainon (EXPR_WFL_QUALIFICATION (wfl), build_tree_list (right, NULL_TREE));
4883 PRIMARY_P (wfl) = 1;
4887 /* Simple merge of two name separated by a `.' */
4890 merge_qualified_name (left, right)
4894 obstack_grow (&temporary_obstack, IDENTIFIER_POINTER (left),
4895 IDENTIFIER_LENGTH (left));
4896 obstack_1grow (&temporary_obstack, '.');
4897 obstack_grow0 (&temporary_obstack, IDENTIFIER_POINTER (right),
4898 IDENTIFIER_LENGTH (right));
4899 node = get_identifier (obstack_base (&temporary_obstack));
4900 obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
4901 QUALIFIED_P (node) = 1;
4905 /* Merge the two parts of a qualified name into LEFT. Set the
4906 location information of the resulting node to LOCATION, usually
4907 inherited from the location information of the `.' operator. */
4910 make_qualified_name (left, right, location)
4914 tree left_id = EXPR_WFL_NODE (left);
4915 tree right_id = EXPR_WFL_NODE (right);
4918 merge = merge_qualified_name (left_id, right_id);
4920 /* Left wasn't qualified and is now qualified */
4921 if (!QUALIFIED_P (left_id))
4923 tree wfl = build_expr_wfl (left_id, ctxp->filename, 0, 0);
4924 EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (left);
4925 EXPR_WFL_QUALIFICATION (left) = build_tree_list (wfl, NULL_TREE);
4928 wfl = build_expr_wfl (right_id, ctxp->filename, 0, 0);
4929 EXPR_WFL_LINECOL (wfl) = location;
4930 chainon (EXPR_WFL_QUALIFICATION (left), build_tree_list (wfl, NULL_TREE));
4932 EXPR_WFL_NODE (left) = merge;
4936 /* Extract the last identifier component of the qualified in WFL. The
4937 last identifier is removed from the linked list */
4940 cut_identifier_in_qualified (wfl)
4944 tree previous = NULL_TREE;
4945 for (q = EXPR_WFL_QUALIFICATION (wfl); ; previous = q, q = TREE_CHAIN (q))
4946 if (!TREE_CHAIN (q))
4949 fatal ("Operating on a non qualified qualified WFL - "
4950 "cut_identifier_in_qualified");
4951 TREE_CHAIN (previous) = NULL_TREE;
4952 return TREE_PURPOSE (q);
4956 /* Resolve the expression name NAME. Return its decl. */
4959 resolve_expression_name (id)
4962 tree name = EXPR_WFL_NODE (id);
4965 /* 6.5.5.1: Simple expression names */
4966 if (!PRIMARY_P (id) && !QUALIFIED_P (name))
4968 /* 15.13.1: NAME can appear within the scope of a local variable
4970 if ((decl = IDENTIFIER_LOCAL_VALUE (name)))
4973 /* 15.13.1: NAME can appear within a class declaration */
4976 decl = lookup_field_wrapper (current_class, name);
4979 int fs = FIELD_STATIC (decl);
4980 /* Instance variable (8.3.1.1) can't appear within
4981 static method, static initializer or initializer for
4982 a static variable. */
4983 if (!fs && METHOD_STATIC (current_function_decl))
4986 (id, "Can't make a static reference to nonstatic variable "
4987 "`%s' in class `%s'",
4988 IDENTIFIER_POINTER (name),
4989 IDENTIFIER_POINTER (DECL_NAME
4990 (TYPE_NAME (current_class))));
4991 return error_mark_node;
4993 decl = build_field_ref ((fs ? NULL_TREE : current_this),
4994 current_class, name);
4995 return (fs ? build_class_init (current_class, decl) : decl);
4997 /* Fall down to error report on undefined variable */
5000 /* 6.5.5.2 Qualified Expression Names */
5003 qualify_ambiguous_name (id);
5004 /* 15.10.1 Field Access Using a Primary and/or Expression Name */
5005 /* 15.10.2: Accessing Superclass Members using super */
5006 return resolve_field_access (id, NULL, NULL);
5009 /* We've got an error here */
5010 parse_error_context (id, "Undefined variable `%s'",
5011 IDENTIFIER_POINTER (name));
5013 return error_mark_node;
5016 /* 15.10.1 Field Acess Using a Primary and/or Expression Name.
5017 We return something suitable to generate the field access. We also
5018 return the field decl in FIELD_DECL and its type in FIELD_TYPE. If
5019 recipient's address can be null. */
5022 resolve_field_access (qual_wfl, field_decl, field_type)
5024 tree *field_decl, *field_type;
5028 tree decl, where_found, type_found;
5030 if (resolve_qualified_expression_name (qual_wfl, &decl,
5031 &where_found, &type_found))
5032 return error_mark_node;
5034 /* Resolve the LENGTH field of an array here */
5035 if (DECL_NAME (decl) == length_identifier_node && TYPE_ARRAY_P (type_found)
5036 && ! flag_emit_class_files)
5038 tree length = build_java_array_length_access (where_found);
5040 build_java_arraynull_check (type_found, length, int_type_node);
5042 /* We might have been trying to resolve field.method(). In which
5043 case, the resolution is over and decl is the answer */
5044 else if (DECL_P (decl) && IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)) == decl)
5046 else if (DECL_P (decl))
5048 is_static = DECL_P (decl) && FIELD_STATIC (decl);
5049 field_ref = build_field_ref ((is_static ? NULL_TREE : where_found),
5050 type_found, DECL_NAME (decl));
5051 if (field_ref == error_mark_node)
5052 return error_mark_node;
5055 field_ref = build_class_init (type_found, field_ref);
5056 /* If the static field was identified by an expression that
5057 needs to be generated, make the field access a compound
5058 expression whose first part of the evaluation of the
5059 field selector part. */
5060 if (where_found && TREE_CODE (where_found) != TYPE_DECL)
5062 tree type = QUAL_DECL_TYPE (field_ref);
5063 field_ref = build (COMPOUND_EXPR, type, where_found, field_ref);
5073 *field_type = QUAL_DECL_TYPE (decl);
5077 /* 6.5.5.2: Qualified Expression Names */
5080 resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
5082 tree *found_decl, *type_found, *where_found;
5084 int from_type = 0; /* Field search initiated from a type */
5085 int from_super = 0, from_cast = 0;
5086 int previous_call_static = 0;
5088 tree decl = NULL_TREE, type = NULL_TREE, q;
5089 *where_found = NULL_TREE;
5091 for (q = EXPR_WFL_QUALIFICATION (wfl); q; q = TREE_CHAIN (q))
5093 tree qual_wfl = QUAL_WFL (q);
5095 /* 15.10.1 Field Access Using a Primary */
5097 switch (TREE_CODE (qual_wfl))
5100 case NEW_CLASS_EXPR:
5101 /* If the access to the function call is a non static field,
5102 build the code to access it. */
5103 if (DECL_P (decl) && !FIELD_STATIC (decl))
5105 decl = maybe_access_field (decl, *where_found, type);
5106 if (decl == error_mark_node)
5109 /* And code for the function call */
5110 if (complete_function_arguments (qual_wfl))
5113 patch_method_invocation_stmt (qual_wfl, decl, type,
5115 if (*where_found == error_mark_node)
5117 *type_found = type = QUAL_DECL_TYPE (*where_found);
5119 /* If the previous call was static and this one is too,
5120 build a compound expression to hold the two (because in
5121 that case, previous function calls aren't transported as
5122 forcoming function's argument. */
5123 if (previous_call_static && is_static)
5125 decl = build (COMPOUND_EXPR, type, decl, *where_found);
5126 TREE_SIDE_EFFECTS (decl) = 1;
5130 previous_call_static = is_static;
5131 decl = *where_found;
5136 *where_found = decl = java_complete_tree (qual_wfl);
5137 if (decl == error_mark_node)
5139 *type_found = type = QUAL_DECL_TYPE (decl);
5144 /* If the access to the function call is a non static field,
5145 build the code to access it. */
5146 if (DECL_P (decl) && !FIELD_STATIC (decl))
5148 decl = maybe_access_field (decl, *where_found, type);
5149 if (decl == error_mark_node)
5152 /* And code for the array reference expression */
5153 decl = java_complete_tree (qual_wfl);
5154 if (decl == error_mark_node)
5156 type = QUAL_DECL_TYPE (decl);
5160 /* Fix for -Wall Just go to the next statement. Don't
5164 /* If we fall here, we weren't processing a (static) function call. */
5165 previous_call_static = 0;
5167 /* It can be the keyword THIS */
5168 if (EXPR_WFL_NODE (qual_wfl) == this_identifier_node)
5173 (wfl, "Keyword `this' used outside allowed context");
5176 /* We have to generate code for intermediate acess */
5177 *where_found = decl = current_this;
5178 type = QUAL_DECL_TYPE (decl);
5182 /* 15.10.2 Accessing Superclass Members using SUPER */
5183 if (EXPR_WFL_NODE (qual_wfl) == super_identifier_node)
5186 /* Check on the restricted use of SUPER */
5187 if (METHOD_STATIC (current_function_decl)
5188 || current_class == object_type_node)
5191 (wfl, "Keyword `super' used outside allowed context");
5194 /* Otherwise, treat SUPER as (SUPER_CLASS)THIS */
5195 node = build_cast (EXPR_WFL_LINECOL (qual_wfl),
5196 CLASSTYPE_SUPER (current_class),
5197 build_this (EXPR_WFL_LINECOL (qual_wfl)));
5198 *where_found = decl = java_complete_tree (node);
5199 *type_found = type = QUAL_DECL_TYPE (decl);
5200 from_super = from_type = 1;
5204 /* 15.13.1: Can't search for field name in packages, so we
5205 assume a variable/class name was meant. */
5206 if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
5208 if (from_super || from_cast)
5210 ((from_cast ? qual_wfl : wfl),
5211 "No variable `%s' defined in class `%s'",
5212 IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
5213 lang_printable_name (type, 0));
5216 (qual_wfl, "Undefined variable or class name: `%s'",
5217 IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)));
5221 /* We have a type name. It's been already resolved when the
5222 expression was qualified. */
5223 else if (RESOLVE_TYPE_NAME_P (qual_wfl))
5225 if (!(decl = QUAL_RESOLUTION (q)))
5226 return 1; /* Error reported already */
5228 if (not_accessible_p (TREE_TYPE (decl), decl, 0))
5231 (qual_wfl, "Can't access %s field `%s.%s' from `%s'",
5232 java_accstring_lookup (get_access_flags_from_decl (decl)),
5233 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))),
5234 IDENTIFIER_POINTER (DECL_NAME (decl)),
5235 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
5239 type = TREE_TYPE (decl);
5242 /* We resolve and expression name */
5247 /* If there exists an early resolution, use it. That occurs
5248 only once and we know that there are more things to
5249 come. Don't do that when processing something after SUPER
5250 (we need more thing to be put in place below */
5251 if (!from_super && QUAL_RESOLUTION (q))
5253 decl = QUAL_RESOLUTION (q);
5257 /* We have to search for a field, knowing the type of its
5258 container. The flag FROM_TYPE indicates that we resolved
5259 the last member of the expression as a type name, which
5260 means that for the resolution of this field, will check
5261 on other errors than if the it was resolved as a member
5262 of an other field. */
5266 if (!from_type && !JREFERENCE_TYPE_P (type))
5269 (qual_wfl, "Attempt to reference field `%s' in `%s %s'",
5270 IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
5271 lang_printable_name (type, 0),
5272 IDENTIFIER_POINTER (DECL_NAME (field_decl)));
5277 lookup_field_wrapper (type, EXPR_WFL_NODE (qual_wfl))))
5280 (qual_wfl, "No variable `%s' defined in class `%s'",
5281 IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
5282 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
5286 /* Check on accessibility here */
5287 if (not_accessible_p (type, field_decl, from_super))
5291 "Can't access %s field `%s.%s' from `%s'",
5292 java_accstring_lookup
5293 (get_access_flags_from_decl (field_decl)),
5294 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))),
5295 IDENTIFIER_POINTER (DECL_NAME (field_decl)),
5297 (DECL_NAME (TYPE_NAME (current_class))));
5301 /* There are things to check when fields are accessed
5302 from type. There are no restrictions on a static
5303 declaration of the field when it is accessed from an
5305 is_static = FIELD_STATIC (field_decl);
5306 if (!from_super && from_type
5307 && !TYPE_INTERFACE_P (type) && !is_static)
5310 (qual_wfl, "Can't make a static reference to nonstatic "
5311 "variable `%s' in class `%s'",
5312 IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
5313 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
5316 from_cast = from_super = 0;
5318 /* If we need to generate something to get a proper handle
5319 on what this field is accessed from, do it now. */
5322 decl = maybe_access_field (decl, *where_found, type);
5323 if (decl == error_mark_node)
5327 /* We want to keep the location were found it, and the type
5329 *where_found = decl;
5332 /* This is the decl found and eventually the next one to
5337 type = QUAL_DECL_TYPE (decl);
5344 /* 6.6 Qualified name and access control. Returns 1 if MEMBER (a decl)
5345 can't be accessed from REFERENCE (a record type). */
5347 int not_accessible_p (reference, member, from_super)
5348 tree reference, member;
5351 int access_flag = get_access_flags_from_decl (member);
5353 /* Access always granted for members declared public */
5354 if (access_flag & ACC_PUBLIC)
5357 /* Check access on protected members */
5358 if (access_flag & ACC_PROTECTED)
5360 /* Access granted if it occurs from within the package
5361 containing the class in which the protected member is
5363 if (class_in_current_package (DECL_CONTEXT (member)))
5366 if (TREE_CODE (member) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (member))
5368 /* Access from SUPER is granted */
5371 /* Otherwise, access isn't granted */
5376 /* If accessed with the form `super.member', then access is
5381 /* Otherwise, access is granted if occuring from the class where
5382 member is declared or a subclass of it */
5383 if (inherits_from_p (reference, current_class))
5389 /* Check access on private members. Access is granted only if it
5390 occurs from within the class in witch it is declared*/
5392 if (access_flag & ACC_PRIVATE)
5393 return (current_class == DECL_CONTEXT (member) ? 0 : 1);
5395 /* Default access are permitted only when occuring within the
5396 package in which the type (REFERENCE) is declared. In other words,
5397 REFERENCE is defined in the current package */
5399 return !class_in_current_package (reference);
5401 /* Otherwise, access is granted */
5405 /* Returns 1 if class was declared in the current package, 0 otherwise */
5408 class_in_current_package (class)
5411 static tree cache = NULL_TREE;
5418 qualified_flag = QUALIFIED_P (DECL_NAME (TYPE_NAME (class)));
5420 /* If the current package is empty and the name of CLASS is
5421 qualified, class isn't in the current package. If there is a
5422 current package and the name of the CLASS is not qualified, class
5423 isn't in the current package */
5424 if ((!ctxp->package && qualified_flag) || (ctxp->package && !qualified_flag))
5427 /* If there is not package and the name of CLASS isn't qualified,
5428 they belong to the same unnamed package */
5429 if (!ctxp->package && !qualified_flag)
5432 /* Compare the left part of the name of CLASS with the package name */
5433 breakdown_qualified (&left, NULL, DECL_NAME (TYPE_NAME (class)));
5434 if (ctxp->package == left)
5442 /* This function may generate code to access DECL from WHERE. This is
5443 done only if certain conditions meet. */
5446 maybe_access_field (decl, where, type)
5447 tree decl, where, type;
5449 if (DECL_P (decl) && decl != current_this
5450 && (!(TREE_CODE (decl) != PARM_DECL
5451 && FIELD_STATIC (decl)))
5452 && !IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)))
5453 decl = build_field_ref (where ? where : current_this,
5454 type, DECL_NAME (decl));
5458 /* Build a method invocation statement, by patching PATCH. If non NULL
5459 and according to the situation, PRIMARY and WHERE may be
5460 used. IS_STATIC is set to 1 if the invoked function is static. */
5463 patch_method_invocation_stmt (patch, primary, where, is_static, ret_decl)
5464 tree patch, primary, where;
5468 tree wfl = TREE_OPERAND (patch, 0);
5469 tree args = TREE_OPERAND (patch, 1);
5470 tree name = EXPR_WFL_NODE (wfl);
5471 tree list, class_type;
5473 /* Should be overriden if everything goes well. Otherwise, if
5474 something fails, it should keep this value. It stop the
5475 evaluation of a bogus assignment. See java_complete_tree,
5476 MODIFY_EXPR: for the reasons why we sometimes want to keep on
5477 evaluating an assignment */
5478 TREE_TYPE (patch) = error_mark_node;
5480 /* Since lookup functions are messing with line numbers, save the
5482 java_parser_context_save_global ();
5484 /* 15.11.1: Compile-Time Step 1: Determine Class or Interface to Search */
5486 /* Resolution of qualified name, excluding constructors */
5487 if (QUALIFIED_P (name) && !CALL_CONSTRUCTOR_P (patch))
5489 tree class_decl, identifier, identifier_wfl;
5490 /* Extract the last IDENTIFIER of the qualified
5491 expression. This is a wfl and we will use it's location
5492 data during error report. */
5493 identifier_wfl = cut_identifier_in_qualified (wfl);
5494 identifier = EXPR_WFL_NODE (identifier_wfl);
5496 /* Given the context, IDENTIFIER is syntactically qualified
5497 as a MethodName. We need to qualify what's before */
5498 qualify_ambiguous_name (wfl);
5500 /* Package resolution are erroneous */
5501 if (RESOLVE_PACKAGE_NAME_P (wfl))
5504 breakdown_qualified (&remainder, NULL, EXPR_WFL_NODE (wfl));
5505 parse_error_context (wfl, "Can't search method `%s' in package "
5506 "`%s'",IDENTIFIER_POINTER (identifier),
5507 IDENTIFIER_POINTER (remainder));
5508 PATCH_METHOD_RETURN_ERROR ();
5510 /* We're resolving a call from a type */
5511 else if (RESOLVE_TYPE_NAME_P (wfl))
5513 tree decl = QUAL_RESOLUTION (EXPR_WFL_QUALIFICATION (wfl));
5514 tree name = DECL_NAME (decl);
5517 class_decl = resolve_and_layout (name, wfl);
5518 if (CLASS_INTERFACE (decl))
5521 (identifier_wfl, "Can't make static reference to method "
5522 "`%s' in interface `%s'", IDENTIFIER_POINTER (identifier),
5523 IDENTIFIER_POINTER (name));
5524 PATCH_METHOD_RETURN_ERROR ();
5526 /* Look the method up in the type selector. The method ought
5528 type = TREE_TYPE (class_decl);
5529 list = lookup_method_invoke (0, wfl, type, identifier, args);
5530 if (list && !METHOD_STATIC (list))
5532 char *fct_name = strdup (lang_printable_name (list, 0));
5535 "Can't make static reference to method `%s %s' in class `%s'",
5536 lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0),
5537 fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
5539 PATCH_METHOD_RETURN_ERROR ();
5542 /* We're resolving an expression name */
5547 /* 1- Find the field to which the call applies */
5548 field = resolve_field_access (wfl, NULL, &type);
5549 if (field == error_mark_node)
5550 PATCH_METHOD_RETURN_ERROR ();
5552 /* 2- Do the layout of the class where the last field
5553 was found, so we can search it. */
5555 resolve_and_layout (DECL_NAME (TYPE_NAME (type)), NULL_TREE);
5557 /* 3- Retrieve a filtered list of method matches, Refine
5558 if necessary. In any cases, point out errors. */
5559 list = lookup_method_invoke (0, identifier_wfl, type,
5562 /* 4- Add the field as an argument */
5563 args = tree_cons (NULL_TREE, field, nreverse (args));
5566 /* CLASS_TYPE is used during the call to not_accessible_p and
5567 IDENTIFIER_WFL will be used to report any problem further */
5568 class_type = TREE_TYPE (class_decl);
5569 wfl = identifier_wfl;
5571 /* Resolution of simple names, names generated after a primary: or
5575 tree class_to_search;
5576 int lc; /* Looking for Constructor */
5578 /* We search constructor in their target class */
5579 if (CALL_CONSTRUCTOR_P (patch))
5581 class_to_search = resolve_no_layout (EXPR_WFL_NODE (wfl), NULL_TREE);
5582 if (!class_to_search)
5585 (wfl, "Class `%s' not found in type declaration",
5586 IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
5587 PATCH_METHOD_RETURN_ERROR ();
5590 /* Can't instantiate an abstract class */
5591 if (CLASS_ABSTRACT (class_to_search))
5594 (wfl, "Class `%s' is an abstract class. It can't be "
5595 "instantiated", IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
5596 PATCH_METHOD_RETURN_ERROR ();
5598 class_to_search = TREE_TYPE (class_to_search);
5601 /* This is a regular search in the local class, unless an
5602 alternate class is specified. */
5605 class_to_search = (where ? where : current_class);
5609 /* NAME is a simple identifier or comes from a primary. Search
5610 in the class whose declaration contain the method being
5612 list = lookup_method_invoke (lc, wfl, class_to_search, name, args);
5614 /* Don't continue if no method were found, as the next statement
5615 can't be executed then. */
5617 PATCH_METHOD_RETURN_ERROR ();
5619 /* Check for static reference if non static methods */
5620 if (check_for_static_method_reference (wfl, patch, list,
5621 class_to_search, primary))
5622 PATCH_METHOD_RETURN_ERROR ();
5624 /* Non static/constructor methods are called with the current
5625 object extra argument. If method is resolved as a primary,
5626 use the primary otherwise use the current THIS. */
5627 args = nreverse (args);
5628 if (!CALL_CONSTRUCTOR_P (patch) && !METHOD_STATIC (list))
5629 args = tree_cons (NULL_TREE, primary ? primary : current_this, args);
5631 class_type = class_to_search;
5634 /* Merge point of all resolution schemes. If we have nothing, this
5635 is an error, already signaled */
5637 PATCH_METHOD_RETURN_ERROR ();
5639 /* Check accessibility, position the is_static flag, build and
5641 if (not_accessible_p (class_type, list, 0))
5643 char *fct_name = strdup (lang_printable_name (list, 0));
5645 (wfl, "Can't access %s method `%s %s.%s' from `%s'",
5646 java_accstring_lookup (get_access_flags_from_decl (list)),
5647 lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0),
5648 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class_type))), fct_name,
5649 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
5651 PATCH_METHOD_RETURN_ERROR ();
5655 *is_static = METHOD_STATIC (list);
5656 java_parser_context_restore_global ();
5657 /* Sometimes, we want the decl of the selected method. Such as for
5661 return patch_invoke (patch, list, args);
5664 /* Check that we're not trying to do a static reference to a method in
5665 non static method. Return 1 if it's the case, 0 otherwise. */
5668 check_for_static_method_reference (wfl, node, method, where, primary)
5669 tree wfl, node, method, where, primary;
5671 if (METHOD_STATIC (current_function_decl)
5672 && !METHOD_STATIC (method) && !primary && !CALL_CONSTRUCTOR_P (node))
5674 char *fct_name = strdup (lang_printable_name (method, 0));
5676 (wfl, "Can't make static reference to method `%s %s' in class `%s'",
5677 lang_printable_name (TREE_TYPE (TREE_TYPE (method)), 0), fct_name,
5678 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (where))));
5685 /* Patch an invoke expression METHOD and ARGS, based on its invocation
5689 patch_invoke (patch, method, args)
5690 tree patch, method, args;
5694 tree signature = build_java_signature (TREE_TYPE (method));
5695 tree original_call, t, ta;
5697 /* Last step for args: convert build-in types */
5698 for (t = TYPE_ARG_TYPES (TREE_TYPE (method)),
5699 ta = args; t && ta; t = TREE_CHAIN (t), ta = TREE_CHAIN (ta))
5700 if (JPRIMITIVE_TYPE_P (TREE_TYPE (TREE_VALUE (ta))) &&
5701 TREE_TYPE (TREE_VALUE (ta)) != TREE_VALUE (t))
5702 TREE_VALUE (ta) = convert (TREE_VALUE (t), TREE_VALUE (ta));
5704 switch ((im = invocation_mode (method, 0)))
5706 case INVOKE_VIRTUAL:
5707 dtable = invoke_build_dtable (0, args);
5708 func = build_invokevirtual (dtable, method);
5712 func = build_known_method_ref (method, TREE_TYPE (method),
5713 DECL_CONTEXT (method), signature, args);
5717 fatal ("Unknown invocation mode - build_invoke");
5721 /* Ensure self_type is initialized, (invokestatic). FIXME */
5722 func = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (method)), func);
5723 TREE_TYPE (patch) = TREE_TYPE (TREE_TYPE (method));
5724 TREE_OPERAND (patch, 0) = func;
5725 TREE_OPERAND (patch, 1) = args;
5726 original_call = patch;
5728 /* We're calling a constructor. New is called an its returned value
5729 is an argument to the constructor. We build a COMPOUND_EXPR and
5730 use saved expression so that the overall NEW expression value is
5731 a pointer to a newly created and initialized class. */
5732 if (CALL_CONSTRUCTOR_P (original_call))
5734 tree class = DECL_CONTEXT (method);
5735 tree c1, saved_new, size, new;
5736 if (!TYPE_SIZE (class))
5737 safe_layout_class (class);
5738 size = size_in_bytes (class);
5739 new = build (CALL_EXPR, promote_type (class),
5740 build_address_of (alloc_object_node),
5741 tree_cons (NULL_TREE, build_class_ref (class),
5742 build_tree_list (NULL_TREE,
5743 size_in_bytes (class))),
5745 saved_new = save_expr (new);
5746 c1 = build_tree_list (NULL_TREE, saved_new);
5747 TREE_CHAIN (c1) = TREE_OPERAND (original_call, 1);
5748 TREE_OPERAND (original_call, 1) = c1;
5749 TREE_SET_CODE (original_call, CALL_EXPR);
5750 patch = build (COMPOUND_EXPR, TREE_TYPE (new), patch, saved_new);
5756 invocation_mode (method, super)
5760 int access = get_access_flags_from_decl (method);
5762 if (access & ACC_STATIC || access & ACC_FINAL)
5763 return INVOKE_STATIC;
5765 if (CLASS_FINAL (TYPE_NAME (DECL_CONTEXT (method))))
5766 return INVOKE_STATIC;
5769 return INVOKE_SUPER;
5771 if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))))
5772 return INVOKE_INTERFACE;
5774 if (DECL_CONSTRUCTOR_P (method))
5775 return INVOKE_STATIC;
5777 return INVOKE_VIRTUAL;
5780 /* Retrieve a refined list of matching methods. It covers the step
5781 15.11.2 (Compile-Time Step 2) */
5784 lookup_method_invoke (lc, cl, class, name, arg_list)
5787 tree class, name, arg_list;
5789 tree method = make_node (FUNCTION_TYPE);
5790 tree arg_type_list = NULL_TREE;
5791 tree signature, list, node;
5792 char *candidates; /* Used for error report */
5794 for (node = arg_list; node; node = TREE_CHAIN (node))
5796 tree current_arg = TREE_TYPE (TREE_VALUE (node));
5797 if (TREE_CODE (current_arg) == RECORD_TYPE)
5798 current_arg = promote_type (current_arg);
5799 arg_type_list = tree_cons (NULL_TREE, current_arg, arg_type_list);
5801 TYPE_ARG_TYPES (method) = arg_type_list;
5805 list = find_applicable_accessible_methods_list (class, name,
5807 list = find_most_specific_methods_list (list);
5811 TREE_TYPE (method) = void_type_node;
5812 signature = build_java_signature (method);
5813 list = lookup_java_constructor (class, signature);
5818 if (list && !TREE_CHAIN (list))
5819 return TREE_VALUE (list);
5821 /* Issue an error. List candidates if any. Candidates are listed
5822 only if accessible (non accessible methods may end-up here for
5823 the sake of a better error report). */
5828 obstack_grow (&temporary_obstack, ". Candidates are:\n", 18);
5829 for (current = list; current; current = TREE_CHAIN (current))
5831 tree cm = TREE_VALUE (current);
5833 if (!cm || not_accessible_p (class, cm, 0))
5835 signature = build_java_argument_signature (TREE_TYPE (cm));
5837 (string, " `%s(%s)' in `%s'%s",
5838 IDENTIFIER_POINTER (name),
5839 IDENTIFIER_POINTER (signature),
5840 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (cm)))),
5841 (TREE_CHAIN (current) ? "\n" : ""));
5842 obstack_grow (&temporary_obstack, string, strlen (string));
5844 obstack_1grow (&temporary_obstack, '\0');
5845 candidates = obstack_finish (&temporary_obstack);
5847 /* Issue the error message */
5848 signature = build_java_argument_signature (method);
5849 parse_error_context (cl, "Can't find method `%s(%s)' in class `%s'%s",
5850 IDENTIFIER_POINTER (name),
5851 IDENTIFIER_POINTER (signature),
5852 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class))),
5853 (candidates ? candidates : ""));
5857 /* 15.11.2.1: Find Methods that are Applicable and Accessible */
5860 find_applicable_accessible_methods_list (class, name, arglist)
5861 tree class, name, arglist;
5864 tree list = NULL_TREE, all_list = NULL_TREE;
5866 while (class != NULL_TREE)
5868 for (method = TYPE_METHODS (class);
5869 method != NULL_TREE; method = TREE_CHAIN (method))
5871 /* Names have to match and we're not looking for constructor */
5872 if (DECL_NAME (method) != name
5873 || DECL_CONSTRUCTOR_P (method))
5876 if (argument_types_convertible (method, arglist))
5878 /* Retain accessible methods only */
5879 if (!not_accessible_p (class, method, 0))
5880 list = tree_cons (NULL_TREE, method, list);
5882 /* Also retain all selected method here */
5883 all_list = tree_cons (NULL_TREE, method, list);
5886 class = CLASSTYPE_SUPER (class);
5888 /* Either return the list obtained or all selected (but
5889 inaccessible) methods for better error report. */
5890 return (!list ? all_list : list);
5893 /* 15.11.2.2 Choose the Most Specific Method */
5896 find_most_specific_methods_list (list)
5900 tree current, new_list = NULL_TREE;
5901 for (current = list; current; current = TREE_CHAIN (current))
5904 DECL_SPECIFIC_COUNT (TREE_VALUE (current)) = 0;
5906 for (method = list; method; method = TREE_CHAIN (method))
5908 /* Don't test a method against itself */
5909 if (method == current)
5912 /* Compare arguments and location where method where declared */
5913 if (argument_types_convertible (TREE_VALUE (method),
5914 TREE_VALUE (current))
5915 && valid_method_invocation_conversion_p
5916 (DECL_CONTEXT (TREE_VALUE (method)),
5917 DECL_CONTEXT (TREE_VALUE (current))))
5919 int v = ++DECL_SPECIFIC_COUNT (TREE_VALUE (current));
5920 max = (v > max ? v : max);
5925 /* Review the list and select the maximally specific methods */
5926 for (current = list; current; current = TREE_CHAIN (current))
5927 if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
5928 new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
5930 /* If we can't find one, lower expectations and try to gather multiple
5931 maximally specific methods */
5936 if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
5937 new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
5945 /* Make sure that the type of each M2_OR_ARGLIST arguments can be
5946 converted by method invocation conversion (5.3) to the type of the
5947 corresponding parameter of M1. Implementation expects M2_OR_ARGLIST
5948 to change less often than M1. */
5951 argument_types_convertible (m1, m2_or_arglist)
5952 tree m1, m2_or_arglist;
5954 static tree m2_arg_value = NULL_TREE;
5955 static tree m2_arg_cache = NULL_TREE;
5957 register tree m1_arg, m2_arg;
5959 m1_arg = TYPE_ARG_TYPES (TREE_TYPE (m1));
5960 if (!METHOD_STATIC (m1))
5961 m1_arg = TREE_CHAIN (m1_arg);
5963 if (m2_arg_value == m2_or_arglist)
5964 m2_arg = m2_arg_cache;
5967 /* M2_OR_ARGLIST can be a function DECL or a raw list of
5969 if (m2_or_arglist && TREE_CODE (m2_or_arglist) == FUNCTION_DECL)
5971 m2_arg = TYPE_ARG_TYPES (TREE_TYPE (m2_or_arglist));
5972 if (!METHOD_STATIC (m2_or_arglist))
5973 m2_arg = TREE_CHAIN (m2_arg);
5976 m2_arg = m2_or_arglist;
5978 m2_arg_value = m2_or_arglist;
5979 m2_arg_cache = m2_arg;
5982 while (m1_arg && m2_arg)
5984 if (!valid_method_invocation_conversion_p (TREE_VALUE (m1_arg),
5985 TREE_VALUE (m2_arg)))
5987 m1_arg = TREE_CHAIN (m1_arg);
5988 m2_arg = TREE_CHAIN (m2_arg);
5990 return (!m1_arg && !m2_arg ? 1 : 0);
5993 /* Qualification routines */
5996 qualify_ambiguous_name (id)
5999 tree qual, qual_wfl, name, decl, ptr_type, saved_current_class;
6000 int again, super_found = 0, this_found = 0;
6002 /* We first qualify the first element, then derive qualification of
6003 others based on the first one. If the first element is qualified
6004 by a resolution (field or type), this resolution is stored in the
6005 QUAL_RESOLUTION of the qual element being examined. We need to
6006 save the current_class since the use of SUPER might change the
6008 saved_current_class = current_class;
6009 qual = EXPR_WFL_QUALIFICATION (id);
6012 /* Simple qualified expression feature a qual_wfl that is a
6013 WFL. Expression derived from a primary feature more complicated
6014 things like a CALL_EXPR. Expression from primary need to be
6015 worked out to extract the part on which the qualification will
6017 qual_wfl = QUAL_WFL (qual);
6018 switch (TREE_CODE (qual_wfl))
6021 qual_wfl = TREE_OPERAND (qual_wfl, 0);
6022 if (TREE_CODE (qual_wfl) != EXPR_WITH_FILE_LOCATION)
6024 qual = EXPR_WFL_QUALIFICATION (qual_wfl);
6025 qual_wfl = QUAL_WFL (qual);
6028 case NEW_CLASS_EXPR:
6031 qual_wfl = TREE_OPERAND (qual_wfl, 0);
6035 /* Fix for -Wall. Just break doing nothing */
6038 name = EXPR_WFL_NODE (qual_wfl);
6039 ptr_type = current_class;
6041 /* If we have a THIS (from a primary), we set the context accordingly */
6042 if (name == this_identifier_node)
6044 qual = TREE_CHAIN (qual);
6045 qual_wfl = QUAL_WFL (qual);
6046 name = EXPR_WFL_NODE (qual_wfl);
6049 /* If we have a SUPER, we set the context accordingly */
6050 if (name == super_identifier_node)
6052 current_class = CLASSTYPE_SUPER (ptr_type);
6053 /* Check that there is such a thing as a super class. If not,
6054 return. The error will be caught later on, during the
6058 current_class = saved_current_class;
6061 qual = TREE_CHAIN (qual);
6062 /* Do one more interation to set things up */
6063 super_found = again = 1;
6067 /* If name appears within the scope of a location variable
6068 declaration or parameter declaration, then it is an expression
6069 name. We don't carry this test out if we're in the context of the
6070 use of SUPER or THIS */
6072 if (!this_found && !super_found && (decl = IDENTIFIER_LOCAL_VALUE (name)))
6074 RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
6075 QUAL_RESOLUTION (qual) = decl;
6078 /* If within the class/interface NAME was found to be used there
6079 exists a (possibly inherited) field named NAME, then this is an
6081 else if ((decl = lookup_field_wrapper (ptr_type, name)))
6083 RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
6084 QUAL_RESOLUTION (qual) = decl;
6087 /* We reclassify NAME as a type name if:
6088 - NAME is a class/interface declared within the compilation
6089 unit containing NAME,
6090 - NAME is imported via a single-type-import declaration,
6091 - NAME is declared in an another compilation unit of the package
6092 of the compilation unit containing NAME,
6093 - NAME is declared by exactly on type-import-on-demand declaration
6094 of the compilation unit containing NAME. */
6095 else if ((decl = resolve_and_layout (name, NULL_TREE)))
6097 RESOLVE_TYPE_NAME_P (qual_wfl) = 1;
6098 QUAL_RESOLUTION (qual) = decl;
6101 /* Method call are expression name */
6102 else if (TREE_CODE (QUAL_WFL (qual)) == CALL_EXPR)
6103 RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
6105 /* Check here that NAME isn't declared by more than one
6106 type-import-on-demand declaration of the compilation unit
6107 containing NAME. FIXME */
6109 /* Otherwise, NAME is reclassified as a package name */
6111 RESOLVE_PACKAGE_NAME_P (qual_wfl) = 1;
6113 /* Propagate the qualification accross other components of the
6115 for (qual = TREE_CHAIN (qual); qual;
6116 qual_wfl = QUAL_WFL (qual), qual = TREE_CHAIN (qual))
6118 if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
6119 RESOLVE_PACKAGE_NAME_P (QUAL_WFL (qual)) = 1;
6121 RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (qual)) = 1;
6124 /* Store the global qualification for the ambiguous part of ID back
6126 if (RESOLVE_EXPRESSION_NAME_P (qual_wfl))
6127 RESOLVE_EXPRESSION_NAME_P (id) = 1;
6128 else if (RESOLVE_TYPE_NAME_P (qual_wfl))
6129 RESOLVE_TYPE_NAME_P (id) = 1;
6130 else if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
6131 RESOLVE_PACKAGE_NAME_P (id) = 1;
6133 /* Restore the current class */
6134 current_class = saved_current_class;
6138 breakdown_qualified (left, right, source)
6139 tree *left, *right, source;
6141 char *p = IDENTIFIER_POINTER (source), *base;
6142 int l = IDENTIFIER_LENGTH (source);
6144 /* Breakdown NAME into REMAINDER . IDENTIFIER */
6147 while (*p != '.' && p != base)
6150 /* We didn't find a '.'. Return an error */
6156 *right = get_identifier (p+1);
6157 *left = get_identifier (IDENTIFIER_POINTER (source));
6164 not_initialized_as_it_should_p (decl)
6169 if (TREE_CODE (decl) == FIELD_DECL
6170 && METHOD_STATIC (current_function_decl))
6172 return DECL_P (decl) && !INITIALIZED_P (decl);
6177 /* Patch tree nodes in a function body. When a BLOCK is found, push
6178 local variable decls if present. */
6181 java_complete_tree (node)
6184 tree nn, cn, wfl_op1, wfl_op2;
6187 /* CONVERT_EXPR always has its type set, even though it needs to be
6189 if (TREE_TYPE (node) && TREE_CODE (node) != CONVERT_EXPR)
6192 /* The switch block implements cases processing container nodes
6193 first. Contained nodes are always written back. Leaves come
6194 next and return a value. */
6195 switch (TREE_CODE (node))
6199 /* 1- Block section.
6200 Set the local values on decl names so we can identify them
6201 faster when they're referenced. At that stage, identifiers
6202 are legal so we don't check for declaration errors. */
6203 for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
6205 DECL_CONTEXT (cn) = current_function_decl;
6206 IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = cn;
6207 INITIALIZED_P (cn) = 0;
6209 if (BLOCK_EXPR_BODY (node))
6211 BLOCK_EXPR_BODY (node) = java_complete_tree (BLOCK_EXPR_BODY (node));
6212 if (BLOCK_EXPR_BODY (node) == error_mark_node)
6213 return error_mark_node;
6215 /* Turn local bindings to null */
6216 for (cn = BLOCK_EXPR_DECLS (node); cn; cn = TREE_CHAIN (cn))
6217 IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = NULL_TREE;
6219 TREE_TYPE (node) = void_type_node;
6222 /* 2- They are expressions but ultimately deal with statements */
6225 wfl_op1 = TREE_OPERAND (node, 0);
6226 COMPLETE_CHECK_OP_0 (node);
6227 return patch_throw_statement (node, wfl_op1);
6229 case SYNCHRONIZED_EXPR:
6230 wfl_op1 = TREE_OPERAND (node, 0);
6231 COMPLETE_CHECK_OP_0 (node);
6232 COMPLETE_CHECK_OP_1 (node);
6233 return patch_synchronized_statement (node, wfl_op1);
6236 return patch_try_statement (node);
6238 case LABELED_BLOCK_EXPR:
6239 PUSH_LABELED_BLOCK (node);
6240 if (LABELED_BLOCK_BODY (node))
6241 COMPLETE_CHECK_OP_1 (node);
6242 TREE_TYPE (node) = void_type_node;
6243 POP_LABELED_BLOCK ();
6246 case EXIT_BLOCK_EXPR:
6247 /* We don't complete operand 1, because it's the return value of
6248 the EXIT_BLOCK_EXPR which doesn't exist it Java */
6249 return patch_bc_statement (node);
6254 /* Check whether the loop was enclosed in a labeled
6255 statement. If not, create one, insert the loop in it and
6257 nn = patch_loop_statement (node);
6259 /* Anyways, walk the body of the loop */
6260 if (TREE_CODE (node) == LOOP_EXPR)
6261 TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
6262 /* Switch statement: walk the switch expression and the cases */
6264 node = patch_switch_statement (node);
6266 if (TREE_OPERAND (node, 0) == error_mark_node)
6267 return error_mark_node;
6268 TREE_TYPE (nn) = TREE_TYPE (node) = void_type_node;
6269 /* If we returned something different, that's because we
6270 inserted a label. Pop the label too. */
6272 POP_LABELED_BLOCK ();
6277 TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
6278 return patch_exit_expr (node);
6282 TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
6283 if (TREE_OPERAND (node, 0) == error_mark_node)
6284 return error_mark_node;
6285 /* then-else branches */
6286 TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
6287 if (TREE_OPERAND (node, 1) == error_mark_node)
6288 return error_mark_node;
6289 TREE_OPERAND (node, 2) = java_complete_tree (TREE_OPERAND (node, 2));
6290 if (TREE_OPERAND (node, 2) == error_mark_node)
6291 return error_mark_node;
6292 return patch_if_else_statement (node);
6295 /* 3- Expression section */
6297 TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
6298 TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
6299 if (TREE_OPERAND (node, 1) == error_mark_node)
6300 return error_mark_node;
6301 TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 1));
6305 return patch_return (node);
6307 case EXPR_WITH_FILE_LOCATION:
6308 if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
6309 || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
6310 return resolve_expression_name (node);
6313 EXPR_WFL_NODE (node) = java_complete_tree (EXPR_WFL_NODE (node));
6314 TREE_SIDE_EFFECTS (node) = 1;
6315 if (EXPR_WFL_NODE (node) == error_mark_node)
6317 /* Its important for the evaluation of assignment that
6318 this mark on the TREE_TYPE is propagated. */
6319 TREE_TYPE (node) = error_mark_node;
6320 return error_mark_node;
6323 TREE_TYPE (node) = TREE_TYPE (EXPR_WFL_NODE (node));
6327 case NEW_ARRAY_EXPR:
6328 /* Patch all the dimensions */
6330 for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
6332 int location = EXPR_WFL_LINECOL (TREE_VALUE (cn));
6333 tree dim = java_complete_tree (TREE_VALUE (cn));
6334 if (dim == error_mark_node)
6341 TREE_VALUE (cn) = dim;
6342 /* Setup the location of the current dimension, for
6343 later error report. */
6345 build_expr_wfl (NULL_TREE, input_filename, 0, 0);
6346 EXPR_WFL_LINECOL (TREE_PURPOSE (cn)) = location;
6349 /* They complete the array creation expression, if no errors
6351 return (flag ? error_mark_node : patch_newarray (node));
6353 case NEW_CLASS_EXPR:
6355 /* Complete function's argument(s) first */
6356 if (complete_function_arguments (node))
6357 return error_mark_node;
6361 node = patch_method_invocation_stmt (node, NULL_TREE,
6362 NULL_TREE, 0, &decl);
6363 if (node != error_mark_node)
6364 check_thrown_exceptions (EXPR_WFL_LINECOL (node), decl);
6369 /* Save potential wfls */
6370 wfl_op1 = TREE_OPERAND (node, 0);
6371 wfl_op2 = TREE_OPERAND (node, 1);
6372 TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
6373 if (TREE_OPERAND (node, 0) == error_mark_node)
6374 return error_mark_node;
6376 if (COMPOUND_ASSIGN_P (wfl_op2))
6380 java_complete_tree (TREE_OPERAND (wfl_op2, 0));
6382 /* Hand stablize the lhs on both places */
6383 lvalue = stabilize_reference (other);
6384 TREE_OPERAND (node, 0) = lvalue;
6385 TREE_OPERAND (TREE_OPERAND (node, 1), 0) = lvalue;
6388 /* There are cases where the type of RHS is fixed. In those
6389 cases, if the evaluation of the RHS fails, we further the
6390 evaluation of the assignment to detect more errors. */
6391 nn = java_complete_tree (TREE_OPERAND (node, 1));
6392 if (nn == error_mark_node)
6394 /* It's hopeless, but we can further things on to discover
6395 an error during the assignment. In any cases, the
6396 assignment operation fails. */
6397 if (TREE_CODE (TREE_OPERAND (node, 1)) != EXPR_WITH_FILE_LOCATION
6398 && TREE_TYPE (TREE_OPERAND (node, 1)) != error_mark_node)
6399 patch_assignment (node, wfl_op1, wfl_op2);
6401 /* Now, we still mark the lhs as initialized */
6402 if (DECL_P (TREE_OPERAND (node, 0)))
6403 INITIALIZED_P (TREE_OPERAND (node, 0)) = 1;
6405 return error_mark_node;
6407 TREE_OPERAND (node, 1) = nn;
6409 /* In case we're handling = with a String as a RHS, we need to
6410 produce a String out of the RHS (it might still be a
6411 STRING_CST or a StringBuffer at this stage */
6412 if ((nn = patch_string (TREE_OPERAND (node, 1))))
6413 TREE_OPERAND (node, 1) = nn;
6414 return patch_assignment (node, wfl_op1, wfl_op2);
6425 case TRUNC_MOD_EXPR:
6427 case TRUTH_ANDIF_EXPR:
6428 case TRUTH_ORIF_EXPR:
6435 /* Operands 0 and 1 are WFL in certain cases only. patch_binop
6436 knows how to handle those cases. */
6437 wfl_op1 = TREE_OPERAND (node, 0);
6438 wfl_op2 = TREE_OPERAND (node, 1);
6440 /* Don't complete string nodes if dealing with the PLUS operand. */
6441 if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op1))
6443 TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
6444 if (TREE_OPERAND (node, 0) == error_mark_node)
6445 return error_mark_node;
6447 if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op2))
6449 TREE_OPERAND (node, 1) = java_complete_tree (wfl_op2);
6450 if (TREE_OPERAND (node, 1) == error_mark_node)
6451 return error_mark_node;
6453 return patch_binop (node, wfl_op1, wfl_op2);
6455 case UNARY_PLUS_EXPR:
6457 case TRUTH_NOT_EXPR:
6459 case PREDECREMENT_EXPR:
6460 case PREINCREMENT_EXPR:
6461 case POSTDECREMENT_EXPR:
6462 case POSTINCREMENT_EXPR:
6464 /* There are cases were wfl_op1 is a WFL. patch_unaryop knows
6465 how to handle those cases. */
6466 wfl_op1 = TREE_OPERAND (node, 0);
6467 TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
6468 if (TREE_OPERAND (node, 0) == error_mark_node)
6469 return error_mark_node;
6470 return patch_unaryop (node, wfl_op1);
6473 /* There are cases were wfl_op1 is a WFL. patch_array_ref knows
6474 how to handle those cases. */
6475 wfl_op1 = TREE_OPERAND (node, 0);
6476 TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
6477 if (TREE_OPERAND (node, 0) == error_mark_node)
6478 return error_mark_node;
6479 if (!flag_emit_class_files)
6480 TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
6481 /* The same applies to wfl_op2 */
6482 wfl_op2 = TREE_OPERAND (node, 1);
6483 TREE_OPERAND (node, 1) = java_complete_tree (wfl_op2);
6484 if (TREE_OPERAND (node, 1) == error_mark_node)
6485 return error_mark_node;
6486 TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1));
6487 return patch_array_ref (node, wfl_op1, wfl_op2);
6490 /* Can't use THIS in a static environment */
6493 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
6494 parse_error_context (wfl_operator, "Keyword `this' used outside "
6496 TREE_TYPE (node) = error_mark_node;
6497 return error_mark_node;
6499 return current_this;
6502 /* Ok: may be we have a STRING_CST or a crafted `StringBuffer'
6503 and it's time to turn it into the appropriate String object
6505 if ((node = patch_string (node)))
6507 fatal ("No case for tree code `%s' - java_complete_tree\n",
6508 tree_code_name [TREE_CODE (node)]);
6513 /* Complete function call's argument. Return a non zero value is an
6517 complete_function_arguments (node)
6523 for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
6525 tree wfl = TREE_VALUE (cn), parm, temp;
6526 parm = java_complete_tree (wfl);
6527 if (parm == error_mark_node)
6532 /* If have a string literal that we haven't transformed yet or a
6533 crafted string buffer, as a result of use of the the String
6534 `+' operator. Build `parm.toString()' and expand it. */
6535 if ((temp = patch_string (parm)))
6537 TREE_VALUE (cn) = parm;
6539 if (not_initialized_as_it_should_p (parm))
6541 ERROR_VARIABLE_NOT_INITIALIZED (wfl, EXPR_WFL_NODE (wfl));
6542 INITIALIZED_P (parm) = 1;
6548 /* Sometimes (for loops and variable initialized during their
6549 declaration), we want to wrap a statement around a WFL and turn it
6553 build_debugable_stmt (location, stmt)
6557 if (TREE_CODE (stmt) != EXPR_WITH_FILE_LOCATION)
6559 stmt = build_expr_wfl (stmt, input_filename, 0, 0);
6560 EXPR_WFL_LINECOL (stmt) = location;
6562 JAVA_MAYBE_GENERATE_DEBUG_INFO (stmt);
6567 build_expr_block (body, decls)
6570 tree node = make_node (BLOCK);
6571 BLOCK_EXPR_DECLS (node) = decls;
6572 BLOCK_EXPR_BODY (node) = body;
6574 TREE_TYPE (node) = TREE_TYPE (body);
6575 TREE_SIDE_EFFECTS (node) = 1;
6579 /* Create a new function block and link it approriately to current
6580 function block chain */
6585 return (enter_a_block (build_expr_block (NULL_TREE, NULL_TREE)));
6588 /* Link block B supercontext to the previous block. The current
6589 function DECL is used as supercontext when enter_a_block is called
6590 for the first time for a given function. The current function body
6591 (DECL_FUNCTION_BODY) is set to be block B. */
6597 tree fndecl = current_function_decl;
6599 if (!DECL_FUNCTION_BODY (fndecl))
6601 BLOCK_SUPERCONTEXT (b) = fndecl;
6602 DECL_FUNCTION_BODY (fndecl) = b;
6606 BLOCK_SUPERCONTEXT (b) = DECL_FUNCTION_BODY (fndecl);
6607 DECL_FUNCTION_BODY (fndecl) = b;
6612 /* Exit a block by changing the current function body
6613 (DECL_FUNCTION_BODY) to the current block super context, only if
6614 the block being exited isn't the method's top level one. */
6619 tree b = DECL_FUNCTION_BODY (current_function_decl);
6621 if (BLOCK_SUPERCONTEXT (b) != current_function_decl)
6622 DECL_FUNCTION_BODY (current_function_decl) = BLOCK_SUPERCONTEXT (b);
6627 /* Lookup for NAME in the nested function's blocks, all the way up to
6628 the current toplevel one. It complies with Java's local variable
6632 lookup_name_in_blocks (name)
6635 tree b = DECL_FUNCTION_BODY (current_function_decl);
6637 while (b != current_function_decl)
6641 /* Paranoid sanity check. To be removed */
6642 if (TREE_CODE (b) != BLOCK)
6643 fatal ("non block expr function body - lookup_name_in_blocks");
6645 for (current = BLOCK_EXPR_DECLS (b); current;
6646 current = TREE_CHAIN (current))
6647 if (DECL_NAME (current) == name)
6649 b = BLOCK_SUPERCONTEXT (b);
6655 maybe_absorb_scoping_blocks ()
6657 while (BLOCK_EXPR_ORIGIN (DECL_FUNCTION_BODY (current_function_decl)))
6659 tree b = exit_block ();
6660 java_method_add_stmt (current_function_decl, b);
6661 SOURCE_FRONTEND_DEBUG (("Absorbing scoping block at line %d", lineno));
6666 /* This section of the source is reserved to build_* functions that
6667 are building incomplete tree nodes and the patch_* functions that
6668 are completing them. */
6670 /* Build an incomplete CALL_EXPR node. */
6673 build_method_invocation (name, args)
6677 tree call = build (CALL_EXPR, NULL_TREE, name, args, NULL_TREE);
6678 TREE_SIDE_EFFECTS (call) = 1;
6679 EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
6683 /* Build an incomplete new xxx(...) node. */
6686 build_new_invocation (name, args)
6689 tree call = build (NEW_CLASS_EXPR, NULL_TREE, name, args, NULL_TREE);
6690 TREE_SIDE_EFFECTS (call) = 1;
6691 EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
6695 /* Build an incomplete assignment expression. */
6698 build_assignment (op, op_location, lhs, rhs)
6699 int op, op_location;
6703 /* Build the corresponding binop if we deal with a Compound
6704 Assignment operator. Mark the binop sub-tree as part of a
6705 Compound Assignment expression */
6706 if (op != ASSIGN_TK)
6708 rhs = build_binop (BINOP_LOOKUP (op), op_location, lhs, rhs);
6709 COMPOUND_ASSIGN_P (rhs) = 1;
6711 assignment = build (MODIFY_EXPR, NULL_TREE, lhs, rhs);
6712 TREE_SIDE_EFFECTS (assignment) = 1;
6713 EXPR_WFL_LINECOL (assignment) = op_location;
6717 /* Print an INTEGER_CST node in a static buffer, and return the buffer. */
6720 print_int_node (node)
6723 static char buffer [80];
6724 if (TREE_CONSTANT_OVERFLOW (node))
6725 sprintf (buffer, "<overflow>");
6727 if (TREE_INT_CST_HIGH (node) == 0)
6728 sprintf (buffer, HOST_WIDE_INT_PRINT_UNSIGNED,
6729 TREE_INT_CST_LOW (node));
6730 else if (TREE_INT_CST_HIGH (node) == -1
6731 && TREE_INT_CST_LOW (node) != 0)
6734 sprintf (&buffer [1], HOST_WIDE_INT_PRINT_UNSIGNED,
6735 -TREE_INT_CST_LOW (node));
6738 sprintf (buffer, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
6739 TREE_INT_CST_HIGH (node), TREE_INT_CST_LOW (node));
6744 /* 15.25 Assignment operators. */
6747 patch_assignment (node, wfl_op1, wfl_op2)
6752 tree rhs = TREE_OPERAND (node, 1);
6753 tree lvalue = TREE_OPERAND (node, 0);
6754 tree lhs_type, rhs_type, new_rhs = NULL_TREE;
6755 int error_found = 0;
6756 int lvalue_from_array = 0;
6758 /* Can't assign to a final. */
6759 if (DECL_P (lvalue) && FIELD_FINAL (lvalue))
6762 (wfl_op1, "Can't assign a value to the final variable `%s'",
6763 IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl_op1)));
6767 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
6769 /* Lhs can be a named variable */
6770 if (DECL_P (lvalue))
6772 INITIALIZED_P (lvalue) = 1;
6773 lhs_type = TREE_TYPE (lvalue);
6775 /* Or Lhs can be a array acccess. Should that be lvalue ? FIXME +
6776 comment on reason why */
6777 else if (TREE_CODE (wfl_op1) == ARRAY_REF)
6779 lhs_type = TREE_TYPE (lvalue);
6780 lvalue_from_array = 1;
6782 /* Or a field access */
6783 else if (TREE_CODE (lvalue) == COMPONENT_REF)
6784 lhs_type = TREE_TYPE (lvalue);
6785 /* Or a function return slot */
6786 else if (TREE_CODE (lvalue) == RESULT_DECL)
6787 lhs_type = TREE_TYPE (lvalue);
6788 /* Otherwise, this is an error */
6791 parse_error_context (wfl_op1, "Invalid left hand side of assignment");
6795 rhs_type = TREE_TYPE (rhs);
6796 /* 5.1 Try the assignment conversion for builtin type. */
6797 new_rhs = try_builtin_assignconv (wfl_op1, lhs_type, rhs);
6799 /* 5.2 If it failed, try a reference conversion */
6800 if (!new_rhs && (new_rhs = try_reference_assignconv (lhs_type, rhs)))
6801 lhs_type = promote_type (rhs_type);
6803 /* 15.25.2 If we have a compound assignment, convert RHS into the
6805 else if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
6806 new_rhs = convert (lhs_type, rhs);
6808 /* Explicit cast required. This is an error */
6811 char *t1 = strdup (lang_printable_name (TREE_TYPE (rhs), 0));
6812 char *t2 = strdup (lang_printable_name (lhs_type, 0));
6814 char operation [32]; /* Max size known */
6816 /* If the assignment is part of a declaration, we use the WFL of
6817 the declared variable to point out the error and call it a
6818 declaration problem. If the assignment is a genuine =
6819 operator, we call is a operator `=' problem, otherwise we
6820 call it an assignment problem. In both of these last cases,
6821 we use the WFL of the operator to indicate the error. */
6823 if (MODIFY_EXPR_FROM_INITIALIZATION_P (node))
6826 strcpy (operation, "declaration");
6831 if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
6832 strcpy (operation, "assignment");
6833 else if (TREE_CODE (TREE_OPERAND (node, 0)) == RESULT_DECL)
6834 strcpy (operation, "`return'");
6836 strcpy (operation, "`='");
6840 (wfl, (!valid_cast_to_p (rhs_type, lhs_type) ?
6841 "Incompatible type for %s. Can't convert `%s' to `%s'" :
6842 "Incompatible type for %s. Explicit cast "
6843 "needed to convert `%s' to `%s'"), operation, t1, t2);
6844 free (t1); free (t2);
6848 /* Before reporting type incompatibility errors, check that the rhs
6849 is initialized, if a variable */
6850 if (not_initialized_as_it_should_p (rhs))
6852 ERROR_VARIABLE_NOT_INITIALIZED (wfl_op2, DECL_NAME (rhs));
6853 INITIALIZED_P (rhs) = 1;
6857 return error_mark_node;
6859 /* If we built a compound expression as the result of a reference
6860 assignment into an array element, return it here. */
6861 if (TREE_CODE (node) == COMPOUND_EXPR)
6864 TREE_OPERAND (node, 0) = lvalue;
6865 TREE_OPERAND (node, 1) = new_rhs;
6866 TREE_TYPE (node) = lhs_type;
6870 /* Check that type SOURCE can be cast into type DEST. If the cast
6871 can't occur at all, return 0 otherwise 1. This function is used to
6872 produce accurate error messages on the reasons why an assignment
6876 try_reference_assignconv (lhs_type, rhs)
6879 tree new_rhs = NULL_TREE;
6880 tree rhs_type = TREE_TYPE (rhs);
6882 if (!JPRIMITIVE_TYPE_P (rhs_type) && JREFERENCE_TYPE_P (lhs_type))
6884 /* `null' may be assigned to any reference type */
6885 if (rhs == null_pointer_node)
6886 new_rhs = null_pointer_node;
6887 /* Try the reference assignment conversion */
6888 else if (valid_ref_assignconv_cast_p (rhs_type, lhs_type, 0))
6890 /* This is a magic assignment that we process differently */
6891 else if (rhs == soft_exceptioninfo_call_node)
6897 /* Check that RHS can be converted into LHS_TYPE by the assignment
6898 conversion (5.2), for the cases of RHS being a builtin type. Return
6899 NULL_TREE if the conversion fails or if because RHS isn't of a
6900 builtin type. Return a converted RHS if the conversion is possible. */
6903 try_builtin_assignconv (wfl_op1, lhs_type, rhs)
6904 tree wfl_op1, lhs_type, rhs;
6906 tree new_rhs = NULL_TREE;
6907 tree rhs_type = TREE_TYPE (rhs);
6909 /* 5.1.1 Try Identity Conversion,
6910 5.1.2 Try Widening Primitive Conversion */
6911 if (valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type))
6912 new_rhs = convert (lhs_type, rhs);
6914 /* Try a narrowing primitive conversion (5.1.3):
6915 - expression is a constant expression of type int AND
6916 - variable is byte, short or char AND
6917 - The value of the expression is representable in the type of the
6919 else if (rhs_type == int_type_node && TREE_CONSTANT (rhs)
6920 && (lhs_type == byte_type_node || lhs_type == char_type_node
6921 || lhs_type == short_type_node))
6923 if (int_fits_type_p (rhs, lhs_type))
6924 new_rhs = convert (lhs_type, rhs);
6925 else if (wfl_op1) /* Might be called with a NULL */
6926 parse_warning_context
6927 (wfl_op1, "Constant expression `%s' to wide for narrowing "
6928 "primitive conversion to `%s'",
6929 print_int_node (rhs), lang_printable_name (lhs_type, 0));
6930 /* Reported a warning that will turn into an error further
6931 down, so we don't return */
6937 /* Return 1 if RHS_TYPE can be converted to LHS_TYPE by identity
6938 conversion (5.1.1) or widening primitve conversion (5.1.2). Return
6939 0 is the conversion test fails. This implements parts the method
6940 invocation convertion (5.3). */
6943 valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type)
6944 tree lhs_type, rhs_type;
6947 JPRIMITIVE_TYPE_P (lhs_type) && JPRIMITIVE_TYPE_P (rhs_type);
6952 if (lhs_type == rhs_type)
6955 /* byte, even if it's smaller than a char can't be converted into a
6956 char. Short can't too, but the < test below takes care of that */
6957 if (lhs_type == char_type_node && rhs_type == byte_type_node)
6960 if (JINTEGRAL_TYPE_P (rhs_type)
6961 && ((TYPE_PRECISION (rhs_type) < TYPE_PRECISION (lhs_type))
6962 || (JFLOAT_TYPE_P (lhs_type) &&
6963 TYPE_PRECISION (rhs_type) == TYPE_PRECISION (lhs_type))))
6965 else if (JFLOAT_TYPE_P (rhs_type)
6966 && (TYPE_PRECISION (rhs_type) < TYPE_PRECISION (lhs_type)))
6972 /* Check that something of SOURCE type can be assigned or cast to
6973 something of DEST type at runtime. Return 1 if the operation is
6974 valid, 0 otherwise. If CAST is set to 1, we're treating the case
6975 were SOURCE is cast into DEST, which borrows a lot of the
6976 assignment check. */
6979 valid_ref_assignconv_cast_p (source, dest, cast)
6984 if (TREE_CODE (source) == POINTER_TYPE)
6985 source = TREE_TYPE (source);
6986 if (TREE_CODE (dest) == POINTER_TYPE)
6987 dest = TREE_TYPE (dest);
6988 /* Case where SOURCE is a class type */
6989 if (TYPE_CLASS_P (source))
6991 if (TYPE_CLASS_P (dest))
6992 return source == dest || inherits_from_p (source, dest)
6993 || (cast && inherits_from_p (dest, source));
6994 if (TYPE_INTERFACE_P (dest))
6996 /* If doing a cast and SOURCE is final, the operation is
6997 always correct a compile time (because even if SOURCE
6998 does not implement DEST, a subclass of SOURCE might). */
6999 if (cast && !CLASS_FINAL (TYPE_NAME (source)))
7001 /* Otherwise, SOURCE must implement DEST */
7002 return interface_of_p (dest, source);
7004 /* DEST is an array, cast permited if SOURCE is of Object type */
7005 return (cast && source == object_type_node ? 1 : 0);
7007 if (TYPE_INTERFACE_P (source))
7009 if (TYPE_CLASS_P (dest))
7011 /* If not casting, DEST must be the Object type */
7013 return dest == object_type_node;
7014 /* We're doing a cast. The cast is always valid is class
7015 DEST is not final, otherwise, DEST must implement SOURCE */
7016 else if (!CLASS_FINAL (TYPE_NAME (dest)))
7019 return interface_of_p (source, dest);
7021 if (TYPE_INTERFACE_P (dest))
7023 /* If doing a cast, then if SOURCE and DEST contain method
7024 with the same signature but different return type, then
7025 this is a (compile time) error */
7028 tree method_source, method_dest;
7032 for (method_source = TYPE_METHODS (source); method_source;
7033 method_source = TREE_CHAIN (method_source))
7036 build_java_argument_signature (TREE_TYPE (method_source));
7037 source_type = TREE_TYPE (TREE_TYPE (method_source));
7038 source_name = DECL_NAME (method_source);
7039 for (method_dest = TYPE_METHODS (dest);
7040 method_dest; method_dest = TREE_CHAIN (method_dest))
7042 build_java_argument_signature (TREE_TYPE (method_dest))
7043 && source_name == DECL_NAME (method_dest)
7044 && source_type != TREE_TYPE (TREE_TYPE (method_dest)))
7050 return source == dest || interface_of_p (dest, source);
7055 if (TYPE_ARRAY_P (source))
7057 if (TYPE_CLASS_P (dest))
7058 return dest == object_type_node;
7059 if (TYPE_INTERFACE_P (dest))
7060 return 0; /* Install test on Clonable. FIXME */
7063 tree source_element_type = TYPE_ARRAY_ELEMENT (source);
7064 tree dest_element_type = TYPE_ARRAY_ELEMENT (dest);
7066 /* In case of severe errors, they turn out null */
7067 if (!dest_element_type || !source_element_type)
7069 if (source_element_type == dest_element_type)
7071 return valid_ref_assignconv_cast_p (source_element_type,
7072 dest_element_type, cast);
7080 valid_cast_to_p (source, dest)
7084 if (TREE_CODE (source) == POINTER_TYPE)
7085 source = TREE_TYPE (source);
7086 if (TREE_CODE (dest) == POINTER_TYPE)
7087 dest = TREE_TYPE (dest);
7089 if (TREE_CODE (source) == RECORD_TYPE && TREE_CODE (dest) == RECORD_TYPE)
7090 return valid_ref_assignconv_cast_p (source, dest, 1);
7092 else if (JNUMERIC_TYPE_P (source) && JNUMERIC_TYPE_P (dest))
7098 /* Method invocation conversion test. Return 1 if type SOURCE can be
7099 converted to type DEST through the methond invocation conversion
7103 valid_method_invocation_conversion_p (dest, source)
7106 return ((JPRIMITIVE_TYPE_P (source)
7107 && JPRIMITIVE_TYPE_P (dest)
7108 && valid_builtin_assignconv_identity_widening_p (dest, source))
7109 || (JREFERENCE_TYPE_P (source)
7110 && JREFERENCE_TYPE_P (dest)
7111 && valid_ref_assignconv_cast_p (source, dest, 0)));
7114 /* Build an incomplete binop expression. */
7117 build_binop (op, op_location, op1, op2)
7124 binop = build (op, NULL_TREE, op1, op2);
7125 TREE_SIDE_EFFECTS (binop) = 1;
7126 /* Store the location of the operator, for better error report. The
7127 string of the operator will be rebuild based on the OP value. */
7128 EXPR_WFL_LINECOL (binop) = op_location;
7132 /* Build the string of the operator retained by NODE. If NODE is part
7133 of a compound expression, add an '=' at the end of the string. This
7134 function is called when an error needs to be reported on an
7135 operator. The string is returned as a pointer to a static character
7139 operator_string (node)
7142 #define BUILD_OPERATOR_STRING(S) \
7144 sprintf (buffer, "%s%s", S, (COMPOUND_ASSIGN_P (node) ? "=" : "")); \
7148 static char buffer [10];
7149 switch (TREE_CODE (node))
7151 case MULT_EXPR: BUILD_OPERATOR_STRING ("*");
7152 case RDIV_EXPR: BUILD_OPERATOR_STRING ("/");
7153 case TRUNC_MOD_EXPR: BUILD_OPERATOR_STRING ("%");
7154 case PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
7155 case MINUS_EXPR: BUILD_OPERATOR_STRING ("-");
7156 case LSHIFT_EXPR: BUILD_OPERATOR_STRING ("<<");
7157 case RSHIFT_EXPR: BUILD_OPERATOR_STRING (">>");
7158 case URSHIFT_EXPR: BUILD_OPERATOR_STRING (">>>");
7159 case BIT_AND_EXPR: BUILD_OPERATOR_STRING ("&");
7160 case BIT_XOR_EXPR: BUILD_OPERATOR_STRING ("^");
7161 case BIT_IOR_EXPR: BUILD_OPERATOR_STRING ("|");
7162 case TRUTH_ANDIF_EXPR: BUILD_OPERATOR_STRING ("&&");
7163 case TRUTH_ORIF_EXPR: BUILD_OPERATOR_STRING ("||");
7164 case EQ_EXPR: BUILD_OPERATOR_STRING ("==");
7165 case NE_EXPR: BUILD_OPERATOR_STRING ("!=");
7166 case GT_EXPR: BUILD_OPERATOR_STRING (">");
7167 case GE_EXPR: BUILD_OPERATOR_STRING (">=");
7168 case LT_EXPR: BUILD_OPERATOR_STRING ("<");
7169 case LE_EXPR: BUILD_OPERATOR_STRING ("<=");
7170 case UNARY_PLUS_EXPR: BUILD_OPERATOR_STRING ("+");
7171 case NEGATE_EXPR: BUILD_OPERATOR_STRING ("-");
7172 case TRUTH_NOT_EXPR: BUILD_OPERATOR_STRING ("!");
7173 case BIT_NOT_EXPR: BUILD_OPERATOR_STRING ("~");
7174 case PREINCREMENT_EXPR: /* Fall through */
7175 case POSTINCREMENT_EXPR: BUILD_OPERATOR_STRING ("++");
7176 case PREDECREMENT_EXPR: /* Fall through */
7177 case POSTDECREMENT_EXPR: BUILD_OPERATOR_STRING ("--");
7179 fatal ("unregistered operator %s - operator_string",
7180 tree_code_name [TREE_CODE (node)]);
7183 #undef BUILD_OPERATOR_STRING
7186 /* Binary operators (15.16 up to 15.18). We return error_mark_node on
7187 errors but we modify NODE so that it contains the type computed
7188 according to the expression, when it's fixed. Otherwise, we write
7189 error_mark_node as the type. It allows us to further the analysis
7190 of remaining nodes and detects more errors in certain cases. */
7193 patch_binop (node, wfl_op1, wfl_op2)
7198 tree op1 = TREE_OPERAND (node, 0);
7199 tree op2 = TREE_OPERAND (node, 1);
7200 tree op1_type = TREE_TYPE (op1);
7201 tree op2_type = TREE_TYPE (op2);
7203 int code = TREE_CODE (node);
7205 /* If 1, tell the routine that we have to return error_mark_node
7206 after checking for the initialization of the RHS */
7207 int error_found = 0;
7209 /* Figure what is going to be checked first for initialization prior
7210 its use. If NODE is part of a compound assignment, we check the
7211 second operand first, otherwise the first one first. We also
7212 initialize the matching WFL for the error report. `cfi' stands
7213 for Check For Initialization */
7214 tree cfi = (COMPOUND_ASSIGN_P (node) ? op2 : op1);
7215 tree cfi_wfl = (COMPOUND_ASSIGN_P (node) ? wfl_op2 : wfl_op1);
7217 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
7219 /* Check initialization of LHS first. We then silence further error
7220 message if the variable wasn't initialized */
7221 if (not_initialized_as_it_should_p (cfi))
7223 ERROR_VARIABLE_NOT_INITIALIZED (cfi_wfl, DECL_NAME (cfi));
7224 INITIALIZED_P (op1) = 1;
7229 /* 15.16 Multiplicative operators */
7230 case MULT_EXPR: /* 15.16.1 Multiplication Operator * */
7231 case RDIV_EXPR: /* 15.16.2 Division Operator / */
7232 case TRUNC_MOD_EXPR: /* 15.16.3 Remainder operator % */
7233 if (!JPRIMITIVE_TYPE_P (op1_type) || !JPRIMITIVE_TYPE_P (op2_type))
7235 if (!JPRIMITIVE_TYPE_P (op1_type))
7236 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
7237 if (!JPRIMITIVE_TYPE_P (op2_type) && (op1_type != op2_type))
7238 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
7239 TREE_TYPE (node) = error_mark_node;
7243 prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
7244 /* Change the division operator if necessary */
7245 if (code == RDIV_EXPR && TREE_CODE (prom_type) == INTEGER_TYPE)
7246 TREE_SET_CODE (node, TRUNC_DIV_EXPR);
7247 /* This one is more complicated. FLOATs are processed by a function
7248 call to soft_fmod. */
7249 if (code == TRUNC_MOD_EXPR)
7250 return build_java_binop (TRUNC_MOD_EXPR, prom_type, op1, op2);
7253 /* 15.17 Additive Operators */
7254 case PLUS_EXPR: /* 15.17.1 String Concatenation Operator + */
7256 /* Operation is valid if either one argument is a string
7257 constant, a String object or a StringBuffer crafted for the
7258 purpose of the a previous usage of the String concatenation
7261 if (TREE_CODE (op1) == STRING_CST
7262 || TREE_CODE (op2) == STRING_CST
7263 || JSTRING_TYPE_P (op1_type)
7264 || JSTRING_TYPE_P (op2_type)
7265 || IS_CRAFTED_STRING_BUFFER_P (op1)
7266 || IS_CRAFTED_STRING_BUFFER_P (op2))
7267 return build_string_concatenation (op1, op2);
7269 case MINUS_EXPR: /* 15.17.2 Additive Operators (+ and -) for
7271 if (!JPRIMITIVE_TYPE_P (op1_type) || !JPRIMITIVE_TYPE_P (op2_type))
7273 if (!JPRIMITIVE_TYPE_P (op1_type))
7274 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
7275 if (!JPRIMITIVE_TYPE_P (op2_type) && (op1_type != op2_type))
7276 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
7277 TREE_TYPE (node) = error_mark_node;
7281 prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
7284 /* 15.18 Shift Operators */
7288 if (!JINTEGRAL_TYPE_P (op1_type) || !JINTEGRAL_TYPE_P (op2_type))
7290 if (!JINTEGRAL_TYPE_P (op1_type))
7291 ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
7294 (wfl_operator, (JPRIMITIVE_TYPE_P (op2_type) ?
7295 "Incompatible type for `%s'. Explicit cast needed to convert "
7296 "shift distance from `%s' to integral" :
7297 "Incompatible type for `%s'. Can't convert shift distance from "
7298 "`%s' to integral"),
7299 operator_string (node), lang_printable_name (op2_type, 0));
7300 TREE_TYPE (node) = error_mark_node;
7305 /* Unary numeric promotion (5.6.1) is performed on each operand
7307 op1 = convert (promote_type (op1_type), op1);
7308 op2 = convert (promote_type (op2_type), op2);
7310 /* The type of the shift expression is the type of the promoted
7311 type of the left-hand operand */
7312 prom_type = TREE_TYPE (op1);
7314 /* Shift int only up to 0x1f and long up to 0x3f */
7315 if (prom_type == int_type_node)
7316 op2 = fold (build (BIT_AND_EXPR, int_type_node, op2,
7317 build_int_2 (0x1f, 0)));
7319 op2 = fold (build (BIT_AND_EXPR, int_type_node, op2,
7320 build_int_2 (0x3f, 0)));
7322 /* The >>> operator is a >> operating on unsigned quantities */
7323 if (code == URSHIFT_EXPR)
7325 op1 = convert (unsigned_type (prom_type), op1);
7326 TREE_SET_CODE (node, RSHIFT_EXPR);
7331 /* 15.21 Bitwise and Logical Operators */
7335 if (JINTEGRAL_TYPE_P (op1_type) && JINTEGRAL_TYPE_P (op2_type))
7336 /* Binary numeric promotion is performed on both operand and the
7337 expression retain that type */
7338 prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
7340 else if (TREE_CODE (op1_type) == BOOLEAN_TYPE
7341 && TREE_CODE (op1_type) == BOOLEAN_TYPE)
7342 /* The type of the bitwise operator expression is BOOLEAN */
7343 prom_type = boolean_type_node;
7346 if (!JINTEGRAL_TYPE_P (op1_type))
7347 ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op1_type);
7348 if (!JINTEGRAL_TYPE_P (op2_type) && (op1_type != op2_type))
7349 ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op2_type);
7350 TREE_TYPE (node) = error_mark_node;
7352 /* Insert a break here if adding thing before the switch's
7353 break for this case */
7357 /* 15.22 Conditional-And Operator */
7358 case TRUTH_ANDIF_EXPR:
7359 /* 15.23 Conditional-Or Operator */
7360 case TRUTH_ORIF_EXPR:
7361 /* Operands must be of BOOLEAN type */
7362 if (TREE_CODE (op1_type) != BOOLEAN_TYPE ||
7363 TREE_CODE (op2_type) != BOOLEAN_TYPE)
7365 if (TREE_CODE (op1_type) != BOOLEAN_TYPE)
7366 ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op1_type);
7367 if (TREE_CODE (op2_type) != BOOLEAN_TYPE && (op1_type != op2_type))
7368 ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op2_type);
7369 TREE_TYPE (node) = boolean_type_node;
7373 /* The type of the conditional operators is BOOLEAN */
7374 prom_type = boolean_type_node;
7377 /* 15.19.1 Numerical Comparison Operators <, <=, >, >= */
7382 /* The type of each of the operands must be a primitive numeric
7384 if (!JNUMERIC_TYPE_P (op1_type) || ! JNUMERIC_TYPE_P (op2_type))
7386 if (!JNUMERIC_TYPE_P (op1_type))
7387 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op1_type);
7388 if (!JNUMERIC_TYPE_P (op2_type) && (op1_type != op2_type))
7389 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op2_type);
7390 TREE_TYPE (node) = boolean_type_node;
7394 /* Binary numeric promotion is performed on the operands */
7395 binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
7396 /* The type of the relation expression is always BOOLEAN */
7397 prom_type = boolean_type_node;
7400 /* 15.20 Equality Operator */
7403 /* 15.20.1 Numerical Equality Operators == and != */
7404 /* Binary numeric promotion is performed on the operands */
7405 if (JPRIMITIVE_TYPE_P (op1_type) && JPRIMITIVE_TYPE_P (op2_type))
7406 binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
7408 /* 15.20.2 Boolean Equality Operators == and != */
7409 else if (TREE_CODE (op1_type) == BOOLEAN_TYPE &&
7410 TREE_CODE (op2_type) == BOOLEAN_TYPE)
7411 ; /* Nothing to do here */
7413 /* 15.20.3 Reference Equality Operators == and != */
7414 /* Types have to be either references or the null type */
7415 else if (op1 == null_pointer_node || op2 == null_pointer_node
7416 || (JREFERENCE_TYPE_P (op1_type) && JREFERENCE_TYPE_P (op2_type)
7417 && ((op1_type == op2_type))))
7418 ; /* Nothing to do here */
7420 /* Else we have an error figure what can't be converted into
7421 what and report the error */
7425 t1 = strdup (lang_printable_name (op1_type, 0));
7427 (wfl_operator, "Incompatible type for `%s'. Can't convert `%s' "
7428 "to `%s'", operator_string (node), t1,
7429 lang_printable_name (op2_type, 0));
7431 TREE_TYPE (node) = boolean_type_node;
7435 prom_type = boolean_type_node;
7439 /* Then check the initialization of the RHS. We don't do that if
7440 we're dealing with a node that is part of a compound
7441 assignment. We then silence further error message if the variable
7442 wasn't initialized */
7443 if (not_initialized_as_it_should_p (op2) && !COMPOUND_ASSIGN_P (node))
7445 ERROR_VARIABLE_NOT_INITIALIZED (wfl_op2, DECL_NAME (op2));
7446 INITIALIZED_P (op2) = 1;
7450 return error_mark_node;
7452 TREE_OPERAND (node, 0) = op1;
7453 TREE_OPERAND (node, 1) = op2;
7454 TREE_TYPE (node) = prom_type;
7458 /* Concatenate the STRING_CST CSTE and STRING. When AFTER is a non
7459 zero value, the value of CSTE comes after the valude of STRING */
7462 do_merge_string_cste (cste, string, string_len, after)
7465 int string_len, after;
7467 int len = TREE_STRING_LENGTH (cste) + string_len;
7468 char *old = TREE_STRING_POINTER (cste);
7469 TREE_STRING_LENGTH (cste) = len;
7470 TREE_STRING_POINTER (cste) = obstack_alloc (expression_obstack, len+1);
7473 strcpy (TREE_STRING_POINTER (cste), string);
7474 strcat (TREE_STRING_POINTER (cste), old);
7478 strcpy (TREE_STRING_POINTER (cste), old);
7479 strcat (TREE_STRING_POINTER (cste), string);
7484 /* Tries to merge OP1 (a STRING_CST) and OP2 (if suitable). Return a
7485 new STRING_CST on success, NULL_TREE on failure */
7488 merge_string_cste (op1, op2, after)
7492 /* Handle two string constants right away */
7493 if (TREE_CODE (op2) == STRING_CST)
7494 return do_merge_string_cste (op1, TREE_STRING_POINTER (op2),
7495 TREE_STRING_LENGTH (op2), after);
7497 /* Reasonable integer constant can be treated right away */
7498 if (TREE_CODE (op2) == INTEGER_CST && !TREE_CONSTANT_OVERFLOW (op2))
7500 static char *boolean_true = "true";
7501 static char *boolean_false = "false";
7502 static char *null_pointer = "null";
7506 if (op2 == boolean_true_node)
7507 string = boolean_true;
7508 else if (op2 == boolean_false_node)
7509 string = boolean_false;
7510 else if (op2 == null_pointer_node)
7511 string = null_pointer;
7512 else if (TREE_TYPE (op2) == char_type_node)
7514 ch[0] = (char )TREE_INT_CST_LOW (op2);
7519 string = print_int_node (op2);
7521 return do_merge_string_cste (op1, string, strlen (string), after);
7526 /* Tries to statically concatenate OP1 and OP2 if possible. Either one
7527 has to be a STRING_CST and the other part must be a STRING_CST or a
7528 INTEGRAL constant. Return a new STRING_CST if the operation
7529 succeed, NULL_TREE otherwise.
7531 If the case we want to optimize for space, we might want to return
7532 NULL_TREE for each invocation of this routine. FIXME */
7535 string_constant_concatenation (op1, op2)
7538 if (TREE_CODE (op1) == STRING_CST || (TREE_CODE (op2) == STRING_CST))
7543 string = (TREE_CODE (op1) == STRING_CST ? op1 : op2);
7544 rest = (string == op1 ? op2 : op1);
7545 invert = (string == op1 ? 0 : 1 );
7547 /* Walk REST, only if it looks reasonable */
7548 if (TREE_CODE (rest) != STRING_CST
7549 && !IS_CRAFTED_STRING_BUFFER_P (rest)
7550 && !JSTRING_TYPE_P (TREE_TYPE (rest))
7551 && TREE_CODE (rest) == EXPR_WITH_FILE_LOCATION)
7553 rest = java_complete_tree (rest);
7554 if (rest == error_mark_node)
7555 return error_mark_node;
7558 return merge_string_cste (string, rest, invert);
7563 /* Implement the `+' operator. Does static optimization if possible,
7564 otherwise create (if necessary) and append elements to a
7565 StringBuffer. The StringBuffer will be carried around until it is
7566 used for a function call or an assignment. Then toString() will be
7567 called on it to turn it into a String object. */
7570 build_string_concatenation (op1, op2)
7575 /* Try to do some static optimization */
7576 if ((result = string_constant_concatenation (op1, op2)))
7579 /* If operands are string constant, turn then into object references */
7581 if (TREE_CODE (op1) == STRING_CST)
7582 op1 = patch_string_cst (op1);
7583 if (TREE_CODE (op2) == STRING_CST)
7584 op2 = patch_string_cst (op2);
7586 /* If OP1 isn't already a StringBuffer, create and
7587 initialize a new one */
7588 if (!IS_CRAFTED_STRING_BUFFER_P (op1))
7590 /* Two solutions here:
7591 1) OP1 is a string reference, we call new StringBuffer(OP1)
7592 2) Op2 is something else, we call new StringBuffer().append(OP1). */
7593 if (JSTRING_TYPE_P (TREE_TYPE (op1)))
7594 op1 = BUILD_STRING_BUFFER (op1);
7597 tree aNew = BUILD_STRING_BUFFER (NULL_TREE);
7598 op1 = make_qualified_primary (aNew, BUILD_APPEND (op1), 0);
7602 /* No longer the last node holding a crafted StringBuffer */
7603 IS_CRAFTED_STRING_BUFFER_P (op1) = 0;
7604 /* Create a node for `{new...,xxx}.append (op2)' */
7605 op1 = make_qualified_primary (op1, BUILD_APPEND (op2), 0);
7606 /* Mark the last node holding a crafted StringBuffer */
7607 IS_CRAFTED_STRING_BUFFER_P (op1) = 1;
7612 /* Patch the string node NODE. NODE can be a STRING_CST of a crafted
7613 StringBuffer. If no string were found to be patched, return
7620 if (TREE_CODE (node) == STRING_CST)
7621 return patch_string_cst (node);
7622 else if (IS_CRAFTED_STRING_BUFFER_P (node))
7624 tree invoke = build_method_invocation (wfl_to_string, NULL_TREE);
7625 return java_complete_tree (make_qualified_primary (node, invoke, 0));
7630 /* Build the internal representation of a string constant. */
7633 patch_string_cst (node)
7637 push_obstacks (&permanent_obstack, &permanent_obstack);
7638 node = get_identifier (TREE_STRING_POINTER (node));
7639 location = alloc_name_constant (CONSTANT_String, node);
7640 node = build_ref_from_constant_pool (location);
7641 TREE_TYPE (node) = promote_type (string_type_node);
7642 TREE_CONSTANT (node) = 1;
7646 /* Build an incomplete unary operator expression. */
7649 build_unaryop (op_token, op_location, op1)
7650 int op_token, op_location;
7657 case PLUS_TK: op = UNARY_PLUS_EXPR; break;
7658 case MINUS_TK: op = NEGATE_EXPR; break;
7659 case NEG_TK: op = TRUTH_NOT_EXPR; break;
7660 case NOT_TK: op = BIT_NOT_EXPR; break;
7661 default: fatal ("Unknown token `%d' for unary operator - build_unaryop",
7665 unaryop = build1 (op, NULL_TREE, op1);
7666 TREE_SIDE_EFFECTS (unaryop) = 1;
7667 /* Store the location of the operator, for better error report. The
7668 string of the operator will be rebuild based on the OP value. */
7669 EXPR_WFL_LINECOL (unaryop) = op_location;
7673 /* Special case for the ++/-- operators, since they require an extra
7674 argument to build, which is set to NULL and patched
7675 later. IS_POST_P is 1 if the operator, 0 otherwise. */
7678 build_incdec (op_token, op_location, op1, is_post_p)
7679 int op_token, op_location;
7683 static enum tree_code lookup [2][2] =
7685 { PREDECREMENT_EXPR, PREINCREMENT_EXPR, },
7686 { POSTDECREMENT_EXPR, POSTINCREMENT_EXPR, },
7688 tree node = build (lookup [is_post_p][(op_token - DECR_TK)],
7689 NULL_TREE, op1, NULL_TREE);
7690 TREE_SIDE_EFFECTS (node) = 1;
7691 /* Store the location of the operator, for better error report. The
7692 string of the operator will be rebuild based on the OP value. */
7693 EXPR_WFL_LINECOL (node) = op_location;
7697 /* Build an incomplete cast operator, based on the use of the
7698 CONVERT_EXPR. Note that TREE_TYPE of the constructed node is
7699 set. java_complete_tree is trained to walk a CONVERT_EXPR even
7700 though its type is already set. */
7703 build_cast (location, type, exp)
7707 tree node = build1 (CONVERT_EXPR, type, exp);
7708 EXPR_WFL_LINECOL (node) = location;
7712 /* 15.14 Unary operators. We return error_mark_node in case of error,
7713 but preserve the type of NODE if the type is fixed. */
7716 patch_unaryop (node, wfl_op)
7720 tree op = TREE_OPERAND (node, 0);
7721 tree op_type = TREE_TYPE (op);
7722 tree prom_type, value;
7723 int code = TREE_CODE (node);
7724 int error_found = 0;
7726 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
7730 /* 15.13.2 Postfix Increment Operator ++ */
7731 case POSTINCREMENT_EXPR:
7732 /* 15.13.3 Postfix Increment Operator -- */
7733 case POSTDECREMENT_EXPR:
7734 /* 15.14.1 Prefix Increment Operator ++ */
7735 case PREINCREMENT_EXPR:
7736 /* 15.14.2 Prefix Decrement Operator -- */
7737 case PREDECREMENT_EXPR:
7738 if (!DECL_P (op) && !(TREE_CODE (op) == INDIRECT_REF
7739 && JPRIMITIVE_TYPE_P (TREE_TYPE (op))))
7741 parse_error_context (wfl_operator, "Invalid argument to `%s'",
7742 operator_string (node));
7743 TREE_TYPE (node) = error_mark_node;
7746 else if (FIELD_FINAL (op))
7749 (wfl_op, "Can't assign a value to the final variable `%s'",
7750 IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl_op)));
7751 TREE_TYPE (node) = error_mark_node;
7754 /* From now on, we know that op if a variable and that it has a
7755 valid wfl. We use wfl_op to locate errors related to the
7757 else if (!JNUMERIC_TYPE_P (op_type))
7760 (wfl_op, "Invalid argument type `%s' to `%s'",
7761 lang_printable_name (op_type, 0), operator_string (node));
7762 TREE_TYPE (node) = error_mark_node;
7767 /* Before the addition, binary numeric promotion if performed on
7769 value = integer_one_node;
7770 prom_type = binary_numeric_promotion (op_type, TREE_TYPE (value),
7772 /* And write the promoted increment back */
7773 TREE_OPERAND (node, 1) = value;
7777 /* 15.14.3 Unary Plus Operator + */
7778 case UNARY_PLUS_EXPR:
7779 /* 15.14.4 Unary Minus Operator - */
7781 if (!JNUMERIC_TYPE_P (op_type))
7783 ERROR_CANT_CONVERT_TO_NUMERIC (wfl_operator, node, op_type);
7784 TREE_TYPE (node) = error_mark_node;
7787 /* Unary numeric promotion is performed on operand */
7790 prom_type = promote_type (op_type);
7791 op = convert (prom_type, op);
7792 if (code == UNARY_PLUS_EXPR)
7797 /* 15.14.5 Bitwise Complement Operator ~ */
7799 if (!JINTEGRAL_TYPE_P (op_type))
7801 ERROR_CAST_NEEDED_TO_INTEGRAL (wfl_operator, node, op_type);
7802 TREE_TYPE (node) = error_mark_node;
7807 prom_type = promote_type (op_type);
7808 op = convert (prom_type, op);
7812 /* 15.14.6 Logical Complement Operator ! */
7813 case TRUTH_NOT_EXPR:
7814 if (TREE_CODE (op_type) != BOOLEAN_TYPE)
7816 ERROR_CANT_CONVERT_TO_BOOLEAN (wfl_operator, node, op_type);
7817 TREE_TYPE (node) = boolean_type_node;
7821 prom_type = boolean_type_node;
7824 /* 15.15 Cast Expression */
7826 value = patch_cast (node, wfl_operator);
7827 if (value == error_mark_node)
7829 TREE_TYPE (node) = error_mark_node;
7837 /* Check variable initialization */
7838 if (not_initialized_as_it_should_p (op))
7840 ERROR_VARIABLE_NOT_INITIALIZED (wfl_op, DECL_NAME (op));
7841 INITIALIZED_P (op) = 1;
7845 return error_mark_node;
7846 /* In the case of UNARY_PLUS_EXPR, we replaced NODE by a new one */
7847 else if (code != UNARY_PLUS_EXPR && code != CONVERT_EXPR)
7849 TREE_OPERAND (node, 0) = op;
7850 TREE_TYPE (node) = prom_type;
7855 /* Generic type resolution that sometimes takes place during node
7856 patching. Returned the resolved type or generate an error
7857 message. Return the resolved type or NULL_TREE. */
7860 resolve_type_during_patch (type)
7863 if (unresolved_type_p (type, NULL))
7865 tree type_decl = resolve_no_layout (EXPR_WFL_NODE (type), NULL_TREE);
7868 parse_error_context (type,
7869 "Class `%s' not found in type declaration",
7870 IDENTIFIER_POINTER (EXPR_WFL_NODE (type)));
7874 return TREE_TYPE (type_decl);
7878 /* 5.5 Casting Conversion. error_mark_node is returned if an error is
7879 found. Otherwise NODE or something meant to replace it is returned. */
7882 patch_cast (node, wfl_operator)
7886 tree op = TREE_OPERAND (node, 0);
7887 tree op_type = TREE_TYPE (op);
7888 tree cast_type = TREE_TYPE (node);
7891 /* First resolve OP_TYPE if unresolved */
7892 if (!(cast_type = resolve_type_during_patch (cast_type)))
7893 return error_mark_node;
7895 /* Check on cast that are proven correct at compile time */
7896 if (JNUMERIC_TYPE_P (cast_type) && JNUMERIC_TYPE_P (op_type))
7898 static tree convert_narrow ();
7900 if (cast_type == op_type)
7903 /* Try widening/narowwing convertion. Potentially, things need
7904 to be worked out in gcc so we implement the extreme cases
7905 correctly. fold_convert() needs to be fixed. */
7906 return convert (cast_type, op);
7909 /* The remaining legal casts involve conversion between reference
7910 types. Check for their compile time correctness. */
7911 if (JREFERENCE_TYPE_P (op_type) && JREFERENCE_TYPE_P (cast_type)
7912 && valid_ref_assignconv_cast_p (cast_type, op_type, 1))
7914 TREE_TYPE (node) = promote_type (cast_type);
7915 /* Now, the case can be determined correct at compile time if
7916 OP_TYPE can be converted into CAST_TYPE by assignment
7919 if (valid_ref_assignconv_cast_p (op_type, cast_type, 0))
7922 /* The cast requires a run-time check */
7923 return build (CALL_EXPR, promote_type (cast_type),
7924 build_address_of (soft_checkcast_node),
7925 tree_cons (NULL_TREE, build_class_ref (cast_type),
7926 build_tree_list (NULL_TREE, op)),
7930 /* Any other casts are proven incorrect at compile time */
7931 t1 = strdup (lang_printable_name (op_type, 0));
7932 parse_error_context (wfl_operator, "Invalid cast from `%s' to `%s'",
7933 t1, lang_printable_name (cast_type, 0));
7935 return error_mark_node;
7938 /* Build an ARRAY_REF incomplete tree node. Note that operand 1 isn't
7939 a list of indices. */
7941 build_array_ref (location, array, index)
7945 tree node = build (ARRAY_REF, NULL_TREE, array, index);
7946 EXPR_WFL_LINECOL (node) = location;
7950 /* 15.12 Array Access Expression */
7953 patch_array_ref (node, wfl_array, wfl_index)
7954 tree node, wfl_array, wfl_index;
7956 tree array = TREE_OPERAND (node, 0);
7957 tree array_type = TREE_TYPE (array);
7958 tree index = TREE_OPERAND (node, 1);
7959 tree index_type = TREE_TYPE (index);
7960 tree promoted_index_type;
7961 int error_found = 0;
7963 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
7965 if (not_initialized_as_it_should_p (array))
7967 ERROR_VARIABLE_NOT_INITIALIZED (wfl_array, DECL_NAME (array));
7968 INITIALIZED_P (array) = 1;
7971 if (TREE_CODE (array_type) == POINTER_TYPE)
7972 array_type = TREE_TYPE (array_type);
7974 /* The array reference must be an array */
7975 if (!TYPE_ARRAY_P (array_type))
7978 (wfl_operator, "`[]' can only be applied to arrays. It can't be "
7979 "applied to `%s'", lang_printable_name (array_type, 0));
7980 TREE_TYPE (node) = error_mark_node;
7984 /* The array index underdoes unary numeric promotion. The promoted
7986 promoted_index_type = promote_type (index_type);
7987 if (promoted_index_type != int_type_node)
7989 int could_cast = valid_cast_to_p (index_type, int_type_node);
7992 (could_cast ? "Incompatible type for `[]'. Explicit cast needed to "
7993 "convert `%s' to `int'" : "Incompatible type for `[]'. "
7994 "Can't convert `%s' to `int'"),
7995 lang_printable_name (index_type, 0));
7996 TREE_TYPE (node) = error_mark_node;
8000 /* Now if the index is a var/parm decl, check on its initialization */
8001 if (not_initialized_as_it_should_p (index))
8003 ERROR_VARIABLE_NOT_INITIALIZED (wfl_index, DECL_NAME (index));
8004 INITIALIZED_P (index) = 1;
8008 return error_mark_node;
8009 index = convert (promoted_index_type, index);
8011 if (TREE_CODE (array_type) == RECORD_TYPE)
8012 array_type = promote_type (TYPE_ARRAY_ELEMENT (array_type));
8013 if (flag_emit_class_files)
8015 TREE_OPERAND (node, 0)= array;
8016 TREE_OPERAND (node, 1)= index;
8019 node = build_java_arrayaccess (array, array_type, index);
8020 TREE_TYPE (node) = array_type;
8024 /* 15.9 Array Creation Expressions */
8027 build_newarray_node (type, dims, extra_dims)
8033 build (NEW_ARRAY_EXPR, NULL_TREE, type, nreverse (dims),
8034 build_int_2 (extra_dims, 0));
8039 patch_newarray (node)
8042 tree type = TREE_OPERAND (node, 0);
8043 tree dims = TREE_OPERAND (node, 1);
8044 tree cdim, array_type;
8045 int error_found = 0;
8047 int xdims = TREE_INT_CST_LOW (TREE_OPERAND (node, 2));
8050 /* Dimension types are verified. It's better for the types to be
8051 verified in order. */
8052 for (cdim = dims, ndims = 0; cdim; cdim = TREE_CHAIN (cdim), ndims++ )
8055 tree dim = TREE_VALUE (cdim);
8057 /* Dim might have been saved during its evaluation */
8058 dim = (TREE_CODE (dim) == SAVE_EXPR ? dim = TREE_OPERAND (dim, 0) : dim);
8060 /* The type of each specified dimension must be an integral type. */
8061 if (!JINTEGRAL_TYPE_P (TREE_TYPE (dim)))
8064 /* Each expression undergoes an unary numeric promotion (5.6.1) and the
8065 promoted type must be int. */
8068 dim = convert (promote_type (TREE_TYPE (dim)), dim);
8069 if (TREE_TYPE (dim) != int_type_node)
8073 /* Report errors on types here */
8077 (TREE_PURPOSE (cdim),
8078 "Incompatible type for dimension in array creation expression. "
8079 "%s convert `%s' to `int'",
8080 (valid_cast_to_p (TREE_TYPE (dim), int_type_node) ?
8081 "Explicit cast needed to" : "Can't"),
8082 lang_printable_name (TREE_TYPE (dim), 0));
8086 /* Check for uninitialized variables */
8087 if (not_initialized_as_it_should_p (dim))
8089 ERROR_VARIABLE_NOT_INITIALIZED (TREE_PURPOSE (cdim),
8091 INITIALIZED_P (dim) = 1;
8095 TREE_PURPOSE (cdim) = NULL_TREE;
8098 /* Resolve array base type if unresolved */
8099 if (!(type = resolve_type_during_patch (type)))
8104 /* We don't want further evaluation of this bogus array creation
8106 TREE_TYPE (node) = error_mark_node;
8107 return error_mark_node;
8110 /* The node is transformed into a function call. Things are done
8111 differently according to the number of dimensions. If the number
8112 of dimension is equal to 1, then the nature of the base type
8113 (primitive or not) matters. */
8114 total_dims = xdims + ndims;
8115 if (total_dims == 1)
8117 if (JPRIMITIVE_TYPE_P (type))
8120 if (type == boolean_type_node)
8122 else if (type == char_type_node)
8124 else if (type == float_type_node)
8126 else if (type == double_type_node)
8128 else if (type == byte_type_node)
8130 else if (type == short_type_node)
8132 else if (type == int_type_node)
8134 else if (type == long_type_node)
8137 fatal ("Can't compute type code - patch_newarray");
8138 return build_newarray (type_code, TREE_VALUE (dims));
8141 return build_anewarray (type, TREE_VALUE (dims));
8144 /* Add extra dimensions as unknown dimensions */
8147 chainon (dims, build_tree_list (NULL_TREE, integer_negative_one_node));
8148 dims = chainon (dims, build_tree_list (NULL_TREE, integer_zero_node));
8150 /* Can't reuse what's already written in expr.c because it uses the
8151 JVM stack representation. Provide a build_multianewarray. FIXME */
8153 for (cdim = TREE_CHAIN (dims); cdim; cdim = TREE_CHAIN (cdim))
8154 array_type = build_java_array_type (promote_type (array_type),
8155 TREE_CODE (cdim) == INTEGER_CST ?
8156 TREE_INT_CST_LOW (cdim) : -1);
8157 return build (CALL_EXPR,
8158 promote_type (array_type),
8159 build_address_of (soft_multianewarray_node),
8160 tree_cons (NULL_TREE, build_class_ref (array_type),
8161 tree_cons (NULL_TREE,
8162 build_int_2 (total_dims, 0), dims )),
8167 build_this (location)
8170 tree node = build_wfl_node (this_identifier_node, input_filename, 0, 0);
8171 TREE_SET_CODE (node, THIS_EXPR);
8172 EXPR_WFL_LINECOL (node) = location;
8176 /* 14.15 The return statement. It builds a modify expression that
8177 assigns the returned value to the RESULT_DECL that hold the value
8181 build_return (location, op)
8185 tree node = build1 (RETURN_EXPR, NULL_TREE, op);
8186 EXPR_WFL_LINECOL (node) = location;
8187 node = build_debugable_stmt (location, node);
8195 tree return_exp = TREE_OPERAND (node, 0);
8196 tree meth = current_function_decl;
8197 tree mtype = TREE_TYPE (TREE_TYPE (current_function_decl));
8199 int error_found = 0;
8201 TREE_TYPE (node) = error_mark_node;
8202 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
8204 /* It's invalid to have a return value within a function that is
8205 declared with the keyword void or that is a constructor */
8206 if (return_exp && (mtype == void_type_node || DECL_CONSTRUCTOR_P (meth)))
8209 /* It's invalid to have a no return value within a function that
8210 isn't declared with the keyword `void' */
8211 if (!return_exp && (mtype != void_type_node && !DECL_CONSTRUCTOR_P (meth)))
8216 char *t = strdup (lang_printable_name (mtype, 0));
8217 parse_error_context (wfl_operator, "`return' with%s value from `%s %s'",
8218 (error_found == 1 ? "" : "out"), t,
8219 lang_printable_name (meth, 0));
8221 return error_mark_node;
8224 /* If we have a return_exp, build a modify expression and expand it */
8227 modify = build (MODIFY_EXPR, NULL_TREE, DECL_RESULT (meth), return_exp);
8228 EXPR_WFL_LINECOL (modify) = EXPR_WFL_LINECOL (node);
8229 modify = java_complete_tree (modify);
8230 if (modify != error_mark_node)
8232 TREE_SIDE_EFFECTS (modify) = 1;
8233 TREE_OPERAND (node, 0) = modify;
8236 return error_mark_node;
8238 TREE_TYPE (node) = void_type_node;
8239 TREE_SIDE_EFFECTS (node) = 1;
8243 /* 14.8 The if Statement */
8246 build_if_else_statement (location, expression, if_body, else_body)
8248 tree expression, if_body, else_body;
8251 /* FIXME: make else body be a void node, where this function is
8254 else_body = build (COMPOUND_EXPR, void_type_node, NULL_TREE, NULL_TREE);
8255 node = build (COND_EXPR, NULL_TREE, expression, if_body, else_body);
8256 EXPR_WFL_LINECOL (node) = location;
8257 node = build_debugable_stmt (location, node);
8262 patch_if_else_statement (node)
8265 tree expression = TREE_OPERAND (node, 0);
8267 TREE_TYPE (node) = error_mark_node;
8268 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
8270 /* The type of expression must be boolean */
8271 if (TREE_TYPE (expression) != boolean_type_node
8272 && TREE_TYPE (expression) != promoted_boolean_type_node)
8276 "Incompatible type for `if'. Can't convert `%s' to `boolean'",
8277 lang_printable_name (TREE_TYPE (expression), 0));
8278 return error_mark_node;
8281 TREE_TYPE (node) = void_type_node;
8282 TREE_SIDE_EFFECTS (node) = 1;
8286 /* 14.6 Labeled Statements */
8288 /* Action taken when a lableled statement is parsed. a new
8289 LABELED_BLOCK_EXPR is created. No statement is attached to the
8293 build_labeled_block (location, label)
8297 tree label_name = merge_qualified_name (label_id, label);
8298 tree label_decl, node;
8300 /* Issue a warning if we try to reuse a label that was previously
8302 if (IDENTIFIER_LOCAL_VALUE (label_name))
8304 EXPR_WFL_LINECOL (wfl_operator) = location;
8305 parse_warning_context (wfl_operator, "Declaration of `%s' shadows "
8306 "a previous declaration",
8307 IDENTIFIER_POINTER (label));
8308 EXPR_WFL_LINECOL (wfl_operator) =
8309 EXPR_WFL_LINECOL (IDENTIFIER_LOCAL_VALUE (label_name));
8310 parse_warning_context (wfl_operator, "This is the location of the "
8311 "previous declaration of label `%s'",
8312 IDENTIFIER_POINTER (label));
8313 java_warning_count--;
8316 label_decl = create_label_decl (label_name);
8317 node = build (LABELED_BLOCK_EXPR, NULL_TREE, label_decl, NULL_TREE);
8318 EXPR_WFL_LINECOL (node) = location;
8319 TREE_SIDE_EFFECTS (node) = 1;
8323 /* Generate a label crafting a unique name for it. This is used to
8324 implicitely label loops that aren't the body part of labeled
8328 generate_labeled_block ()
8330 return build_labeled_block (0, generate_name ());
8333 /* A labeled statement LBE is attached a statement. */
8336 complete_labeled_statement (lbe, statement)
8337 tree lbe; /* Labeled block expr */
8340 /* In anyways, tie the loop to its statement */
8341 LABELED_BLOCK_BODY (lbe) = statement;
8343 /* Ok, if statement is a for loop, we have to attach the labeled
8344 statement to the block the for loop belongs to and return the
8346 if (TREE_CODE (statement) == LOOP_EXPR && IS_FOR_LOOP_P (statement))
8348 java_method_add_stmt (current_function_decl, lbe);
8349 return exit_block ();
8355 /* 14.10, 14.11, 14.12 Loop Statements */
8357 /* Create an empty LOOP_EXPR and make it the last in the nested loop
8361 build_new_loop (loop_body)
8364 tree loop = build (LOOP_EXPR, NULL_TREE, loop_body);
8365 TREE_SIDE_EFFECTS (loop) = 1;
8370 /* Create a loop body according to the following structure:
8372 COMPOUND_EXPR (loop main body)
8373 EXIT_EXPR (this order is for while/for loops.
8374 LABELED_BLOCK_EXPR the order is reversed for do loops)
8375 LABEL_DECL (continue occurding here branche at the
8376 BODY end of this labeled block)
8379 REVERSED, if non zero, tells that the loop condition expr comes
8380 after the body, like in the do-while loop.
8382 To obtain a loop, the loop body structure described above is
8383 encapsulated within a LOOP_EXPR surrounded by a LABELED_BLOCK_EXPR:
8386 LABEL_DECL (use this label to exit the loop)
8388 <structure described above> */
8391 build_loop_body (location, condition, reversed)
8396 tree first, second, body;
8398 condition = build (EXIT_EXPR, NULL_TREE, condition); /* Force walk */
8399 EXPR_WFL_LINECOL (condition) = location; /* For accurate error report */
8400 condition = build_debugable_stmt (location, condition);
8401 TREE_SIDE_EFFECTS (condition) = 1;
8403 body = generate_labeled_block ();
8404 first = (reversed ? body : condition);
8405 second = (reversed ? condition : body);
8407 build (COMPOUND_EXPR, NULL_TREE,
8408 build (COMPOUND_EXPR, NULL_TREE, first, second), size_zero_node);
8411 /* Install CONDITION (if any) and loop BODY (using REVERSED to tell
8412 their order) on the current loop. Unlink the current loop from the
8416 complete_loop_body (location, condition, body, reversed)
8418 tree condition, body;
8421 tree to_return = ctxp->current_loop;
8422 tree loop_body = LOOP_EXPR_BODY (to_return);
8425 tree cnode = LOOP_EXPR_BODY_CONDITION_EXPR (loop_body, reversed);
8426 /* We wrapped the EXIT_EXPR around a WFL so we can debug it.
8427 The real EXIT_EXPR is one operand further. */
8428 EXPR_WFL_LINECOL (cnode) = location;
8429 /* This one is for accurate error reports */
8430 EXPR_WFL_LINECOL (TREE_OPERAND (cnode, 0)) = location;
8431 TREE_OPERAND (TREE_OPERAND (cnode, 0), 0) = condition;
8433 LOOP_EXPR_BODY_BODY_EXPR (loop_body, reversed) = body;
8438 /* Tailored version of complete_loop_body for FOR loops, when FOR
8439 loops feature the condition part */
8442 complete_for_loop (location, condition, update, body)
8444 tree condition, update, body;
8446 /* Put the condition and the loop body in place */
8447 tree loop = complete_loop_body (location, condition, body, 0);
8448 /* LOOP is the current loop which has been now popped of the loop
8449 stack. Install the update block */
8450 LOOP_EXPR_BODY_UPDATE_BLOCK (LOOP_EXPR_BODY (loop)) = update;
8454 /* If the loop isn't surrounded by a labeled statement, create one and
8455 insert LOOP as it's body. */
8458 patch_loop_statement (loop)
8461 tree loop_label, to_return_as_loop;
8463 if (LOOP_HAS_LABEL_P (loop))
8465 loop_label = ctxp->current_labeled_block;
8466 to_return_as_loop = loop;
8470 loop_label = generate_labeled_block ();
8471 LABELED_BLOCK_BODY (loop_label) = loop;
8472 PUSH_LABELED_BLOCK (loop_label);
8473 to_return_as_loop = loop_label;
8475 TREE_TYPE (to_return_as_loop) = void_type_node;
8476 return to_return_as_loop;
8479 /* 14.13, 14.14: break and continue Statements */
8481 /* Build a break or a continue statement. a null NAME indicates an
8482 unlabeled break/continue statement. */
8485 build_bc_statement (location, is_break, name)
8486 int location, is_break;
8489 tree break_continue, label_block_expr = NULL_TREE;
8493 if (!(label_block_expr = IDENTIFIER_LOCAL_VALUE
8494 (merge_qualified_name (label_id, EXPR_WFL_NODE (name)))))
8495 /* Null means that we don't have a target for this named
8496 break/continue. In this case, we make the target to be the
8497 label name, so that the error can be reported accuratly in
8498 patch_bc_statement. */
8499 label_block_expr = EXPR_WFL_NODE (name);
8501 /* Unlabeled break/continue will be handled during the
8502 break/continue patch operation */
8504 = build (EXIT_BLOCK_EXPR, NULL_TREE, label_block_expr, NULL_TREE);
8506 IS_BREAK_STMT_P (break_continue) = is_break;
8507 TREE_SIDE_EFFECTS (break_continue) = 1;
8508 EXPR_WFL_LINECOL (break_continue) = location;
8509 break_continue = build_debugable_stmt (location, break_continue);
8510 return break_continue;
8513 /* Verification of a break/continue statement. */
8516 patch_bc_statement (node)
8519 tree bc_label = EXIT_BLOCK_LABELED_BLOCK (node), target_stmt;
8520 int is_unlabeled = 0;
8521 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
8523 /* Not having a target means that the break/continue statement is
8524 unlabeled. We try to find a decent label for it */
8528 /* There should be a loop/switch to branch to */
8529 if (ctxp->current_loop)
8531 if (TREE_CODE (ctxp->current_loop) == LOOP_EXPR)
8533 /* At that stage, we're in the loop body, which is
8534 encapsulated around a LABELED_BLOCK_EXPR. So searching
8535 the current loop label requires us to consider the
8536 labeled block before the current one. */
8537 if (!LOOP_HAS_LABEL_SKIP_P (ctxp->current_loop))
8538 fatal ("unlabeled loop has no installed label -- "
8539 "patch_bc_statement");
8540 bc_label = TREE_CHAIN (ctxp->current_labeled_block);
8542 /* For a SWITCH statement, this is the current one */
8544 bc_label = ctxp->current_labeled_block;
8546 /* Not having a loop to break/continue to is an error */
8549 parse_error_context (wfl_operator, "`%s' must be in loop%s",
8550 (IS_BREAK_STMT_P (node) ? "break" : "continue"),
8551 (IS_BREAK_STMT_P (node) ? " or switch" : ""));
8552 return error_mark_node;
8555 /* Having an identifier here means that the target is unknown. */
8556 else if (TREE_CODE (bc_label) == IDENTIFIER_NODE)
8558 parse_error_context (wfl_operator, "No label definition found for `%s'",
8559 IDENTIFIER_POINTER (bc_label));
8560 return error_mark_node;
8563 /* Find the statement we're targeting. */
8564 target_stmt = LABELED_BLOCK_BODY (bc_label);
8566 /* 14.13 The break Statement */
8567 if (IS_BREAK_STMT_P (node))
8569 /* Named break are always fine, as far as they have a target
8570 (already verified). Anonymous break need to target
8571 while/do/for/switch */
8573 !(TREE_CODE (target_stmt) == LOOP_EXPR /* do/while/for */
8574 || TREE_CODE (target_stmt) == SWITCH_EXPR)) /* switch FIXME */
8576 parse_error_context (wfl_operator,
8577 "`break' must be in loop or switch");
8578 return error_mark_node;
8580 /* If previously unlabeled, install the new found label */
8582 EXIT_BLOCK_LABELED_BLOCK (node) = bc_label;
8584 /* 14.14 The continue Statement */
8585 /* The continue statement must always target a loop */
8588 if (TREE_CODE (target_stmt) != LOOP_EXPR) /* do/while/for */
8590 parse_error_context (wfl_operator, "`continue' must be in loop");
8591 return error_mark_node;
8593 /* Everything looks good. We can fix the `continue' jump to go
8594 at the place in the loop were the continue is. The continue
8595 is the current labeled block, by construction. */
8596 EXIT_BLOCK_LABELED_BLOCK (node) = ctxp->current_labeled_block;
8599 /* Our break/continue don't return values. */
8600 TREE_TYPE (node) = void_type_node;
8601 /* Encapsulate the break within a compound statement so that it's
8602 expanded all the times by expand_expr (and not clobered
8603 sometimes, like after a if statement) */
8604 node = add_stmt_to_compound (NULL_TREE, void_type_node, node);
8605 TREE_SIDE_EFFECTS (node) = 1;
8609 /* Process the exit expression belonging to a loop. Its type must be
8613 patch_exit_expr (node)
8616 tree expression = TREE_OPERAND (node, 0);
8617 TREE_TYPE (node) = error_mark_node;
8618 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
8620 /* The type of expression must be boolean */
8621 if (TREE_TYPE (expression) != boolean_type_node)
8625 "Incompatible type for loop conditional. Can't convert `%s' to "
8627 lang_printable_name (TREE_TYPE (expression), 0));
8628 return error_mark_node;
8630 /* Now we know things are allright, invert the condition, fold and
8632 TREE_OPERAND (node, 0) =
8633 fold (build1 (TRUTH_NOT_EXPR, boolean_type_node, expression));
8634 TREE_TYPE (node) = void_type_node;
8638 /* 14.9 Switch statement */
8641 patch_switch_statement (node)
8644 int error_found = 0;
8645 tree se = TREE_OPERAND (node, 0), se_type, sb;
8646 tree default_found = NULL_TREE;
8648 /* Complete the switch expression */
8649 se = TREE_OPERAND (node, 0) = java_complete_tree (se);
8650 se_type = TREE_TYPE (se);
8651 /* The type of the switch expression must be char, byte, short or
8653 if (!JINTEGRAL_TYPE_P (se_type))
8655 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
8656 parse_error_context (wfl_operator, "Incompatible type for `switch'. "
8657 "Can't convert `%s' to `int'",
8658 lang_printable_name (se_type, 0));
8659 /* This is what java_complete_tree will check */
8660 TREE_OPERAND (node, 0) = error_mark_node;
8661 return error_mark_node;
8664 /* Process the switch body. We should have a list of TREE_LIST. The
8665 PURPOSE of each node should be a list of case values, VALUE
8666 should be the associated block. We try to process all cases and
8667 defaults before returning, possibly finding errors. */
8668 TREE_OPERAND (node, 1) = nreverse (TREE_OPERAND (node, 1));
8669 for (sb = TREE_OPERAND (node, 1); sb; sb = TREE_CHAIN (sb))
8673 /* If we don't have a TREE_LIST here, we have a statement inside
8674 the switch that isn't tied to a label. This error is caught
8675 by the parser and we don't have to report it here. */
8677 TREE_PURPOSE (sb) = nreverse (TREE_PURPOSE (sb));
8678 for (label = TREE_PURPOSE (sb); label; label = TREE_CHAIN (label))
8682 /* Verification of the default label */
8683 if (TREE_CODE (label) == DEFAULT_EXPR)
8685 /* Only one default label is allowed per switch
8689 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (label);
8690 parse_error_context (wfl_operator,
8691 "Duplicate case label: `default'");
8695 default_found = label;
8698 /* Verification of case labels */
8701 case_expr = java_complete_tree (TREE_OPERAND (label, 0));
8702 if (case_expr == error_mark_node)
8705 /* First, the case expression must be constant */
8706 case_expr = fold (case_expr);
8707 if (!TREE_CONSTANT (case_expr))
8709 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (label);
8710 parse_error_context (label, "Constant expression required");
8715 /* It must be assignable to the type of the switch
8717 if (!try_builtin_assignconv (NULL_TREE, se_type, case_expr))
8719 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (label);
8722 "Incompatible type for case. Can't convert `%s' to `int'",
8723 lang_printable_name (TREE_TYPE (case_expr), 0));
8728 /* Multiple instance of a case label bearing the same
8729 value is checked during code generation. The case
8730 expression is allright so far. */
8731 TREE_OPERAND (label, 0) = case_expr;
8735 /* First TREE_VALUE should be the block tied to this list of
8736 cases. Check that this block exists and the walk it */
8737 if (TREE_VALUE (sb))
8739 TREE_VALUE (sb) = java_complete_tree (TREE_VALUE (sb));
8740 if (TREE_VALUE (sb) == error_mark_node)
8745 /* Ready to return */
8748 TREE_TYPE (node) = error_mark_node;
8749 return error_mark_node;
8751 TREE_TYPE (node) = void_type_node;
8752 TREE_SIDE_EFFECTS (node) = 1;
8756 /* Do the expansion of a Java switch. With Gcc, switches are front-end
8757 dependant things, but they rely on gcc routines. This function is
8758 placed here because it uses things defined locally in parse.y. */
8760 static tree case_identity (t, v)
8761 tree t __attribute__ ((__unused__));
8768 java_expand_switch (exp)
8772 expand_start_case (0, TREE_OPERAND (exp, 0), int_type_node, "switch");
8774 for (sb = TREE_OPERAND (exp, 1); sb; sb = TREE_CHAIN (sb))
8776 /* We have a list of TREE_LIST. PURPOSE is the case value, and
8777 when it exists, VALUE is the associated block */
8779 /* The first CASE element should contain the associated block,
8780 if any. All other should be case statements related to the
8783 for (label = TREE_PURPOSE (sb); label; label = TREE_CHAIN (label))
8785 tree label_decl = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
8786 if (TREE_CODE (label) == CASE_EXPR)
8789 if (pushcase (TREE_OPERAND (label, 0), case_identity,
8790 label_decl, &duplicate) == 2)
8792 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (label);
8794 (wfl_operator, "Duplicate case label: `%s'",
8795 print_int_node (TREE_OPERAND (label, 0)));
8799 pushcase (NULL_TREE, 0, label_decl, NULL);
8801 /* Expand the associated block, if any */
8802 if (TREE_VALUE (sb))
8803 expand_expr_stmt (TREE_VALUE (sb));
8805 expand_end_case (TREE_OPERAND (exp, 0));
8808 /* 14.18 The try statement */
8810 /* Wrap BLOCK around a LABELED_BLOCK, set DECL to the newly generated
8811 exit labeld and issue a jump to FINALLY_LABEL:
8822 build_jump_to_finally (block, decl, finally_label, type)
8823 tree block, decl, finally_label, type;
8826 tree new_block = build (LABELED_BLOCK_EXPR, type,
8827 create_label_decl (generate_name ()), block);
8829 stmt = build (MODIFY_EXPR, void_type_node, decl,
8830 build_address_of (LABELED_BLOCK_LABEL (new_block)));
8831 TREE_SIDE_EFFECTS (stmt) = 1;
8832 add_stmt_to_block (block, type, stmt);
8833 stmt = build (GOTO_EXPR, void_type_node, finally_label);
8834 TREE_SIDE_EFFECTS (stmt) = 1;
8835 add_stmt_to_block (block, type, stmt);
8840 build_try_statement (location, try_block, catches, finally)
8842 tree try_block, catches, finally;
8848 /* This block defines a scope for the entire try[-catch]-finally
8849 sequence. It hold a local variable used to return from the
8850 finally using a computed goto. We call it
8851 return_from_finally (RFF). */
8852 rff = build_decl_no_layout (VAR_DECL, generate_name (),
8853 return_address_type_node);
8855 /* Modification of the try block. */
8856 try_block = build_jump_to_finally (try_block, rff,
8857 FINALLY_EXPR_LABEL (finally),
8860 /* To the finally block: add the computed goto */
8861 add_stmt_to_block (FINALLY_EXPR_BLOCK (finally), NULL_TREE,
8862 build (GOTO_EXPR, void_type_node, rff));
8864 /* Modification of each catch blocks, if any */
8867 tree catch, catch_decl, catch_block, stmt;
8869 for (catch = catches; catch; catch = TREE_CHAIN (catch))
8870 TREE_OPERAND (catch, 0) =
8871 build_jump_to_finally (TREE_OPERAND (catch, 0), rff,
8872 FINALLY_EXPR_LABEL (finally),
8875 /* Plus, at the end of the list, we add the catch clause that
8876 will catch an uncaught exception, call finally and rethrow it:
8878 void *exception_parameter; (catch_decl)
8881 exception_parameter = _Jv_exception_info ();
8887 exception_parameter */
8888 catch_decl = build_decl_no_layout (VAR_DECL, generate_name (),
8890 BUILD_ASSIGN_EXCEPTION_INFO (stmt, catch_decl);
8891 catch_block = build_expr_block (stmt, NULL_TREE);
8892 catch_block = build_jump_to_finally (catch_block, rff,
8893 FINALLY_EXPR_LABEL (finally),
8895 BUILD_THROW (stmt, catch_decl);
8896 catch_block = build_expr_block (catch_block, catch_decl);
8897 add_stmt_to_block (catch_block, void_type_node, stmt);
8899 /* Link the new handler to the existing list as the first
8900 entry. It will be the last one to be generated. */
8901 catch = build1 (CATCH_EXPR, void_type_node, catch_block);
8902 TREE_CHAIN (catch) = catches;
8907 node = build (TRY_EXPR, NULL_TREE, try_block, catches, finally);
8908 EXPR_WFL_LINECOL (node) = location;
8910 /* If we have a finally, surround this whole thing by a block where
8911 the RFF local variable is defined. */
8913 return (finally ? build_expr_block (node, rff) : node);
8916 /* Get the catch clause block from an element of the catch clause
8917 list. If depends on whether a finally clause exists or node (in
8918 which case the original catch clause was surrounded by a
8919 LABELED_BLOCK_EXPR. */
8922 java_get_catch_block (node, finally_present_p)
8924 int finally_present_p;
8926 return (CATCH_EXPR_GET_EXPR (TREE_OPERAND (node, 0), finally_present_p));
8930 patch_try_statement (node)
8933 int error_found = 0;
8934 tree try = TREE_OPERAND (node, 0);
8935 /* Exception handlers are considered in left to right order */
8936 tree catch = nreverse (TREE_OPERAND (node, 1));
8937 tree finally = TREE_OPERAND (node, 2);
8938 int finally_p = (finally ? 1 : 0);
8939 tree current, caught_type_list = NULL_TREE;
8941 /* Check catch clauses, if any. Every time we find an error, we try
8942 to process the next catch clause. We process the catch clause before
8943 the try block so that when processing the try block we can check thrown
8944 exceptions againts the caught type list. */
8945 for (current = catch; current; current = TREE_CHAIN (current))
8947 tree carg_decl, carg_type;
8948 tree sub_current, catch_block, catch_clause;
8951 /* Always detect the last catch clause if a finally is
8952 present. This is the catch-all handler and it just needs to
8954 if (!TREE_CHAIN (current) && finally)
8956 TREE_OPERAND (current, 0) =
8957 java_complete_tree (TREE_OPERAND (current, 0));
8961 /* At this point, the structure of the catch clause is
8962 LABELED_BLOCK_EXPR (if we have a finally)
8963 CATCH_EXPR (catch node)
8964 BLOCK (with the decl of the parameter)
8966 MODIFIY_EXPR (assignemnt of the catch parameter)
8967 BLOCK (catch clause block)
8968 LABEL_DECL (where to return after finally (if any))
8970 Since the structure of the catch clause depends on the
8971 presence of a finally, we use a function call to get to the
8973 catch_clause = java_get_catch_block (current, finally_p);
8974 carg_decl = BLOCK_EXPR_DECLS (catch_clause);
8975 carg_type = TREE_TYPE (TREE_TYPE (carg_decl));
8977 /* Catch clauses can't have more than one parameter declared,
8978 but it's already enforced by the grammar. Make sure that the
8979 only parameter of the clause statement in of class Throwable
8980 or a subclass of Throwable, but that was done earlier. The
8981 catch clause parameter type has also been resolved. */
8983 /* Just make sure that the catch clause parameter type inherits
8984 from java.lang.Throwable */
8985 if (!inherits_from_p (carg_type, throwable_type_node))
8987 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
8988 parse_error_context (wfl_operator,
8989 "Can't catch class `%s'. Catch clause "
8990 "parameter type must be a subclass of "
8991 "class `java.lang.Throwable'",
8992 lang_printable_name (carg_type, 0));
8997 /* Partial check for unreachable catch statement: The catch
8998 clause is reachable iff is no earlier catch block A in
8999 the try statement such that the type of the catch
9000 clause's parameter is the same as or a subclass of the
9001 type of A's parameter */
9003 for (sub_current = catch;
9004 sub_current != current; sub_current = TREE_CHAIN (sub_current))
9006 tree sub_catch_clause, decl;
9007 sub_catch_clause = java_get_catch_block (sub_current, finally_p);
9008 decl = BLOCK_EXPR_DECLS (sub_catch_clause);
9010 if (inherits_from_p (carg_type, TREE_TYPE (TREE_TYPE (decl))))
9012 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
9014 (wfl_operator, "`catch' not reached because of the catch "
9015 "clause at line %d", EXPR_WFL_LINENO (sub_current));
9016 unreachable = error_found = 1;
9023 /* Things to do here: the exception must be thrown */
9025 /* Link this type to the caught type list */
9026 caught_type_list = tree_cons (NULL_TREE, carg_type, caught_type_list);
9028 /* Complete the catch clause block */
9029 catch_block = java_complete_tree (TREE_OPERAND (current, 0));
9030 if (catch_block == error_mark_node)
9035 TREE_OPERAND (current, 0) = catch_block;
9038 PUSH_EXCEPTIONS (caught_type_list);
9039 if ((try = java_complete_tree (try)) == error_mark_node)
9043 /* Process finally */
9046 FINALLY_EXPR_BLOCK (finally) =
9047 java_complete_tree (FINALLY_EXPR_BLOCK (finally));
9048 if (FINALLY_EXPR_BLOCK (finally) == error_mark_node)
9052 /* Verification ends here */
9054 return error_mark_node;
9056 TREE_OPERAND (node, 0) = try;
9057 TREE_OPERAND (node, 1) = catch;
9058 TREE_OPERAND (node, 2) = finally;
9059 TREE_TYPE (node) = void_type_node;
9063 /* 14.17 The synchronized Statement */
9066 patch_synchronized_statement (node, wfl_op1)
9069 tree expr = TREE_OPERAND (node, 0);
9070 tree block = TREE_OPERAND (node, 1);
9071 tree try_block, catch_all, stmt, compound, decl;
9073 /* The TYPE of expr must be a reference type */
9074 if (!JREFERENCE_TYPE_P (TREE_TYPE (TREE_OPERAND (node, 0))))
9076 SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
9077 parse_error_context (wfl_operator, "Incompatible type for `synchronized'"
9078 ". Can't convert `%s' to `java.lang.Object'",
9079 lang_printable_name (TREE_TYPE (expr), 0));
9080 return error_mark_node;
9083 /* Generate a try-finally for the synchronized statement, except
9084 that the handler that catches all throw exception calls
9085 _Jv_MonitorExit and then rethrow the exception.
9086 The synchronized statement is then implemented as:
9089 _Jv_MonitorEnter (expression)
9091 _Jv_MonitorExit (expression)
9095 e = _Jv_exception_info ();
9096 _Jv_MonitorExit (expression)
9101 BUILD_MONITOR_ENTER (stmt, expr);
9102 compound = add_stmt_to_compound (NULL_TREE, int_type_node, stmt);
9103 compound = add_stmt_to_compound (compound, void_type_node, block);
9104 BUILD_MONITOR_EXIT (stmt, expr);
9105 compound = add_stmt_to_compound (compound, int_type_node, stmt);
9106 try_block = build_expr_block (compound, NULL_TREE);
9108 /* CATCH_ALL block */
9109 decl = build_decl_no_layout (VAR_DECL, generate_name (), ptr_type_node);
9110 BUILD_ASSIGN_EXCEPTION_INFO (stmt, decl);
9111 compound = add_stmt_to_compound (NULL_TREE, void_type_node, stmt);
9112 BUILD_MONITOR_EXIT (stmt, expr);
9113 compound = add_stmt_to_compound (compound, int_type_node, stmt);
9114 BUILD_THROW (stmt, decl);
9115 compound = add_stmt_to_compound (compound, void_type_node, stmt);
9116 catch_all = build_expr_block (compound, decl);
9117 catch_all = build_expr_block (catch_all, NULL_TREE);
9118 catch_all = build1 (CATCH_EXPR, void_type_node, catch_all);
9120 /* TRY-CATCH statement */
9121 return build (TRY_EXPR, void_type_node, try_block, catch_all, NULL_TREE);
9124 /* 14.16 The throw Statement */
9127 patch_throw_statement (node, wfl_op1)
9130 tree expr = TREE_OPERAND (node, 0);
9131 tree type = TREE_TYPE (expr);
9132 int unchecked_ok = 0, tryblock_throws_ok = 0;
9134 /* Thrown expression must be assignable to java.lang.Throwable */
9135 if (!try_reference_assignconv (throwable_type_node, expr))
9137 SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
9138 parse_error_context (wfl_operator, "Can't throw `%s'; it must be a "
9139 "subclass of class `java.lang.Throwable'",
9140 lang_printable_name (type, 0));
9141 /* If the thrown expression was a reference, we further the
9142 compile-time check. */
9143 if (!JREFERENCE_TYPE_P (type))
9144 return error_mark_node;
9147 /* At least one of the following must be true */
9149 /* The type of the throw expression is a not checked exception,
9150 i.e. is a unchecked expression. */
9151 unchecked_ok = IS_UNCHECKED_EXPRESSION_P (TREE_TYPE (type));
9153 /* Throw is contained in a try statement and at least one catch
9154 clause can receive the thrown expression or the current method is
9155 declared to throw such an exception. Or, the throw statement is
9156 contained in a method or constructor declaration and the type of
9157 the Expression is assignable to at least one type listed in the
9158 throws clause the declaration. */
9159 SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
9161 tryblock_throws_ok =
9162 check_thrown_exceptions_do (TREE_TYPE (expr));
9163 if (!(unchecked_ok || tryblock_throws_ok))
9165 /* If there is a surrounding try block that has no matching
9166 clatch clause, report it first. A surrounding try block exits
9167 only if there is something after the list of checked
9168 exception thrown by the current function (if any). */
9169 if (IN_TRY_BLOCK_P ())
9170 parse_error_context (wfl_operator, "Checked exception `%s' can't be "
9171 "caught by any of the catch clause(s) "
9172 "of the surrounding `try' block",
9173 lang_printable_name (type, 0));
9174 /* If we have no surrounding try statement and the method doesn't have
9175 any throws, report it now. FIXME */
9176 else if (!EXCEPTIONS_P (currently_caught_type_list)
9177 && !tryblock_throws_ok)
9178 parse_error_context (wfl_operator, "Checked exception `%s' isn't "
9179 "thrown from a `try' block",
9180 lang_printable_name (type, 0));
9181 /* Otherwise, the current method doesn't have the appropriate
9182 throws declaration */
9184 parse_error_context (wfl_operator, "Checked exception `%s' doesn't "
9185 "match any of current method's `throws' "
9187 lang_printable_name (type, 0));
9188 return error_mark_node;
9191 /* If a throw statement is contained in a static initializer, then a
9192 compile-time check ensures that either its value is always an
9193 unchecked exception or its value is always caught by some try
9194 statement that contains it. FIXME, static initializer. */
9196 BUILD_THROW (node, expr);
9200 /* Check that exception said to be thrown by method DECL can be
9201 effectively caught from where DECL is invoked. */
9204 check_thrown_exceptions (location, decl)
9209 /* For all the unchecked exceptions thrown by DECL */
9210 for (throws = DECL_FUNCTION_THROWS (decl); throws;
9211 throws = TREE_CHAIN (throws))
9212 if (!check_thrown_exceptions_do (TREE_VALUE (throws)))
9214 EXPR_WFL_LINECOL (wfl_operator) = location;
9216 (wfl_operator, "Exception `%s' must be caught, or it must be "
9217 "declared in the `throws' clause of `%s'",
9218 lang_printable_name (TREE_VALUE (throws), 0),
9219 IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
9223 /* Return 1 if EXCEPTION is caught at the current nesting level of
9224 try-catch blocks, OR is listed in the `throws' clause of the
9228 check_thrown_exceptions_do (exception)
9231 tree list = currently_caught_type_list;
9232 /* First, all the nested try-catch-finally at that stage. The
9233 last element contains `throws' clause exceptions, if any. */
9237 for (caught = TREE_VALUE (list); caught; caught = TREE_CHAIN (caught))
9238 if (valid_ref_assignconv_cast_p (exception, TREE_VALUE (caught), 0))
9240 list = TREE_CHAIN (list);
9246 purge_unchecked_exceptions (mdecl)
9249 tree throws = DECL_FUNCTION_THROWS (mdecl);
9250 tree new = NULL_TREE;
9254 tree next = TREE_CHAIN (throws);
9255 if (!IS_UNCHECKED_EXPRESSION_P (TREE_VALUE (throws)))
9257 TREE_CHAIN (throws) = new;
9262 /* List is inverted here, but it doesn't matter */
9263 DECL_FUNCTION_THROWS (mdecl) = new;