diff options
Diffstat (limited to 'gcc/java')
-rw-r--r-- | gcc/java/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/java/decl.c | 99 | ||||
-rw-r--r-- | gcc/java/parse.y | 25 |
3 files changed, 109 insertions, 29 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index a1ef24f..b63d751 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,10 @@ +2000-10-07 Alexandre Petit-Bianco <apbianco@cygnus.com> + + Patch contributed by Corey Minyard. + * decl.c (check_local_named_variable): New function. + (tree check_local_unnamed_variable): Likewise. + (find_local_variable): Splitted. Call check_local_{un}named_variable. + 2000-10-07 Anthony Green <green@redhat.com> * class.c (layout_class): Handle case where superclass can't be @@ -250,6 +257,13 @@ Wed Sep 13 11:50:35 2000 Alexandre Petit-Bianco <apbianco@cygnus.com> 2000-08-11 Alexandre Petit-Bianco <apbianco@cygnus.com> + * parse.y (variable_declarator_id:): Better error message. + (expression_statement:): Use YYNOT_TWICE. + (cast_expression:): Likewise. + (assignment:): Likewise. + +2000-08-11 Alexandre Petit-Bianco <apbianco@cygnus.com> + * parse.y (do_merge_string_cste): New locals. Create new STRING_CSTs each time, use memcpy. Fixes gcj/311. diff --git a/gcc/java/decl.c b/gcc/java/decl.c index 8dd349f..dd36ff0 100644 --- a/gcc/java/decl.c +++ b/gcc/java/decl.c @@ -50,6 +50,8 @@ static struct binding_level *make_binding_level PARAMS ((void)); static boolean emit_init_test_initialization PARAMS ((struct hash_entry *, hash_table_key)); static tree create_primitive_vtable PARAMS ((const char *)); +static tree check_local_named_variable PARAMS ((tree, tree, int, int *)); +static tree check_local_unnamed_variable PARAMS ((tree, tree, tree)); /* Set to non-zero value in order to emit class initilization code before static field references. */ @@ -140,6 +142,58 @@ push_jvm_slot (index, decl) return decl; } +/* Find out if 'decl' passed in fits the defined PC location better than + 'best'. Return decl if it does, return best if it doesn't. If decl + is returned, then updated is set to true. */ + +static tree +check_local_named_variable (best, decl, pc, updated) + tree best; + tree decl; + int pc; + int *updated; +{ + if (pc >= DECL_LOCAL_START_PC (decl) + && pc < DECL_LOCAL_END_PC (decl)) + { + if (best == NULL_TREE + || (DECL_LOCAL_START_PC (decl) > DECL_LOCAL_START_PC (best) + && DECL_LOCAL_END_PC (decl) < DECL_LOCAL_END_PC (best))) + { + *updated = 1; + return decl; + } + } + + return best; +} + +/* Find the best declaration based upon type. If 'decl' fits 'type' better + than 'best', return 'decl'. Otherwise return 'best'. */ + +static tree +check_local_unnamed_variable (best, decl, type) + tree best; + tree decl; + tree type; +{ + if (TREE_TYPE (decl) == type + || (TREE_CODE (TREE_TYPE (decl)) == TREE_CODE (type) + && TYPE_PRECISION (TREE_TYPE (decl)) <= 32 + && TYPE_PRECISION (type) <= 32 + && TREE_CODE (type) != POINTER_TYPE) + || (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE + && type == ptr_type_node)) + { + if (best == NULL_TREE + || (TREE_TYPE (decl) == type && TREE_TYPE (best) != type)) + return decl; + } + + return best; +} + + /* Find a VAR_DECL (or PARM_DECL) at local index INDEX that has type TYPE, that is valid at PC (or -1 if any pc). If there is no existing matching decl, allocate one. */ @@ -152,32 +206,41 @@ find_local_variable (index, type, pc) { tree decl = TREE_VEC_ELT (decl_map, index); tree best = NULL_TREE; + int found_scoped_var = 0; + /* Scan through every declaration that has been created in this slot. */ while (decl != NULL_TREE) { - int in_range; - in_range = pc < 0 - || (pc >= DECL_LOCAL_START_PC (decl) - && pc < DECL_LOCAL_END_PC (decl)); - - if ((TREE_TYPE (decl) == type - || (TREE_CODE (TREE_TYPE (decl)) == TREE_CODE (type) - && TYPE_PRECISION (TREE_TYPE (decl)) <= 32 - && TYPE_PRECISION (type) <= 32 - && TREE_CODE (type) != POINTER_TYPE) - || (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE - && type == ptr_type_node)) - && in_range) + /* Variables created in give_name_to_locals() have a name and have + a specified scope, so we can handle them specifically. We want + to use the specific decls created for those so they are assigned + the right variables in the debugging information. */ + if (DECL_NAME (decl) != NULL_TREE) { - if (best == NULL_TREE - || (DECL_LOCAL_START_PC (decl) > DECL_LOCAL_START_PC (best) - && DECL_LOCAL_END_PC (decl) < DECL_LOCAL_START_PC (best))) - best = decl; - } + /* This is a variable we have a name for, so it has a scope + supplied in the class file. But it only matters when we + actually have a PC to use. If pc<0, then we are asking + for a stack slot and this decl won't be one of those. */ + if (pc >= 0) + best = check_local_named_variable (best, decl, pc, + &found_scoped_var); + } + /* We scan for type information unless we found a variable in the + proper scope already. */ + else if (!found_scoped_var) + { + /* If we don't have scoping information for a variable, we use + a different method to look it up. */ + best = check_local_unnamed_variable (best, decl, type); + } + decl = DECL_LOCAL_SLOT_CHAIN (decl); } + if (best != NULL_TREE) return best; + + /* If we don't find a match, create one with the type passed in. */ return push_jvm_slot (index, build_decl (VAR_DECL, NULL_TREE, type)); } diff --git a/gcc/java/parse.y b/gcc/java/parse.y index 5db2edc..e66d2f5 100644 --- a/gcc/java/parse.y +++ b/gcc/java/parse.y @@ -971,7 +971,15 @@ variable_declarator_id: | identifier error {yyerror ("Invalid declaration"); DRECOVER(vdi);} | variable_declarator_id OSB_TK error - {yyerror ("']' expected"); DRECOVER(vdi);} + { + tree node = java_lval.node; + if (node && (TREE_CODE (node) == INTEGER_CST + || TREE_CODE (node) == EXPR_WITH_FILE_LOCATION)) + yyerror ("Can't specify array dimension in a declaration"); + else + yyerror ("']' expected"); + DRECOVER(vdi); + } | variable_declarator_id CSB_TK error {yyerror ("Unbalanced ']'"); DRECOVER(vdi);} ; @@ -1465,20 +1473,17 @@ expression_statement: } | error SC_TK { - if (ctxp->prevent_ese != lineno) - yyerror ("Invalid expression statement"); + YYNOT_TWICE yyerror ("Invalid expression statement"); DRECOVER (expr_stmt); } | error OCB_TK { - if (ctxp->prevent_ese != lineno) - yyerror ("Invalid expression statement"); + YYNOT_TWICE yyerror ("Invalid expression statement"); DRECOVER (expr_stmt); } | error CCB_TK { - if (ctxp->prevent_ese != lineno) - yyerror ("Invalid expression statement"); + YYNOT_TWICE yyerror ("Invalid expression statement"); DRECOVER (expr_stmt); } | this_or_super OP_TK error @@ -2342,8 +2347,7 @@ cast_expression: /* Error handling here is potentially weak */ {yyerror ("']' expected, invalid type expression");} | OP_TK error { - if (ctxp->prevent_ese != lineno) - yyerror ("Invalid type expression"); RECOVER; + YYNOT_TWICE yyerror ("Invalid type expression"); RECOVER; RECOVER; } | OP_TK primitive_type dims CP_TK error @@ -2560,8 +2564,7 @@ assignment: { $$ = build_assignment ($2.token, $2.location, $1, $3); } | left_hand_side assignment_operator error { - if (ctxp->prevent_ese != lineno) - yyerror ("Missing term"); + YYNOT_TWICE yyerror ("Missing term"); DRECOVER (assign); } ; |