aboutsummaryrefslogtreecommitdiff
path: root/gcc/java
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/java')
-rw-r--r--gcc/java/ChangeLog14
-rw-r--r--gcc/java/decl.c99
-rw-r--r--gcc/java/parse.y25
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);
}
;