/* Handle the constant pool of the Java(TM) Virtual Machine.
- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005
+ Free Software Foundation, Inc.
This file is part of GCC.
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.
Java and all Java-based marks are trademarks or registered trademarks
of Sun Microsystems, Inc. in the United States and other countries.
static tree
get_tag_node (int tag)
{
- /* A Cache for build_int_2 (CONSTANT_XXX, 0). */
+ /* A Cache for build_int_cst (CONSTANT_XXX, 0). */
if (tag_nodes[tag] == NULL_TREE)
- tag_nodes[tag] = build_int_2 (tag, 0);
+ tag_nodes[tag] = build_int_cst (NULL_TREE, tag);
return tag_nodes[tag];
}
int
alloc_name_constant (int tag, tree name)
{
- CPool *outgoing_cpool = cpool_for_class (current_class);
+ CPool *outgoing_cpool = cpool_for_class (output_class);
return find_tree_constant (outgoing_cpool, tag, name);
}
+/* Create a constant pool entry for a name_and_type. This one has '.'
+ rather than '/' because it isn't going into a class file, it's
+ going into a compiled object. We don't use the '/' separator in
+ compiled objects. */
+
+static int
+find_name_and_type_constant_tree (CPool *cpool, tree name, tree type)
+{
+ int name_index = find_utf8_constant (cpool, name);
+ int type_index
+ = find_utf8_constant (cpool,
+ identifier_subst (build_java_signature (type),
+ "", '/', '.', ""));
+ return find_constant1 (cpool, CONSTANT_NameAndType,
+ (name_index << 16) | type_index);
+}
+
+/* Look for a field ref that matches DECL in the constant pool of
+ CLASS.
+ Return the index of the entry. */
+
+int
+alloc_constant_fieldref (tree class, tree decl)
+{
+ CPool *outgoing_cpool = cpool_for_class (class);
+ int class_index
+ = find_tree_constant (outgoing_cpool, CONSTANT_Class,
+ DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl))));
+ int name_type_index
+ = find_name_and_type_constant_tree (outgoing_cpool, DECL_NAME (decl),
+ TREE_TYPE (decl));
+ return find_constant1 (outgoing_cpool, CONSTANT_Fieldref,
+ (class_index << 16) | name_type_index);
+}
+
/* Build an identifier for the internal name of reference type TYPE. */
tree
IDENTIFIER_LENGTH(class_name))));
}
-/* Return a reference to the data array of the current constant pool. */
+/* Return the decl of the data array of the current constant pool. */
static tree
build_constant_data_ref (void)
{
- tree cpool_data_ref = NULL_TREE;
+ tree decl = TYPE_CPOOL_DATA_REF (output_class);
- if (TYPE_CPOOL_DATA_REF (current_class))
- cpool_data_ref = TYPE_CPOOL_DATA_REF (current_class);
-
- if (cpool_data_ref == NULL_TREE)
+ if (decl == NULL_TREE)
{
- tree decl;
- tree decl_name = mangled_classname ("_CD_", current_class);
- decl = build_decl (VAR_DECL, decl_name,
- build_array_type (ptr_type_node,
- one_elt_array_domain_type));
+ tree type;
+ tree decl_name = mangled_classname ("_CD_", output_class);
+
+ /* Build a type with unspecified bounds. The will make sure
+ that targets do the right thing with whatever size we end
+ up with at the end. Using bounds that are too small risks
+ assuming the data is in the small data section. */
+ type = build_array_type (ptr_type_node, NULL_TREE);
+
+ /* We need to lay out the type ourselves, since build_array_type
+ thinks the type is incomplete. */
+ layout_type (type);
+
+ decl = build_decl (VAR_DECL, decl_name, type);
TREE_STATIC (decl) = 1;
- make_decl_rtl (decl, NULL);
- TYPE_CPOOL_DATA_REF (current_class) = cpool_data_ref
- = build1 (ADDR_EXPR, ptr_type_node, decl);
+ TYPE_CPOOL_DATA_REF (output_class) = decl;
}
- return cpool_data_ref;
+
+ return decl;
}
/* Get the pointer value at the INDEX'th element of the constant pool. */
tree
build_ref_from_constant_pool (int index)
{
- tree t = build_constant_data_ref ();
- index *= int_size_in_bytes (ptr_type_node);
- t = fold (build (PLUS_EXPR, ptr_type_node,
- t, build_int_2 (index, 0)));
- return build1 (INDIRECT_REF, ptr_type_node, t);
+ tree d = build_constant_data_ref ();
+ tree i = build_int_cst (NULL_TREE, index);
+ return build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (d)), d, i,
+ NULL_TREE, NULL_TREE);
}
/* Build an initializer for the constants field of the current constant pool.
tree data_list = NULL_TREE;
int i;
for (i = outgoing_cpool->count; --i > 0; )
- {
- tags_list
- = tree_cons (NULL_TREE, get_tag_node (outgoing_cpool->tags[i]),
- tags_list);
- data_list
- = tree_cons (NULL_TREE, build_utf8_ref (outgoing_cpool->data[i].t),
- data_list);
- }
+ switch (outgoing_cpool->tags[i])
+ {
+ case CONSTANT_Fieldref:
+ case CONSTANT_NameAndType:
+ {
+ jword temp = outgoing_cpool->data[i].w;
+
+ tags_list
+ = tree_cons (NULL_TREE,
+ build_int_cst (NULL_TREE, outgoing_cpool->tags[i]),
+ tags_list);
+ data_list
+ = tree_cons (NULL_TREE,
+ fold_convert (ptr_type_node,
+ (build_int_cst (NULL_TREE, temp))),
+ data_list);
+ }
+ break;
+ default:
+ tags_list
+ = tree_cons (NULL_TREE, get_tag_node (outgoing_cpool->tags[i]),
+ tags_list);
+ data_list
+ = tree_cons (NULL_TREE, build_utf8_ref (outgoing_cpool->data[i].t),
+ data_list);
+ break;
+ }
if (outgoing_cpool->count > 0)
{
- tree index_type;
tree data_decl, tags_decl, tags_type;
- tree max_index = build_int_2 (outgoing_cpool->count - 1, 0);
- TREE_TYPE (max_index) = sizetype;
- index_type = build_index_type (max_index);
+ tree max_index = build_int_cst (sizetype, outgoing_cpool->count - 1);
+ tree index_type = build_index_type (max_index);
/* Add dummy 0'th element of constant pool. */
tags_list = tree_cons (NULL_TREE, get_tag_node (0), tags_list);
data_list = tree_cons (NULL_TREE, null_pointer_node, data_list);
- data_decl = TREE_OPERAND (build_constant_data_ref (), 0);
- TREE_TYPE (data_decl) = build_array_type (ptr_type_node, index_type),
- DECL_INITIAL (data_decl) = build_constructor (TREE_TYPE (data_decl),
- data_list);
+ data_decl = build_constant_data_ref ();
+ TREE_TYPE (data_decl) = build_array_type (ptr_type_node, index_type);
+ DECL_INITIAL (data_decl) = build_constructor_from_list
+ (TREE_TYPE (data_decl), data_list);
DECL_SIZE (data_decl) = TYPE_SIZE (TREE_TYPE (data_decl));
DECL_SIZE_UNIT (data_decl) = TYPE_SIZE_UNIT (TREE_TYPE (data_decl));
- rest_of_decl_compilation (data_decl, (char *) 0, 1, 0);
+ rest_of_decl_compilation (data_decl, 1, 0);
data_value = build_address_of (data_decl);
tags_type = build_array_type (unsigned_byte_type_node, index_type);
current_class),
tags_type);
TREE_STATIC (tags_decl) = 1;
- DECL_INITIAL (tags_decl) = build_constructor (tags_type, tags_list);
- rest_of_decl_compilation (tags_decl, (char*) 0, 1, 0);
+ DECL_INITIAL (tags_decl) = build_constructor_from_list
+ (tags_type, tags_list);
+ rest_of_decl_compilation (tags_decl, 1, 0);
tags_value = build_address_of (tags_decl);
}
else
tags_value = null_pointer_node;
}
START_RECORD_CONSTRUCTOR (cons, constants_type_node);
- PUSH_FIELD_VALUE (cons, "size", build_int_2 (outgoing_cpool->count, 0));
+ PUSH_FIELD_VALUE (cons, "size",
+ build_int_cst (NULL_TREE, outgoing_cpool->count));
PUSH_FIELD_VALUE (cons, "tags", tags_value);
PUSH_FIELD_VALUE (cons, "data", data_value);
FINISH_RECORD_CONSTRUCTOR (cons);