Commit 00150bf9 by Andrew Haley Committed by Andrew Haley

verify.c (verify_jvm_instructions): Comment change only.

2004-07-20  Andrew Haley  <aph@redhat.com>

	* verify.c (verify_jvm_instructions): Comment change only.

	* typeck.c (build_java_array_type): Add size field to array name.

	* java-tree.h (LOCAL_SLOT_P): New.
	(update_aliases): Add PC argument.
	(pushdecl_function_level): New function.

	* java-gimplify.c (java_gimplify_expr): Handle VAR_DECL,
	MODIFY_EXPR, and SAVE_EXPR.
	(java_gimplify_modify_expr): New function.

	* expr.c (push_type_0): Call find_stack_slot() to create temporary.
	(expand_iinc): Pass PC to update_aliases().
	(STORE_INTERNAL): Likewise.
	(process_jvm_instruction): Likewise.

	* decl.c (base_decl_map): New variable.
	(uniq): New variable.
	(update_aliases): Rewrite with more thorough checking.
	(debug_variable_p): New function.
	(push_jvm_slot): Don't initialize local variable.  Don't pushdecl.
	(check_local_named_variable): Delete whole function.
	(initialize_local_variable): New function.
	(check_local_unnamed_variable): Add checks and comments.
	(find_local_variable): Rewrite.
	(java_replace_reference): New function.
	(function_binding_level): New variable.
	(pushdecl_function_level): New function.
	(maybe_pushlevels): Set DECL_LOCAL_END_PC.
	(maybe_pushlevels): Call pushdecl() on each of the new decls.
	(start_java_method): Reset uniq.  Create base_decl_map.  Set
	function_binding_level.
	(end_java_method): Null unused fields to save memory.

From-SVN: r85009
parent 5d16533a
2004-07-20 Andrew Haley <aph@redhat.com>
* verify.c (verify_jvm_instructions): Comment change only.
* typeck.c (build_java_array_type): Add size field to array name.
* java-tree.h (LOCAL_SLOT_P): New.
(update_aliases): Add PC argument.
(pushdecl_function_level): New function.
* java-gimplify.c (java_gimplify_expr): Handle VAR_DECL,
MODIFY_EXPR, and SAVE_EXPR.
(java_gimplify_modify_expr): New function.
* expr.c (push_type_0): Call find_stack_slot() to create temporary.
(expand_iinc): Pass PC to update_aliases().
(STORE_INTERNAL): Likewise.
(process_jvm_instruction): Likewise.
* decl.c (base_decl_map): New variable.
(uniq): New variable.
(update_aliases): Rewrite with more thorough checking.
(debug_variable_p): New function.
(push_jvm_slot): Don't initialize local variable. Don't pushdecl.
(check_local_named_variable): Delete whole function.
(initialize_local_variable): New function.
(check_local_unnamed_variable): Add checks and comments.
(find_local_variable): Rewrite.
(java_replace_reference): New function.
(function_binding_level): New variable.
(pushdecl_function_level): New function.
(maybe_pushlevels): Set DECL_LOCAL_END_PC.
(maybe_pushlevels): Call pushdecl() on each of the new decls.
(start_java_method): Reset uniq. Create base_decl_map. Set
function_binding_level.
(end_java_method): Null unused fields to save memory.
2004-07-20 Nathan Sidwell <nathan@codesourcery.com>
* class.c (add_interface_do): Remove.
......
......@@ -57,7 +57,6 @@ static tree lookup_name_current_level (tree);
static tree push_promoted_type (const char *, tree);
static struct binding_level *make_binding_level (void);
static tree create_primitive_vtable (const char *);
static tree check_local_named_variable (tree, tree, int, int *);
static tree check_local_unnamed_variable (tree, tree, tree);
/* Name of the Cloneable class. */
......@@ -76,14 +75,20 @@ tree java_io_serializable_identifier_node;
static GTY(()) tree decl_map;
/* The base_decl_map is contains one variable of ptr_type: this is
used to contain every variable of reference type that is ever
stored in a local variable slot. */
static GTY(()) tree base_decl_map;
/* An index used to make temporary identifiers unique. */
static int uniq;
/* A list of local variables VAR_DECLs for this method that we have seen
debug information, but we have not reached their starting (byte) PC yet. */
static GTY(()) tree pending_local_decls;
/* Push a local variable or stack slot into the decl_map,
and assign it an rtl. */
#if defined(DEBUG_JAVA_BINDING_LEVELS)
int binding_depth = 0;
int is_class_level = 0;
......@@ -99,51 +104,67 @@ indent (void)
}
#endif /* defined(DEBUG_JAVA_BINDING_LEVELS) */
/* Copy the value in decl into every alias in the same local variable
slot. */
/* True if decl is a named local variable, i.e. if it is an alias
that's used only for debugging purposes. */
static bool
debug_variable_p (tree decl)
{
if (TREE_CODE (decl) == PARM_DECL)
return false;
if (LOCAL_SLOT_P (decl))
return false;
return true;
}
/* Copy the value in decl into every live alias in the same local
variable slot. Some of these will be dead stores removed by the
optimizer. */
void
update_aliases (tree decl, int index)
update_aliases (tree decl, int index, int pc)
{
tree tmp = TREE_VEC_ELT (decl_map, index);
tree type = TREE_TYPE (decl);
while (tmp != NULL_TREE)
tree decl_type = TREE_TYPE (decl);
tree tmp;
if (debug_variable_p (decl))
abort ();
for (tmp = TREE_VEC_ELT (decl_map, index);
tmp != NULL_TREE;
tmp = DECL_LOCAL_SLOT_CHAIN (tmp))
{
tree tmp_type = TREE_TYPE (tmp);
if (tmp != decl
&& ! LOCAL_VAR_OUT_OF_SCOPE_P (tmp)
&& TYPE_MODE (type) == TYPE_MODE (TREE_TYPE (tmp)))
&& LOCAL_SLOT_P (tmp) == 0
&& (pc == -1
|| (pc >= DECL_LOCAL_START_PC (tmp)
&& pc <= DECL_LOCAL_END_PC (tmp)))
&& (tmp_type == decl_type
|| (INTEGRAL_TYPE_P (tmp_type)
&& INTEGRAL_TYPE_P (decl_type)
&& TYPE_PRECISION (decl_type) <= 32
&& TYPE_PRECISION (tmp_type) <= 32)
|| (TREE_CODE (tmp_type) == POINTER_TYPE
&& TREE_CODE (decl_type) == POINTER_TYPE)))
{
tree src = build1 (NOP_EXPR, TREE_TYPE (tmp), decl);
java_add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (tmp), tmp, src));
tree src = build1 (NOP_EXPR, tmp_type, decl);
if (LOCAL_VAR_OUT_OF_SCOPE_P (tmp))
abort ();
java_add_stmt
(build (MODIFY_EXPR, tmp_type, tmp, src));
}
tmp = DECL_LOCAL_SLOT_CHAIN (tmp);
}
}
static tree
push_jvm_slot (int index, tree decl)
{
tree type = TREE_TYPE (decl);
tree tmp;
DECL_CONTEXT (decl) = current_function_decl;
layout_decl (decl, 0);
/* Look for another variable of the same mode in this slot. */
tmp = TREE_VEC_ELT (decl_map, index);
while (tmp != NULL_TREE)
{
if (! LOCAL_VAR_OUT_OF_SCOPE_P (tmp)
&& TYPE_MODE (type) == TYPE_MODE (TREE_TYPE (tmp)))
{
/* At the point of its creation this decl inherits whatever
is in the slot. */
tree src = build1 (NOP_EXPR, TREE_TYPE (decl), tmp);
java_add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (decl), decl, src));
break;
}
tmp = DECL_LOCAL_SLOT_CHAIN (tmp);
}
/* Now link the decl into the decl_map. */
if (DECL_LANG_SPECIFIC (decl) == NULL)
{
......@@ -155,31 +176,54 @@ push_jvm_slot (int index, tree decl)
DECL_LOCAL_SLOT_CHAIN (decl) = TREE_VEC_ELT (decl_map, index);
TREE_VEC_ELT (decl_map, index) = decl;
if (TREE_CODE (decl) != PARM_DECL)
pushdecl (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. */
/* At the point of its creation a local variable decl inherits
whatever is already in the same slot. In the case of a local
variable that is declared but unused, we won't find anything. */
static tree
check_local_named_variable (tree best, tree decl, int pc, int *updated)
static void
initialize_local_variable (tree decl, int index)
{
if (pc >= DECL_LOCAL_START_PC (decl)
&& pc < DECL_LOCAL_END_PC (decl))
tree decl_type = TREE_TYPE (decl);
if (TREE_CODE (decl_type) == POINTER_TYPE)
{
if (best == NULL_TREE
|| (DECL_LOCAL_START_PC (decl) > DECL_LOCAL_START_PC (best)
&& DECL_LOCAL_END_PC (decl) < DECL_LOCAL_END_PC (best)))
tree tmp = TREE_VEC_ELT (base_decl_map, index);
if (tmp)
{
*updated = 1;
return decl;
/* At the point of its creation this decl inherits whatever
is in the slot. */
tree src = build1 (NOP_EXPR, decl_type, tmp);
java_add_stmt
(build (MODIFY_EXPR, decl_type, decl, src));
}
}
else
{
tree tmp;
return best;
for (tmp = TREE_VEC_ELT (decl_map, index);
tmp != NULL_TREE;
tmp = DECL_LOCAL_SLOT_CHAIN (tmp))
{
tree tmp_type = TREE_TYPE (tmp);
if (tmp != decl
&& ! debug_variable_p (tmp)
&& (tmp_type == decl_type
|| (INTEGRAL_TYPE_P (tmp_type)
&& INTEGRAL_TYPE_P (decl_type)
&& TYPE_PRECISION (decl_type) <= 32
&& TYPE_PRECISION (tmp_type) <= 32
&& TYPE_PRECISION (tmp_type) >= TYPE_PRECISION (decl_type))))
{
java_add_stmt
(build (MODIFY_EXPR, decl_type, decl, tmp));
return;
}
}
}
}
/* Find the best declaration based upon type. If 'decl' fits 'type' better
......@@ -188,16 +232,25 @@ check_local_named_variable (tree best, tree decl, int pc, int *updated)
static tree
check_local_unnamed_variable (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
tree decl_type = TREE_TYPE (decl);
if (LOCAL_VAR_OUT_OF_SCOPE_P (decl))
abort ();
/* Use the same decl for all integer types <= 32 bits. This is
necessary because sometimes a value is stored as (for example)
boolean but loaded as int. */
if (decl_type == type
|| (INTEGRAL_TYPE_P (decl_type)
&& INTEGRAL_TYPE_P (type)
&& TYPE_PRECISION (decl_type) <= 32
&& TYPE_PRECISION (type) <= 32
&& TREE_CODE (type) != POINTER_TYPE)
&& TYPE_PRECISION (decl_type) >= TYPE_PRECISION (type))
|| (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
&& type == ptr_type_node))
{
if (best == NULL_TREE
|| (TREE_TYPE (decl) == type && TREE_TYPE (best) != type))
|| (decl_type == type && TREE_TYPE (best) != type))
return decl;
}
......@@ -210,63 +263,103 @@ check_local_unnamed_variable (tree best, tree decl, tree type)
If there is no existing matching decl, allocate one. */
tree
find_local_variable (int index, tree type, int pc)
find_local_variable (int index, tree type, int pc ATTRIBUTE_UNUSED)
{
tree decl = TREE_VEC_ELT (decl_map, index);
tree best = NULL_TREE;
int found_scoped_var = 0;
tree tmp = TREE_VEC_ELT (decl_map, index);
tree decl = NULL_TREE;
/* Scan through every declaration that has been created in this slot. */
while (decl != NULL_TREE)
{
bool has_name = false;
tree name = DECL_NAME (decl);
if (name && IDENTIFIER_POINTER (name))
has_name = IDENTIFIER_POINTER (name)[0] != '#';
/* 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 (has_name)
{
/* 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)
/* Scan through every declaration that has been created in this
slot. We're only looking for variables that correspond to local
index declarations and PARM_DECLs, not named variables: such
local variables are used only for debugging information. */
while (tmp != NULL_TREE)
{
/* 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 (! debug_variable_p (tmp))
decl = check_local_unnamed_variable (decl, tmp, type);
tmp = DECL_LOCAL_SLOT_CHAIN (tmp);
}
if (best != NULL_TREE)
return best;
/* If we don't find a match, create one with the type passed in.
Ths name of the variable is #n#m, which n is the variable index
The name of the variable is #n#m, which n is the variable index
in the local variable area and m is a dummy identifier for
uniqueness -- multiple variables may share the same local
variable index. */
variable index. We don't call pushdecl() to push pointer types
into a binding expr because they'll all be replaced by a single
variable that is used for every reference in that local variable
slot. */
if (! decl)
{
char buf[64];
tree name;
static int uniq;
sprintf (buf, "#%d#%d", index, uniq++);
sprintf (buf, "#slot#%d#%d", index, uniq++);
name = get_identifier (buf);
decl = build_decl (VAR_DECL, name, type);
DECL_IGNORED_P (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
decl = push_jvm_slot (index, decl);
LOCAL_SLOT_P (decl) = 1;
if (TREE_CODE (type) != POINTER_TYPE)
pushdecl_function_level (decl);
}
/* As well as creating a local variable that matches the type, we
also create a base variable (of ptr_type) that will hold all its
aliases. */
if (TREE_CODE (type) == POINTER_TYPE
&& ! TREE_VEC_ELT (base_decl_map, index))
{
char buf[64];
tree name;
tree base_decl;
sprintf (buf, "#ref#%d#%d", index, uniq++);
name = get_identifier (buf);
base_decl
= TREE_VEC_ELT (base_decl_map, index)
= build_decl (VAR_DECL, name, ptr_type_node);
pushdecl_function_level (base_decl);
DECL_IGNORED_P (base_decl) = 1;
DECL_ARTIFICIAL (base_decl) = 1;
}
return decl;
}
/* Called during gimplification for every variable. If the variable
is a temporary of pointer type, replace it with a common variable
thath is used to hold all pointer types that are ever stored in
that slot. Set WANT_LVALUE if you want a variable that is to be
written to. */
tree
java_replace_reference (tree var_decl, bool want_lvalue)
{
tree decl_type;
if (! base_decl_map)
return var_decl;
decl_type = TREE_TYPE (var_decl);
if (TREE_CODE (decl_type) == POINTER_TYPE)
{
if (DECL_LANG_SPECIFIC (var_decl)
&& LOCAL_SLOT_P (var_decl))
{
int index = DECL_LOCAL_SLOT_NUMBER (var_decl);
tree base_decl = TREE_VEC_ELT (base_decl_map, index);
if (! base_decl)
abort ();
if (! want_lvalue)
base_decl = build1 (NOP_EXPR, decl_type, base_decl);
return push_jvm_slot (index, build_decl (VAR_DECL, name, type));
return base_decl;
}
}
return var_decl;
}
......@@ -331,6 +424,11 @@ static GTY(()) struct binding_level *free_binding_level;
static GTY(()) struct binding_level *global_binding_level;
/* The binding level that holds variables declared at the outermost
level within a function body. */
static struct binding_level *function_binding_level;
/* A PC value bigger than any PC value we may ever may encounter. */
#define LARGEST_PC (( (unsigned int)1 << (HOST_BITS_PER_INT - 1)) - 1)
......@@ -1174,6 +1272,20 @@ pushdecl_top_level (tree x)
return t;
}
/* Like pushdecl, only it places X in FUNCTION_BINDING_LEVEL, if appropriate. */
tree
pushdecl_function_level (tree x)
{
tree t;
struct binding_level *b = current_binding_level;
current_binding_level = function_binding_level;
t = pushdecl (x);
current_binding_level = b;
return t;
}
/* Nonzero if we are currently in the global binding level. */
int
......@@ -1497,9 +1609,13 @@ maybe_pushlevels (int pc)
pending_local_decls = *ptr;
*ptr = NULL_TREE;
/* Force non-nested range to be nested in current range. */
/* Force non-nested range to be nested in current range by
truncating variable lifetimes. */
if (end_pc > current_binding_level->end_pc)
{
end_pc = current_binding_level->end_pc;
DECL_LOCAL_END_PC (decl) = end_pc;
}
maybe_start_try (pc, end_pc);
......@@ -1512,6 +1628,8 @@ maybe_pushlevels (int pc)
{
next = TREE_CHAIN (decl);
push_jvm_slot (DECL_LOCAL_SLOT_NUMBER (decl), decl);
pushdecl (decl);
initialize_local_variable (decl, DECL_LOCAL_SLOT_NUMBER (decl));
}
}
......@@ -1698,11 +1816,14 @@ start_java_method (tree fndecl)
tree tem, *ptr;
int i;
uniq = 0;
current_function_decl = fndecl;
announce_function (fndecl);
i = DECL_MAX_LOCALS(fndecl) + DECL_MAX_STACK(fndecl);
decl_map = make_tree_vec (i);
base_decl_map = make_tree_vec (i);
type_map = xrealloc (type_map, i * sizeof (tree));
#if defined(DEBUG_JAVA_BINDING_LEVELS)
......@@ -1751,6 +1872,8 @@ start_java_method (tree fndecl)
/* Push local variables. */
pushlevel (2);
function_binding_level = current_binding_level;
}
void
......@@ -1777,6 +1900,14 @@ end_java_method (void)
DECL_STRUCT_FUNCTION (fndecl) = NULL;
DECL_INITIAL (fndecl) = NULL_TREE;
}
if (! flag_unit_at_a_time)
{
/* Nulling these fields when we no longer need them saves
memory. */
DECL_SAVED_TREE (fndecl) = NULL;
DECL_STRUCT_FUNCTION (fndecl) = NULL;
DECL_INITIAL (fndecl) = NULL_TREE;
}
current_function_decl = NULL_TREE;
}
......
......@@ -255,6 +255,9 @@ push_type_0 (tree type)
n_words = 1 + TYPE_IS_WIDE (type);
if (stack_pointer + n_words > DECL_MAX_STACK (current_function_decl))
return 0;
/* Allocate decl for this variable now, so we get a temporary that
survives the whole method. */
find_stack_slot (stack_pointer, type);
stack_type_map[stack_pointer++] = type;
n_words--;
while (--n_words >= 0)
......@@ -368,7 +371,7 @@ pop_type (tree type)
return type;
}
/* Return 1f if SOURCE_TYPE can be safely widened to TARGET_TYPE.
/* Return 1 if SOURCE_TYPE can be safely widened to TARGET_TYPE.
Handles array types and interfaces. */
int
......@@ -1289,7 +1292,7 @@ expand_iinc (unsigned int local_var_index, int ival, int pc)
constant_value = build_int_2 (ival, ival < 0 ? -1 : 0);
res = fold (build2 (PLUS_EXPR, int_type_node, local_var, constant_value));
java_add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (local_var), local_var, res));
update_aliases (local_var, local_var_index);
update_aliases (local_var, local_var_index, pc);
}
......@@ -2758,7 +2761,8 @@ process_jvm_instruction (int PC, const unsigned char* byte_ops,
{ \
int saw_index = 0; \
int index = OPERAND_VALUE; \
build_java_ret (find_local_variable (index, ptr_type_node, oldpc)); \
build_java_ret \
(find_local_variable (index, return_address_type_node, oldpc)); \
}
#define JSR(OPERAND_TYPE, OPERAND_VALUE) \
......@@ -2937,7 +2941,7 @@ process_jvm_instruction (int PC, const unsigned char* byte_ops,
decl = find_local_variable (index, type, oldpc); \
set_local_type (index, type); \
java_add_stmt (build2 (MODIFY_EXPR, type, decl, value)); \
update_aliases (decl, index); \
update_aliases (decl, index, PC); \
}
#define STORE(OPERAND_TYPE, OPERAND_VALUE) \
......
......@@ -37,6 +37,7 @@ static tree java_gimplify_default_expr (tree);
static tree java_gimplify_block (tree);
static tree java_gimplify_new_array_init (tree);
static tree java_gimplify_try_expr (tree);
static tree java_gimplify_modify_expr (tree);
static void dump_java_tree (enum tree_dump_index, tree);
......@@ -117,6 +118,21 @@ java_gimplify_expr (tree *expr_p, tree *pre_p ATTRIBUTE_UNUSED,
*expr_p = build_exception_object_ref (TREE_TYPE (*expr_p));
break;
case VAR_DECL:
*expr_p = java_replace_reference (*expr_p, /* want_lvalue */ false);
return GS_UNHANDLED;
case MODIFY_EXPR:
*expr_p = java_gimplify_modify_expr (*expr_p);
return GS_UNHANDLED;
case SAVE_EXPR:
if (TREE_CODE (TREE_OPERAND (*expr_p, 0)) == VAR_DECL)
TREE_OPERAND (*expr_p, 0)
= java_replace_reference (TREE_OPERAND (*expr_p, 0),
/* want_lvalue */ false);
return GS_UNHANDLED;
/* These should already be lowered before we get here. */
case URSHIFT_EXPR:
case COMPARE_EXPR:
......@@ -140,6 +156,33 @@ java_gimplify_expr (tree *expr_p, tree *pre_p ATTRIBUTE_UNUSED,
return GS_OK;
}
/* This is specific to the bytecode compiler. If a variable has
LOCAL_SLOT_P set, replace an assignment to it with an assignment to
the corresponding variable that holds all its aliases. */
static tree
java_gimplify_modify_expr (tree modify_expr)
{
tree lhs = TREE_OPERAND (modify_expr, 0);
tree rhs = TREE_OPERAND (modify_expr, 1);
tree lhs_type = TREE_TYPE (lhs);
if (TREE_CODE (lhs) == VAR_DECL
&& DECL_LANG_SPECIFIC (lhs)
&& LOCAL_SLOT_P (lhs)
&& TREE_CODE (lhs_type) == POINTER_TYPE)
{
tree new_lhs = java_replace_reference (lhs, /* want_lvalue */ true);
tree new_rhs = build1 (NOP_EXPR, TREE_TYPE (new_lhs), rhs);
modify_expr = build (MODIFY_EXPR, TREE_TYPE (new_lhs),
new_lhs, new_rhs);
modify_expr = build1 (NOP_EXPR, lhs_type, modify_expr);
}
return modify_expr;
}
static tree
java_gimplify_case_expr (tree expr)
{
......
......@@ -925,6 +925,8 @@ union lang_tree_node
/* True if NODE is a variable that is out of scope. */
#define LOCAL_VAR_OUT_OF_SCOPE_P(NODE) \
(DECL_LANG_SPECIFIC (NODE)->u.v.freed)
#define LOCAL_SLOT_P(NODE) \
(DECL_LANG_SPECIFIC (NODE)->u.v.local_slot)
/* Create a DECL_LANG_SPECIFIC if necessary. */
#define MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC(T) \
if (DECL_LANG_SPECIFIC (T) == NULL) \
......@@ -1010,7 +1012,8 @@ struct lang_decl_var GTY(())
tree owner;
unsigned int final_iud : 1; /* Final initialized upon declaration */
unsigned int cif : 1; /* True: decl is a class initialization flag */
unsigned int freed; /* Decl is no longer in scope. */
unsigned int freed : 1; /* Decl is no longer in scope. */
unsigned int local_slot : 1; /* Decl is a temporary in the stack frame. */
};
/* This is what 'lang_decl' really points to. */
......@@ -1176,7 +1179,7 @@ extern void set_java_signature (tree, tree);
extern tree build_static_field_ref (tree);
extern tree build_address_of (tree);
extern tree find_local_variable (int index, tree type, int pc);
extern void update_aliases (tree decl, int index);
extern void update_aliases (tree decl, int index, int pc);
extern tree find_stack_slot (int index, tree type);
extern tree build_prim_array_type (tree, HOST_WIDE_INT);
extern tree build_java_array_type (tree, HOST_WIDE_INT);
......@@ -1254,6 +1257,8 @@ extern void java_layout_seen_class_methods (void);
extern void check_for_initialization (tree, tree);
extern tree pushdecl_top_level (tree);
extern tree pushdecl_function_level (tree);
extern tree java_replace_reference (tree, bool);
extern int alloc_class_constant (tree);
extern void init_expr_processing (void);
extern void push_super_field (tree, tree);
......
......@@ -391,9 +391,17 @@ build_java_array_type (tree element_type, HOST_WIDE_INT length)
el_name = TYPE_NAME (el_name);
if (TREE_CODE (el_name) == TYPE_DECL)
el_name = DECL_NAME (el_name);
TYPE_NAME (t) = build_decl (TYPE_DECL,
identifier_subst (el_name, "", '.', '.', "[]"),
{
char suffix[12];
if (length >= 0)
sprintf (suffix, "[%d]", (int)length);
else
strcpy (suffix, "[]");
TYPE_NAME (t)
= build_decl (TYPE_DECL,
identifier_subst (el_name, "", '.', '.', suffix),
t);
}
set_java_signature (t, sig);
set_super_info (0, t, object_type_node, 0);
......
......@@ -734,8 +734,8 @@ verify_jvm_instructions (JCF* jcf, const unsigned char *byte_ops, long length)
handlers. */
prev_eh_ranges = NULL_EH_RANGE;
/* Allocate decl and rtx for this variable now, so if we're not
optimizing, we get a temporary that survives the whole method. */
/* Allocate decl for this variable now, so we get a temporary
! that survives the whole method. */
find_local_variable (index, type, oldpc);
if (TYPE_IS_WIDE (type))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment