aboutsummaryrefslogtreecommitdiff
path: root/gcc/java/decl.c
diff options
context:
space:
mode:
authorAlexandre Petit-Bianco <apbianco@cygnus.com>2000-10-10 17:54:59 +0000
committerAlexandre Petit-Bianco <apbianco@cygnus.com>2000-10-10 17:54:59 +0000
commit88209d698b030125297d8f300d1755336beec719 (patch)
tree29e47287ccecef100ce0b62cbd6d9692d2e0680c /gcc/java/decl.c
parentef50b7cf0c5069fb02fd268d7c40a7b26eae07bc (diff)
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-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. (http://gcc.gnu.org/ml/gcc-patches/2000-10/msg00286.html) git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@36827 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/java/decl.c')
-rw-r--r--gcc/java/decl.c99
1 files changed, 81 insertions, 18 deletions
diff --git a/gcc/java/decl.c b/gcc/java/decl.c
index 8dd349ff8c7..dd36ff02674 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));
}