/* Process declarations and variables for the GNU compiler for the
Java(TM) language.
- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
- Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007,
+ 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
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.
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>.
Java and all Java-based marks are trademarks or registered trademarks
of Sun Microsystems, Inc. in the United States and other countries.
#include "java-except.h"
#include "ggc.h"
#include "timevar.h"
+#include "cgraph.h"
#include "tree-inline.h"
+#include "target.h"
+#include "version.h"
+#include "tree-iterator.h"
+#include "langhooks.h"
+#include "cgraph.h"
#if defined (DEBUG_JAVA_BINDING_LEVELS)
extern void indent (void);
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);
+static void parse_version (void);
+
+
+/* The following ABI flags are used in the high-order bits of the version
+ ID field. The version ID number itself should never be larger than
+ 0xfffff, so it should be safe to use top 12 bits for these flags. */
+
+#define FLAG_BINARYCOMPAT_ABI (1<<31) /* Class is built with the BC-ABI. */
+
+#define FLAG_BOOTSTRAP_LOADER (1<<30) /* Used when defining a class that
+ should be loaded by the bootstrap
+ loader. */
+
+/* If an ABI change is made within a GCC release series, rendering current
+ binaries incompatible with the old runtimes, this number must be set to
+ enforce the compatibility rules. */
+#define MINOR_BINARYCOMPAT_ABI_VERSION 1
+
+/* The runtime may recognize a variety of BC ABIs (objects generated by
+ different version of gcj), but will probably always require strict
+ matching for the ordinary (C++) ABI. */
+
+/* The version ID of the BC ABI that we generate. This must be kept in
+ sync with parse_version(), libgcj, and reality (if the BC format changes,
+ this must change). */
+#define GCJ_CURRENT_BC_ABI_VERSION \
+ (4 * 100000 + 0 * 1000 + MINOR_BINARYCOMPAT_ABI_VERSION)
+
+/* The ABI version number. */
+tree gcj_abi_version;
/* Name of the Cloneable class. */
tree java_lang_cloneable_identifier_node;
/* Name of the Serializable class. */
tree java_io_serializable_identifier_node;
-/* Set to nonzero value in order to emit class initialization code
- before static field references. */
-extern int always_initialize_class_p;
-
/* The DECL_MAP is a mapping from (index, type) to a decl node.
If index < max_locals, it is the index of a local variable.
if index >= max_locals, then index-max_locals is a stack slot.
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. */
+/* The decl for "_Jv_ResolvePoolEntry". */
+tree soft_resolvepoolentry_node;
+
+/* The decl for the .constants field of an instance of Class. */
+tree constants_field_decl_node;
+
+/* The decl for the .data field of an instance of Class. */
+tree constants_data_field_decl_node;
#if defined(DEBUG_JAVA_BINDING_LEVELS)
int binding_depth = 0;
void
indent (void)
{
- register unsigned i;
+ int i;
for (i = 0; i < binding_depth*2; i++)
putc (' ', stderr);
}
#endif /* defined(DEBUG_JAVA_BINDING_LEVELS) */
+/* 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;
+}
+
static tree
push_jvm_slot (int index, tree decl)
{
- struct rtx_def *rtl = NULL;
- tree type = TREE_TYPE (decl);
- tree tmp;
-
DECL_CONTEXT (decl) = current_function_decl;
layout_decl (decl, 0);
- /* See if we have an appropriate rtl (i.e. same mode) at this index.
- If so, we must use it. */
- tmp = TREE_VEC_ELT (decl_map, index);
- while (tmp != NULL_TREE)
- {
- if (TYPE_MODE (type) == TYPE_MODE (TREE_TYPE (tmp))
- && ! LOCAL_VAR_OUT_OF_SCOPE_P (tmp))
- rtl = DECL_RTL_IF_SET (tmp);
- if (rtl != NULL)
- break;
- tmp = DECL_LOCAL_SLOT_CHAIN (tmp);
- }
- if (rtl != NULL)
- SET_DECL_RTL (decl, rtl);
- else
- {
- if (index >= DECL_MAX_LOCALS (current_function_decl))
- DECL_REGISTER (decl) = 1;
- expand_decl (decl);
- }
-
/* Now link the decl into the decl_map. */
if (DECL_LANG_SPECIFIC (decl) == NULL)
{
}
DECL_LOCAL_SLOT_CHAIN (decl) = TREE_VEC_ELT (decl_map, index);
TREE_VEC_ELT (decl_map, 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 (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;
+ return decl;
}
/* Find the best declaration based upon type. If 'decl' fits 'type' better
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
- && 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;
- }
+ tree decl_type = TREE_TYPE (decl);
+
+ gcc_assert (! LOCAL_VAR_OUT_OF_SCOPE_P (decl));
+
+ /* 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
+ && TYPE_PRECISION (decl_type) >= TYPE_PRECISION (type))
+ /* ptr_type_node is used for null pointers, which are
+ assignment compatible with everything. */
+ || (TREE_CODE (decl_type) == POINTER_TYPE
+ && type == ptr_type_node)
+ /* Whenever anyone wants to use a slot that is initially
+ occupied by a PARM_DECL of pointer type they must get that
+ decl, even if they asked for a pointer to a different type.
+ However, if someone wants a scalar variable in a slot that
+ initially held a pointer arg -- or vice versa -- we create a
+ new VAR_DECL.
+
+ ???: As long as verification is correct, this will be a
+ compatible type. But maybe we should create a dummy variable
+ and replace all references to it with the DECL and a
+ NOP_EXPR.
+ */
+ || (TREE_CODE (decl_type) == POINTER_TYPE
+ && TREE_CODE (decl) == PARM_DECL
+ && TREE_CODE (type) == POINTER_TYPE))
+ {
+ if (best == NULL_TREE
+ || (decl_type == type && TREE_TYPE (best) != type))
+ return decl;
+ }
- return best;
+ return best;
}
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)
+ /* 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)
{
- /* 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)
- {
- /* 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 (! debug_variable_p (tmp))
+ decl = check_local_unnamed_variable (decl, tmp, type);
+ tmp = DECL_LOCAL_SLOT_CHAIN (tmp);
}
- if (best != NULL_TREE)
- return best;
+ /* gcj has a function called promote_type(), which is used by both
+ the bytecode compiler and the source compiler. Unfortunately,
+ the type systems for the Java VM and the Java language are not
+ the same: a boolean in the VM promotes to an int, not to a wide
+ boolean. If our caller wants something to hold a boolean, that
+ had better be an int, because that slot might be re-used
+ later in integer context. */
+ if (TREE_CODE (type) == BOOLEAN_TYPE)
+ type = integer_type_node;
+
+ /* If we don't find a match, create one with the type passed in.
+ 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. 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;
+ sprintf (buf, "#slot#%d#%d", index, uniq++);
+ name = get_identifier (buf);
+ decl = build_decl (input_location, 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);
+ }
- /* 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));
+ /* 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 (input_location, 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 genericization 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. */
+
+static 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);
+
+ gcc_assert (base_decl);
+ if (! want_lvalue)
+ base_decl = build1 (NOP_EXPR, decl_type, base_decl);
+
+ return base_decl;
+ }
+ }
+
+ return var_decl;
}
+/* Helper for java_genericize. */
+
+tree
+java_replace_references (tree *tp, int *walk_subtrees,
+ void *data ATTRIBUTE_UNUSED)
+{
+ if (TREE_CODE (*tp) == MODIFY_EXPR)
+ {
+ source_location loc = EXPR_LOCATION (*tp);
+ tree lhs = TREE_OPERAND (*tp, 0);
+ /* 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. */
+ if (TREE_CODE (lhs) == VAR_DECL
+ && DECL_LANG_SPECIFIC (lhs)
+ && LOCAL_SLOT_P (lhs)
+ && TREE_CODE (TREE_TYPE (lhs)) == POINTER_TYPE)
+ {
+ tree new_lhs = java_replace_reference (lhs, /* want_lvalue */ true);
+ tree new_rhs = build1 (NOP_EXPR, TREE_TYPE (new_lhs),
+ TREE_OPERAND (*tp, 1));
+ tree tem = build2 (MODIFY_EXPR, TREE_TYPE (new_lhs),
+ new_lhs, new_rhs);
+ *tp = build1 (NOP_EXPR, TREE_TYPE (lhs), tem);
+ SET_EXPR_LOCATION (tem, loc);
+ SET_EXPR_LOCATION (new_rhs, loc);
+ SET_EXPR_LOCATION (*tp, loc);
+ }
+ }
+ if (TREE_CODE (*tp) == VAR_DECL)
+ {
+ *tp = java_replace_reference (*tp, /* want_lvalue */ false);
+ *walk_subtrees = 0;
+ }
+
+ return NULL_TREE;
+}
/* Same as find_local_index, except that INDEX is a stack index. */
type, -1);
}
-struct binding_level
- {
+struct GTY(())
+ binding_level {
/* A chain of _DECL nodes for all variables, constants, functions,
* and typedef types. These are in the reverse of the order supplied.
*/
that were entered and exited one level down. */
tree blocks;
- /* The BLOCK node for this level, if one has been preallocated.
- If 0, the BLOCK is allocated (if needed) when the level is popped. */
- tree this_block;
-
/* The binding level which this one is contained in (inherits from). */
struct binding_level *level_chain;
/* The bytecode PC that marks the start of this level. */
int start_pc;
-#if defined(DEBUG_JAVA_BINDING_LEVELS)
- /* Binding depth at which this level began. */
+ /* The statements in this binding level. */
+ tree stmts;
+
+ /* An exception range associated with this binding level. */
+ struct eh_range * GTY((skip (""))) exception_range;
+
+ /* Binding depth at which this level began. Used only for debugging. */
unsigned binding_depth;
-#endif /* defined(DEBUG_JAVA_BINDING_LEVELS) */
+
+ /* The location at which this level began. */
+ source_location loc;
};
#define NULL_BINDING_LEVEL (struct binding_level *) NULL
/* The binding level currently in effect. */
-static struct binding_level *current_binding_level;
+static GTY(()) struct binding_level *current_binding_level;
/* A chain of binding_level structures awaiting reuse. */
-static struct binding_level *free_binding_level;
+static GTY(()) struct binding_level *free_binding_level;
/* The outermost binding level, for names of file scope.
This is created when the compiler is started and exists
through the entire run. */
-static struct binding_level *global_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. */
/* Binding level structures are initialized by copying this one. */
static const struct binding_level clear_binding_level
- = {NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE,
- NULL_BINDING_LEVEL, LARGEST_PC, 0};
-
-#if 0
-/* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
- that have names. Here so we can clear out their names' definitions
- at the end of the function. */
-
-static tree named_labels;
-
-/* A list of LABEL_DECLs from outer contexts that are currently shadowed. */
-
-static tree shadowed_labels;
-#endif
+= {
+ NULL_TREE, /* names */
+ NULL_TREE, /* shadowed */
+ NULL_TREE, /* blocks */
+ NULL_BINDING_LEVEL, /* level_chain */
+ LARGEST_PC, /* end_pc */
+ 0, /* start_pc */
+ NULL, /* stmts */
+ NULL, /* exception_range */
+ 0, /* binding_depth */
+ 0, /* loc */
+ };
tree java_global_trees[JTI_MAX];
-
+
/* Build (and pushdecl) a "promoted type" for all standard
types shorter than int. */
TYPE_MAX_VALUE (type) = copy_node (in_max);
TREE_TYPE (TYPE_MAX_VALUE (type)) = type;
TYPE_PRECISION (type) = TYPE_PRECISION (int_type_node);
+ TYPE_STRING_FLAG (type) = TYPE_STRING_FLAG (actual_type);
layout_type (type);
- pushdecl (build_decl (TYPE_DECL, get_identifier (name), type));
+ pushdecl (build_decl (input_location,
+ TYPE_DECL, get_identifier (name), type));
return type;
}
-/* Return a definition for a builtin function named NAME and whose data type
- is TYPE. TYPE should be a function type with argument types.
- FUNCTION_CODE tells later passes how to compile calls to this function.
- See tree.h for its possible values.
-
- If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME,
- the name to be called if we can't opencode the function. If
- ATTRS is nonzero, use that for the function's attribute list. */
-
-tree
-builtin_function (const char *name,
- tree type,
- int function_code,
- enum built_in_class class,
- const char *library_name,
- tree attrs ATTRIBUTE_UNUSED)
-{
- tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
- DECL_EXTERNAL (decl) = 1;
- TREE_PUBLIC (decl) = 1;
- if (library_name)
- SET_DECL_ASSEMBLER_NAME (decl, get_identifier (library_name));
- make_decl_rtl (decl, NULL);
- pushdecl (decl);
- DECL_BUILT_IN_CLASS (decl) = class;
- DECL_FUNCTION_CODE (decl) = function_code;
- return decl;
-}
-
/* Return tree that represents a vtable for a primitive array. */
static tree
create_primitive_vtable (const char *name)
char buf[50];
sprintf (buf, "_Jv_%sVTable", name);
- r = build_decl (VAR_DECL, get_identifier (buf), ptr_type_node);
+ r = build_decl (input_location,
+ VAR_DECL, get_identifier (buf), ptr_type_node);
DECL_EXTERNAL (r) = 1;
return r;
}
+/* Parse the version string and compute the ABI version number. */
+static void
+parse_version (void)
+{
+ const char *p = version_string;
+ unsigned int major = 0, minor = 0;
+ unsigned int abi_version;
+
+ /* Skip leading junk. */
+ while (*p && !ISDIGIT (*p))
+ ++p;
+ gcc_assert (*p);
+
+ /* Extract major version. */
+ while (ISDIGIT (*p))
+ {
+ major = major * 10 + *p - '0';
+ ++p;
+ }
+
+ gcc_assert (*p == '.' && ISDIGIT (p[1]));
+ ++p;
+
+ /* Extract minor version. */
+ while (ISDIGIT (*p))
+ {
+ minor = minor * 10 + *p - '0';
+ ++p;
+ }
+
+ if (flag_indirect_dispatch)
+ {
+ abi_version = GCJ_CURRENT_BC_ABI_VERSION;
+ abi_version |= FLAG_BINARYCOMPAT_ABI;
+ }
+ else /* C++ ABI */
+ {
+ /* Implicit in this computation is the idea that we won't break the
+ old-style binary ABI in a sub-minor release (e.g., from 4.0.0 to
+ 4.0.1). */
+ abi_version = 100000 * major + 1000 * minor;
+ }
+ if (flag_bootstrap_classes)
+ abi_version |= FLAG_BOOTSTRAP_LOADER;
+
+ gcj_abi_version = build_int_cstu (ptr_type_node, abi_version);
+}
+
void
java_init_decl_processing (void)
{
- register tree endlink;
+ tree endlink;
tree field = NULL_TREE;
tree t;
init_class_processing ();
- init_resource_processing ();
current_function_decl = NULL;
current_binding_level = NULL_BINDING_LEVEL;
initialize_sizetypes ();
byte_type_node = make_signed_type (8);
- pushdecl (build_decl (TYPE_DECL, get_identifier ("byte"), byte_type_node));
+ pushdecl (build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("byte"), byte_type_node));
short_type_node = make_signed_type (16);
- pushdecl (build_decl (TYPE_DECL, get_identifier ("short"), short_type_node));
+ pushdecl (build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("short"), short_type_node));
int_type_node = make_signed_type (32);
- pushdecl (build_decl (TYPE_DECL, get_identifier ("int"), int_type_node));
+ pushdecl (build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("int"), int_type_node));
long_type_node = make_signed_type (64);
- pushdecl (build_decl (TYPE_DECL, get_identifier ("long"), long_type_node));
+ pushdecl (build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("long"), long_type_node));
unsigned_byte_type_node = make_unsigned_type (8);
- pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned byte"),
+ pushdecl (build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("unsigned byte"),
unsigned_byte_type_node));
unsigned_short_type_node = make_unsigned_type (16);
- pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned short"),
+ pushdecl (build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("unsigned short"),
unsigned_short_type_node));
unsigned_int_type_node = make_unsigned_type (32);
- pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned int"),
+ pushdecl (build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("unsigned int"),
unsigned_int_type_node));
unsigned_long_type_node = make_unsigned_type (64);
- pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned long"),
+ pushdecl (build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("unsigned long"),
unsigned_long_type_node));
- set_sizetype (make_unsigned_type (POINTER_SIZE));
+ /* This is not a java type, however tree-dfa requires a definition for
+ size_type_node. */
+ size_type_node = make_unsigned_type (POINTER_SIZE);
+ set_sizetype (size_type_node);
/* Define these next since types below may used them. */
integer_type_node = java_type_for_size (INT_TYPE_SIZE, 0);
- integer_zero_node = build_int_2 (0, 0);
- integer_one_node = build_int_2 (1, 0);
- integer_two_node = build_int_2 (2, 0);
- integer_four_node = build_int_2 (4, 0);
- integer_minus_one_node = build_int_2 (-1, -1);
+ integer_zero_node = build_int_cst (NULL_TREE, 0);
+ integer_one_node = build_int_cst (NULL_TREE, 1);
+ integer_two_node = build_int_cst (NULL_TREE, 2);
+ integer_four_node = build_int_cst (NULL_TREE, 4);
+ integer_minus_one_node = build_int_cst (NULL_TREE, -1);
/* A few values used for range checking in the lexer. */
- decimal_int_max = build_int_2 (0x80000000, 0);
- TREE_TYPE (decimal_int_max) = unsigned_int_type_node;
+ decimal_int_max = build_int_cstu (unsigned_int_type_node, 0x80000000);
#if HOST_BITS_PER_WIDE_INT == 64
- decimal_long_max = build_int_2 (0x8000000000000000LL, 0);
-#else
-#if HOST_BITS_PER_WIDE_INT == 32
- decimal_long_max = build_int_2 (0, 0x80000000);
+ decimal_long_max = build_int_cstu (unsigned_long_type_node,
+ 0x8000000000000000LL);
+#elif HOST_BITS_PER_WIDE_INT == 32
+ decimal_long_max = build_int_cst_wide (unsigned_long_type_node,
+ 0, 0x80000000);
#else
#error "unsupported size"
#endif
-#endif
- TREE_TYPE (decimal_long_max) = unsigned_long_type_node;
size_zero_node = size_int (0);
size_one_node = size_int (1);
bitsize_one_node = bitsize_int (1);
bitsize_unit_node = bitsize_int (BITS_PER_UNIT);
- long_zero_node = build_int_2 (0, 0);
- TREE_TYPE (long_zero_node) = long_type_node;
+ long_zero_node = build_int_cst (long_type_node, 0);
void_type_node = make_node (VOID_TYPE);
- pushdecl (build_decl (TYPE_DECL, get_identifier ("void"), void_type_node));
+ pushdecl (build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("void"), void_type_node));
layout_type (void_type_node); /* Uses size_zero_node */
+
ptr_type_node = build_pointer_type (void_type_node);
+ const_ptr_type_node
+ = build_pointer_type (build_type_variant (void_type_node, 1, 0));
+
t = make_node (VOID_TYPE);
layout_type (t); /* Uses size_zero_node */
return_address_type_node = build_pointer_type (t);
- null_pointer_node = build_int_2 (0, 0);
- TREE_TYPE (null_pointer_node) = ptr_type_node;
-
- /* Used by the parser to represent empty statements and blocks. */
- empty_stmt_node = build1 (NOP_EXPR, void_type_node, size_zero_node);
- CAN_COMPLETE_NORMALLY (empty_stmt_node) = 1;
+ null_pointer_node = build_int_cst (ptr_type_node, 0);
-#if 0
- /* Make a type to be the domain of a few array types
- whose domains don't really matter.
- 200 is small enough that it always fits in size_t
- and large enough that it can hold most function names for the
- initializations of __FUNCTION__ and __PRETTY_FUNCTION__. */
- short_array_type_node = build_prim_array_type (short_type_node, 200);
-#endif
- char_type_node = make_node (CHAR_TYPE);
+ char_type_node = make_node (INTEGER_TYPE);
+ TYPE_STRING_FLAG (char_type_node) = 1;
TYPE_PRECISION (char_type_node) = 16;
fixup_unsigned_type (char_type_node);
- pushdecl (build_decl (TYPE_DECL, get_identifier ("char"), char_type_node));
+ pushdecl (build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("char"), char_type_node));
boolean_type_node = make_node (BOOLEAN_TYPE);
TYPE_PRECISION (boolean_type_node) = 1;
fixup_unsigned_type (boolean_type_node);
- pushdecl (build_decl (TYPE_DECL, get_identifier ("boolean"),
+ pushdecl (build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("boolean"),
boolean_type_node));
boolean_false_node = TYPE_MIN_VALUE (boolean_type_node);
boolean_true_node = TYPE_MAX_VALUE (boolean_type_node);
float_type_node = make_node (REAL_TYPE);
TYPE_PRECISION (float_type_node) = 32;
- pushdecl (build_decl (TYPE_DECL, get_identifier ("float"),
+ pushdecl (build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("float"),
float_type_node));
layout_type (float_type_node);
double_type_node = make_node (REAL_TYPE);
TYPE_PRECISION (double_type_node) = 64;
- pushdecl (build_decl (TYPE_DECL, get_identifier ("double"),
+ pushdecl (build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("double"),
double_type_node));
layout_type (double_type_node);
float_array_vtable = create_primitive_vtable ("float");
double_array_vtable = create_primitive_vtable ("double");
+ one_elt_array_domain_type = build_index_type (integer_one_node);
+ utf8const_type = make_node (RECORD_TYPE);
+ PUSH_FIELD (input_location,
+ utf8const_type, field, "hash", unsigned_short_type_node);
+ PUSH_FIELD (input_location,
+ utf8const_type, field, "length", unsigned_short_type_node);
+ FINISH_RECORD (utf8const_type);
+ utf8const_ptr_type = build_pointer_type (utf8const_type);
+
+ atable_type = build_array_type (ptr_type_node,
+ one_elt_array_domain_type);
+ TYPE_NONALIASED_COMPONENT (atable_type) = 1;
+ atable_ptr_type = build_pointer_type (atable_type);
+
+ itable_type = build_array_type (ptr_type_node,
+ one_elt_array_domain_type);
+ TYPE_NONALIASED_COMPONENT (itable_type) = 1;
+ itable_ptr_type = build_pointer_type (itable_type);
+
+ symbol_type = make_node (RECORD_TYPE);
+ PUSH_FIELD (input_location,
+ symbol_type, field, "clname", utf8const_ptr_type);
+ PUSH_FIELD (input_location, symbol_type, field, "name", utf8const_ptr_type);
+ PUSH_FIELD (input_location,
+ symbol_type, field, "signature", utf8const_ptr_type);
+ FINISH_RECORD (symbol_type);
+
+ symbols_array_type = build_array_type (symbol_type,
+ one_elt_array_domain_type);
+ symbols_array_ptr_type = build_pointer_type (symbols_array_type);
+
+ assertion_entry_type = make_node (RECORD_TYPE);
+ PUSH_FIELD (input_location,
+ assertion_entry_type, field, "assertion_code", integer_type_node);
+ PUSH_FIELD (input_location,
+ assertion_entry_type, field, "op1", utf8const_ptr_type);
+ PUSH_FIELD (input_location,
+ assertion_entry_type, field, "op2", utf8const_ptr_type);
+ FINISH_RECORD (assertion_entry_type);
+
+ assertion_table_type = build_array_type (assertion_entry_type,
+ one_elt_array_domain_type);
+
/* As you're adding items here, please update the code right after
this section, so that the filename containing the source code of
the pre-defined class gets registered correctly. */
add_predefined_file (get_identifier ("java/lang/Exception.java"));
add_predefined_file (get_identifier ("java/lang/ClassNotFoundException.java"));
add_predefined_file (get_identifier ("java/lang/NoClassDefFoundError.java"));
- add_predefined_file (get_identifier ("gnu/gcj/RawData.java"));
methodtable_type = make_node (RECORD_TYPE);
layout_type (methodtable_type);
- build_decl (TYPE_DECL, get_identifier ("methodtable"), methodtable_type);
+ build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("methodtable"), methodtable_type);
methodtable_ptr_type = build_pointer_type (methodtable_type);
TYPE_identifier_node = get_identifier ("TYPE");
init_identifier_node = get_identifier ("<init>");
clinit_identifier_node = get_identifier ("<clinit>");
- finit_identifier_node = get_identifier ("finit$");
- instinit_identifier_node = get_identifier ("instinit$");
void_signature_node = get_identifier ("()V");
- length_identifier_node = get_identifier ("length");
finalize_identifier_node = get_identifier ("finalize");
this_identifier_node = get_identifier ("this");
- super_identifier_node = get_identifier ("super");
- continue_identifier_node = get_identifier ("continue");
- access0_identifier_node = get_identifier ("access$0");
- classdollar_identifier_node = get_identifier ("class$");
java_lang_cloneable_identifier_node = get_identifier ("java.lang.Cloneable");
java_io_serializable_identifier_node =
/* for lack of a better place to put this stub call */
init_expr_processing();
- utf8const_type = make_node (RECORD_TYPE);
- PUSH_FIELD (utf8const_type, field, "hash", unsigned_short_type_node);
- PUSH_FIELD (utf8const_type, field, "length", unsigned_short_type_node);
- FINISH_RECORD (utf8const_type);
- utf8const_ptr_type = build_pointer_type (utf8const_type);
-
constants_type_node = make_node (RECORD_TYPE);
- PUSH_FIELD (constants_type_node, field, "size", unsigned_int_type_node);
- PUSH_FIELD (constants_type_node, field, "tags", ptr_type_node);
- PUSH_FIELD (constants_type_node, field, "data", ptr_type_node);
+ PUSH_FIELD (input_location,
+ constants_type_node, field, "size", unsigned_int_type_node);
+ PUSH_FIELD (input_location,
+ constants_type_node, field, "tags", ptr_type_node);
+ PUSH_FIELD (input_location,
+ constants_type_node, field, "data", ptr_type_node);
+ constants_data_field_decl_node = field;
FINISH_RECORD (constants_type_node);
- build_decl (TYPE_DECL, get_identifier ("constants"), constants_type_node);
+ build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("constants"), constants_type_node);
access_flags_type_node = unsigned_short_type_node;
dtable_type = make_node (RECORD_TYPE);
dtable_ptr_type = build_pointer_type (dtable_type);
- one_elt_array_domain_type = build_index_type (integer_one_node);
otable_type = build_array_type (integer_type_node,
one_elt_array_domain_type);
TYPE_NONALIASED_COMPONENT (otable_type) = 1;
otable_ptr_type = build_pointer_type (otable_type);
- atable_type = build_array_type (ptr_type_node,
- one_elt_array_domain_type);
- TYPE_NONALIASED_COMPONENT (atable_type) = 1;
- atable_ptr_type = build_pointer_type (atable_type);
- symbol_type = make_node (RECORD_TYPE);
- PUSH_FIELD (symbol_type, field, "clname", utf8const_ptr_type);
- PUSH_FIELD (symbol_type, field, "name", utf8const_ptr_type);
- PUSH_FIELD (symbol_type, field, "signature", utf8const_ptr_type);
- FINISH_RECORD (symbol_type);
-
- symbols_array_type = build_array_type (symbol_type,
- one_elt_array_domain_type);
- symbols_array_ptr_type = build_pointer_type (symbols_array_type);
-
- if (flag_indirect_dispatch)
- {
- otable_decl = build_decl (VAR_DECL, get_identifier ("otable"), otable_type);
- DECL_EXTERNAL (otable_decl) = 1;
- TREE_STATIC (otable_decl) = 1;
- TREE_READONLY (otable_decl) = 1;
- TREE_CONSTANT (otable_decl) = 1;
- pushdecl (otable_decl);
- otable_syms_decl = build_decl (VAR_DECL, get_identifier ("otable_syms"),
- symbols_array_type);
- TREE_STATIC (otable_syms_decl) = 1;
- TREE_CONSTANT (otable_syms_decl) = 1;
- pushdecl (otable_syms_decl);
-
- atable_decl = build_decl (VAR_DECL, get_identifier ("atable"), atable_type);
- DECL_EXTERNAL (atable_decl) = 1;
- TREE_STATIC (atable_decl) = 1;
- TREE_READONLY (atable_decl) = 1;
- TREE_CONSTANT (atable_decl) = 1;
- pushdecl (atable_decl);
- atable_syms_decl = build_decl (VAR_DECL, get_identifier ("atable_syms"),
- symbols_array_type);
- TREE_STATIC (atable_syms_decl) = 1;
- TREE_CONSTANT (atable_syms_decl) = 1;
- pushdecl (atable_syms_decl);
- }
-
- {
- tree catch_class_type = make_node (RECORD_TYPE);
- PUSH_FIELD (catch_class_type, field, "address", utf8const_ptr_type);
- PUSH_FIELD (catch_class_type, field, "classname", ptr_type_node);
- FINISH_RECORD (catch_class_type);
-
- ctable_decl
- = build_decl (VAR_DECL, get_identifier ("catch_classes"),
- build_array_type
- (catch_class_type, 0));
- DECL_EXTERNAL (ctable_decl) = 1;
- TREE_STATIC (ctable_decl) = 1;
- TREE_READONLY (ctable_decl) = 1;
- TREE_CONSTANT (ctable_decl) = 1;
- pushdecl (ctable_decl);
- }
+ PUSH_FIELD (input_location,
+ object_type_node, field, "vtable", dtable_ptr_type);
+ DECL_FCONTEXT (field) = object_type_node;
+ TYPE_VFIELD (object_type_node) = field;
- PUSH_FIELD (object_type_node, field, "vtable", dtable_ptr_type);
/* This isn't exactly true, but it is what we have in the source.
There is an unresolved issue here, which is whether the vtable
should be marked by the GC. */
if (! flag_hash_synchronization)
- PUSH_FIELD (object_type_node, field, "sync_info",
+ PUSH_FIELD (input_location, object_type_node, field, "sync_info",
build_pointer_type (object_type_node));
for (t = TYPE_FIELDS (object_type_node); t != NULL_TREE; t = TREE_CHAIN (t))
FIELD_PRIVATE (t) = 1;
set_super_info (0, string_type_node, object_type_node, 0);
class_ptr_type = build_pointer_type (class_type_node);
- PUSH_FIELD (class_type_node, field, "next", class_ptr_type);
- PUSH_FIELD (class_type_node, field, "name", utf8const_ptr_type);
- PUSH_FIELD (class_type_node, field, "accflags", access_flags_type_node);
- PUSH_FIELD (class_type_node, field, "superclass", class_ptr_type);
- PUSH_FIELD (class_type_node, field, "constants", constants_type_node);
- PUSH_FIELD (class_type_node, field, "methods", method_ptr_type_node);
- PUSH_FIELD (class_type_node, field, "method_count", short_type_node);
- PUSH_FIELD (class_type_node, field, "vtable_method_count", short_type_node);
- PUSH_FIELD (class_type_node, field, "fields", field_ptr_type_node);
- PUSH_FIELD (class_type_node, field, "size_in_bytes", int_type_node);
- PUSH_FIELD (class_type_node, field, "field_count", short_type_node);
- PUSH_FIELD (class_type_node, field, "static_field_count", short_type_node);
- PUSH_FIELD (class_type_node, field, "vtable", dtable_ptr_type);
- PUSH_FIELD (class_type_node, field, "otable", otable_ptr_type);
- PUSH_FIELD (class_type_node, field, "otable_syms",
+ PUSH_FIELD (input_location,
+ class_type_node, field, "next_or_version", class_ptr_type);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "name", utf8const_ptr_type);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "accflags", access_flags_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "superclass", class_ptr_type);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "constants", constants_type_node);
+ constants_field_decl_node = field;
+ PUSH_FIELD (input_location,
+ class_type_node, field, "methods", method_ptr_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "method_count", short_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "vtable_method_count", short_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "fields", field_ptr_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "size_in_bytes", int_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "field_count", short_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "static_field_count", short_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "vtable", dtable_ptr_type);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "otable", otable_ptr_type);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "otable_syms",
+ symbols_array_ptr_type);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "atable", atable_ptr_type);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "atable_syms",
symbols_array_ptr_type);
- PUSH_FIELD (class_type_node, field, "atable", atable_ptr_type);
- PUSH_FIELD (class_type_node, field, "atable_syms",
+ PUSH_FIELD (input_location,
+ class_type_node, field, "itable", itable_ptr_type);
+ PUSH_FIELD (input_location, class_type_node, field, "itable_syms",
symbols_array_ptr_type);
- PUSH_FIELD (class_type_node, field, "catch_classes", ptr_type_node);
- PUSH_FIELD (class_type_node, field, "interfaces",
+ PUSH_FIELD (input_location,
+ class_type_node, field, "catch_classes", ptr_type_node);
+ PUSH_FIELD (input_location, class_type_node, field, "interfaces",
build_pointer_type (class_ptr_type));
- PUSH_FIELD (class_type_node, field, "loader", ptr_type_node);
- PUSH_FIELD (class_type_node, field, "interface_count", short_type_node);
- PUSH_FIELD (class_type_node, field, "state", byte_type_node);
- PUSH_FIELD (class_type_node, field, "thread", ptr_type_node);
- PUSH_FIELD (class_type_node, field, "depth", short_type_node);
- PUSH_FIELD (class_type_node, field, "ancestors", ptr_type_node);
- PUSH_FIELD (class_type_node, field, "idt", ptr_type_node);
- PUSH_FIELD (class_type_node, field, "arrayclass", ptr_type_node);
- PUSH_FIELD (class_type_node, field, "protectionDomain", ptr_type_node);
- PUSH_FIELD (class_type_node, field, "signers", ptr_type_node);
- PUSH_FIELD (class_type_node, field, "chain", ptr_type_node);
+ PUSH_FIELD (input_location, class_type_node, field, "loader", ptr_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "interface_count", short_type_node);
+ PUSH_FIELD (input_location, class_type_node, field, "state", byte_type_node);
+ PUSH_FIELD (input_location, class_type_node, field, "thread", ptr_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "depth", short_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "ancestors", ptr_type_node);
+ PUSH_FIELD (input_location, class_type_node, field, "idt", ptr_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "arrayclass", ptr_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "protectionDomain", ptr_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "assertion_table", ptr_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "hack_signers", ptr_type_node);
+ PUSH_FIELD (input_location, class_type_node, field, "chain", ptr_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "aux_info", ptr_type_node);
+ PUSH_FIELD (input_location, class_type_node, field, "engine", ptr_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "reflection_data", ptr_type_node);
for (t = TYPE_FIELDS (class_type_node); t != NULL_TREE; t = TREE_CHAIN (t))
FIELD_PRIVATE (t) = 1;
push_super_field (class_type_node, object_type_node);
FINISH_RECORD (class_type_node);
- build_decl (TYPE_DECL, get_identifier ("Class"), class_type_node);
+ build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("Class"), class_type_node);
field_info_union_node = make_node (UNION_TYPE);
- PUSH_FIELD (field_info_union_node, field, "boffset", int_type_node);
- PUSH_FIELD (field_info_union_node, field, "addr", ptr_type_node);
-#if 0
- PUSH_FIELD (field_info_union_node, field, "idx", unsigned_short_type_node);
-#endif
+ PUSH_FIELD (input_location,
+ field_info_union_node, field, "boffset", int_type_node);
+ PUSH_FIELD (input_location,
+ field_info_union_node, field, "addr", ptr_type_node);
layout_type (field_info_union_node);
- PUSH_FIELD (field_type_node, field, "name", utf8const_ptr_type);
- PUSH_FIELD (field_type_node, field, "type", class_ptr_type);
- PUSH_FIELD (field_type_node, field, "accflags", access_flags_type_node);
- PUSH_FIELD (field_type_node, field, "bsize", unsigned_short_type_node);
- PUSH_FIELD (field_type_node, field, "info", field_info_union_node);
+ PUSH_FIELD (input_location,
+ field_type_node, field, "name", utf8const_ptr_type);
+ PUSH_FIELD (input_location, field_type_node, field, "type", class_ptr_type);
+ PUSH_FIELD (input_location,
+ field_type_node, field, "accflags", access_flags_type_node);
+ PUSH_FIELD (input_location,
+ field_type_node, field, "bsize", unsigned_short_type_node);
+ PUSH_FIELD (input_location,
+ field_type_node, field, "info", field_info_union_node);
FINISH_RECORD (field_type_node);
- build_decl (TYPE_DECL, get_identifier ("Field"), field_type_node);
+ build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("Field"), field_type_node);
nativecode_ptr_array_type_node
= build_array_type (nativecode_ptr_type_node, one_elt_array_domain_type);
- PUSH_FIELD (dtable_type, field, "class", class_ptr_type);
- PUSH_FIELD (dtable_type, field, "methods", nativecode_ptr_array_type_node);
+ PUSH_FIELD (input_location,
+ dtable_type, field, "class", class_ptr_type);
+ PUSH_FIELD (input_location,
+ dtable_type, field, "methods", nativecode_ptr_array_type_node);
FINISH_RECORD (dtable_type);
- build_decl (TYPE_DECL, get_identifier ("dispatchTable"), dtable_type);
-
-#define jint_type int_type_node
-#define jint_ptr_type ptr_type_node
+ build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("dispatchTable"), dtable_type);
jexception_type = make_node (RECORD_TYPE);
- PUSH_FIELD (jexception_type, field, "start_pc", ptr_type_node);
- PUSH_FIELD (jexception_type, field, "end_pc", ptr_type_node);
- PUSH_FIELD (jexception_type, field, "handler_pc", ptr_type_node);
- PUSH_FIELD (jexception_type, field, "catch_type", class_ptr_type);
+ PUSH_FIELD (input_location,
+ jexception_type, field, "start_pc", ptr_type_node);
+ PUSH_FIELD (input_location, jexception_type, field, "end_pc", ptr_type_node);
+ PUSH_FIELD (input_location,
+ jexception_type, field, "handler_pc", ptr_type_node);
+ PUSH_FIELD (input_location,
+ jexception_type, field, "catch_type", class_ptr_type);
FINISH_RECORD (jexception_type);
- build_decl (TYPE_DECL, get_identifier ("jexception"), field_type_node);
+ build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("jexception"), field_type_node);
jexception_ptr_type = build_pointer_type (jexception_type);
lineNumberEntry_type = make_node (RECORD_TYPE);
- PUSH_FIELD (lineNumberEntry_type, field, "line_nr", unsigned_short_type_node);
- PUSH_FIELD (lineNumberEntry_type, field, "start_pc", ptr_type_node);
+ PUSH_FIELD (input_location,
+ lineNumberEntry_type, field, "line_nr", unsigned_short_type_node);
+ PUSH_FIELD (input_location,
+ lineNumberEntry_type, field, "start_pc", ptr_type_node);
FINISH_RECORD (lineNumberEntry_type);
lineNumbers_type = make_node (RECORD_TYPE);
- PUSH_FIELD (lineNumbers_type, field, "length", unsigned_int_type_node);
+ PUSH_FIELD (input_location,
+ lineNumbers_type, field, "length", unsigned_int_type_node);
FINISH_RECORD (lineNumbers_type);
-#define instn_ptr_type_node ptr_type_node /* XXX JH */
-
-#define lineNumbers_ptr_type_node build_pointer_type(lineNumbers_type)
-
- PUSH_FIELD (method_type_node, field, "name", utf8const_ptr_type);
- PUSH_FIELD (method_type_node, field, "signature", utf8const_ptr_type);
- PUSH_FIELD (method_type_node, field, "accflags", access_flags_type_node);
- PUSH_FIELD (method_type_node, field, "index", unsigned_short_type_node);
- PUSH_FIELD (method_type_node, field, "ncode", nativecode_ptr_type_node);
- PUSH_FIELD (method_type_node, field, "throws", ptr_type_node);
+ PUSH_FIELD (input_location,
+ method_type_node, field, "name", utf8const_ptr_type);
+ PUSH_FIELD (input_location,
+ method_type_node, field, "signature", utf8const_ptr_type);
+ PUSH_FIELD (input_location,
+ method_type_node, field, "accflags", access_flags_type_node);
+ PUSH_FIELD (input_location,
+ method_type_node, field, "index", unsigned_short_type_node);
+ PUSH_FIELD (input_location,
+ method_type_node, field, "ncode", nativecode_ptr_type_node);
+ PUSH_FIELD (input_location,
+ method_type_node, field, "throws", ptr_type_node);
FINISH_RECORD (method_type_node);
- build_decl (TYPE_DECL, get_identifier ("Method"), method_type_node);
+ build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("Method"), method_type_node);
endlink = end_params_node = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
- t = tree_cons (NULL_TREE, class_ptr_type,
- tree_cons (NULL_TREE, int_type_node, endlink));
- alloc_object_node = builtin_function ("_Jv_AllocObject",
- build_function_type (ptr_type_node, t),
- 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ t = tree_cons (NULL_TREE, class_ptr_type, endlink);
+ alloc_object_node = add_builtin_function ("_Jv_AllocObject",
+ build_function_type (ptr_type_node, t),
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
DECL_IS_MALLOC (alloc_object_node) = 1;
- alloc_no_finalizer_node =
- builtin_function ("_Jv_AllocObjectNoFinalizer",
- build_function_type (ptr_type_node, t),
- 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ alloc_no_finalizer_node =
+ add_builtin_function ("_Jv_AllocObjectNoFinalizer",
+ build_function_type (ptr_type_node, t),
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
DECL_IS_MALLOC (alloc_no_finalizer_node) = 1;
t = tree_cons (NULL_TREE, ptr_type_node, endlink);
- soft_initclass_node = builtin_function ("_Jv_InitClass",
- build_function_type (void_type_node,
- t),
- 0, NOT_BUILT_IN, NULL, NULL_TREE);
-
- throw_node = builtin_function ("_Jv_Throw",
- build_function_type (ptr_type_node, t),
- 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ soft_initclass_node = add_builtin_function ("_Jv_InitClass",
+ build_function_type (void_type_node,
+ t),
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ t = tree_cons (NULL_TREE, class_ptr_type,
+ tree_cons (NULL_TREE, int_type_node, endlink));
+ soft_resolvepoolentry_node
+ = add_builtin_function ("_Jv_ResolvePoolEntry",
+ build_function_type (ptr_type_node, t),
+ 0,NOT_BUILT_IN, NULL, NULL_TREE);
+ DECL_PURE_P (soft_resolvepoolentry_node) = 1;
+ throw_node = add_builtin_function ("_Jv_Throw",
+ build_function_type (void_type_node, t),
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
/* Mark throw_nodes as `noreturn' functions with side effects. */
TREE_THIS_VOLATILE (throw_node) = 1;
TREE_SIDE_EFFECTS (throw_node) = 1;
- t = build_function_type (int_type_node, endlink);
- soft_monitorenter_node
- = builtin_function ("_Jv_MonitorEnter", t, 0, NOT_BUILT_IN,
- NULL, NULL_TREE);
- soft_monitorexit_node
- = builtin_function ("_Jv_MonitorExit", t, 0, NOT_BUILT_IN,
- NULL, NULL_TREE);
-
- t = tree_cons (NULL_TREE, int_type_node,
+ t = build_function_type (void_type_node, tree_cons (NULL_TREE, ptr_type_node,
+ endlink));
+ soft_monitorenter_node
+ = add_builtin_function ("_Jv_MonitorEnter", t, 0, NOT_BUILT_IN,
+ NULL, NULL_TREE);
+ soft_monitorexit_node
+ = add_builtin_function ("_Jv_MonitorExit", t, 0, NOT_BUILT_IN,
+ NULL, NULL_TREE);
+
+ t = tree_cons (NULL_TREE, ptr_type_node,
tree_cons (NULL_TREE, int_type_node, endlink));
soft_newarray_node
- = builtin_function ("_Jv_NewPrimArray",
- build_function_type(ptr_type_node, t),
- 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ = add_builtin_function ("_Jv_NewPrimArray",
+ build_function_type (ptr_type_node, t),
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
DECL_IS_MALLOC (soft_newarray_node) = 1;
t = tree_cons (NULL_TREE, int_type_node,
tree_cons (NULL_TREE, class_ptr_type,
- tree_cons (NULL_TREE, object_ptr_type_node, endlink)));
+ tree_cons (NULL_TREE, object_ptr_type_node,
+ endlink)));
soft_anewarray_node
- = builtin_function ("_Jv_NewObjectArray",
- build_function_type (ptr_type_node, t),
- 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ = add_builtin_function ("_Jv_NewObjectArray",
+ build_function_type (ptr_type_node, t),
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
DECL_IS_MALLOC (soft_anewarray_node) = 1;
/* There is no endlink here because _Jv_NewMultiArray is a varargs
t = tree_cons (NULL_TREE, ptr_type_node,
tree_cons (NULL_TREE, int_type_node, NULL_TREE));
soft_multianewarray_node
- = builtin_function ("_Jv_NewMultiArray",
- build_function_type (ptr_type_node, t),
- 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ = add_builtin_function ("_Jv_NewMultiArray",
+ build_function_type (ptr_type_node, t),
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
DECL_IS_MALLOC (soft_multianewarray_node) = 1;
t = build_function_type (void_type_node,
tree_cons (NULL_TREE, int_type_node, endlink));
soft_badarrayindex_node
- = builtin_function ("_Jv_ThrowBadArrayIndex", t,
- 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ = add_builtin_function ("_Jv_ThrowBadArrayIndex", t,
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
/* Mark soft_badarrayindex_node as a `noreturn' function with side
effects. */
TREE_THIS_VOLATILE (soft_badarrayindex_node) = 1;
TREE_SIDE_EFFECTS (soft_badarrayindex_node) = 1;
soft_nullpointer_node
- = builtin_function ("_Jv_ThrowNullPointerException",
- build_function_type (void_type_node, endlink),
- 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ = add_builtin_function ("_Jv_ThrowNullPointerException",
+ build_function_type (void_type_node, endlink),
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
/* Mark soft_nullpointer_node as a `noreturn' function with side
effects. */
TREE_THIS_VOLATILE (soft_nullpointer_node) = 1;
TREE_SIDE_EFFECTS (soft_nullpointer_node) = 1;
+ soft_abstractmethod_node
+ = add_builtin_function ("_Jv_ThrowAbstractMethodError",
+ build_function_type (void_type_node, endlink),
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ /* Mark soft_abstractmethod_node as a `noreturn' function with side
+ effects. */
+ TREE_THIS_VOLATILE (soft_abstractmethod_node) = 1;
+ TREE_SIDE_EFFECTS (soft_abstractmethod_node) = 1;
+
+ soft_nosuchfield_node
+ = add_builtin_function ("_Jv_ThrowNoSuchFieldError",
+ build_function_type (void_type_node, endlink),
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ /* Mark soft_nosuchfield_node as a `noreturn' function with side
+ effects. */
+ TREE_THIS_VOLATILE (soft_nosuchfield_node) = 1;
+ TREE_SIDE_EFFECTS (soft_nosuchfield_node) = 1;
+
t = tree_cons (NULL_TREE, class_ptr_type,
tree_cons (NULL_TREE, object_ptr_type_node, endlink));
soft_checkcast_node
- = builtin_function ("_Jv_CheckCast",
- build_function_type (ptr_type_node, t),
- 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ = add_builtin_function ("_Jv_CheckCast",
+ build_function_type (ptr_type_node, t),
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
t = tree_cons (NULL_TREE, object_ptr_type_node,
tree_cons (NULL_TREE, class_ptr_type, endlink));
soft_instanceof_node
- = builtin_function ("_Jv_IsInstanceOf",
- build_function_type (boolean_type_node, t),
- 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ = add_builtin_function ("_Jv_IsInstanceOf",
+ build_function_type (boolean_type_node, t),
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ DECL_PURE_P (soft_instanceof_node) = 1;
t = tree_cons (NULL_TREE, object_ptr_type_node,
tree_cons (NULL_TREE, object_ptr_type_node, endlink));
soft_checkarraystore_node
- = builtin_function ("_Jv_CheckArrayStore",
- build_function_type (void_type_node, t),
- 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ = add_builtin_function ("_Jv_CheckArrayStore",
+ build_function_type (void_type_node, t),
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
t = tree_cons (NULL_TREE, ptr_type_node,
tree_cons (NULL_TREE, ptr_type_node,
tree_cons (NULL_TREE, int_type_node, endlink)));
- soft_lookupinterfacemethod_node
- = builtin_function ("_Jv_LookupInterfaceMethodIdx",
- build_function_type (ptr_type_node, t),
- 0, NOT_BUILT_IN, NULL, NULL_TREE);
-
+ soft_lookupinterfacemethod_node
+ = add_builtin_function ("_Jv_LookupInterfaceMethodIdx",
+ build_function_type (ptr_type_node, t),
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ DECL_PURE_P (soft_lookupinterfacemethod_node) = 1;
+ t = tree_cons (NULL_TREE, ptr_type_node,
+ tree_cons (NULL_TREE, ptr_type_node,
+ tree_cons (NULL_TREE, ptr_type_node, endlink)));
+ soft_lookupinterfacemethodbyname_node
+ = add_builtin_function ("_Jv_LookupInterfaceMethod",
+ build_function_type (ptr_type_node, t),
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
t = tree_cons (NULL_TREE, object_ptr_type_node,
tree_cons (NULL_TREE, ptr_type_node,
tree_cons (NULL_TREE, ptr_type_node,
tree_cons (NULL_TREE, int_type_node,
endlink))));
soft_lookupjnimethod_node
- = builtin_function ("_Jv_LookupJNIMethod",
- build_function_type (ptr_type_node, t),
- 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ = add_builtin_function ("_Jv_LookupJNIMethod",
+ build_function_type (ptr_type_node, t),
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
t = tree_cons (NULL_TREE, ptr_type_node, endlink);
soft_getjnienvnewframe_node
- = builtin_function ("_Jv_GetJNIEnvNewFrame",
- build_function_type (ptr_type_node, t),
- 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ = add_builtin_function ("_Jv_GetJNIEnvNewFrame",
+ build_function_type (ptr_type_node, t),
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
soft_jnipopsystemframe_node
- = builtin_function ("_Jv_JNI_PopSystemFrame",
- build_function_type (ptr_type_node, t),
- 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ = add_builtin_function ("_Jv_JNI_PopSystemFrame",
+ build_function_type (void_type_node, t),
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
+
+ t = tree_cons (NULL_TREE, object_ptr_type_node, endlink);
+ soft_unwrapjni_node
+ = add_builtin_function ("_Jv_UnwrapJNIweakReference",
+ build_function_type (object_ptr_type_node, t),
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ t = tree_cons (NULL_TREE, int_type_node,
+ tree_cons (NULL_TREE, int_type_node, endlink));
soft_idiv_node
- = builtin_function ("_Jv_divI",
- build_function_type (int_type_node, t),
- 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ = add_builtin_function ("_Jv_divI",
+ build_function_type (int_type_node, t),
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
soft_irem_node
- = builtin_function ("_Jv_remI",
- build_function_type (int_type_node, t),
- 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ = add_builtin_function ("_Jv_remI",
+ build_function_type (int_type_node, t),
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ t = tree_cons (NULL_TREE, long_type_node,
+ tree_cons (NULL_TREE, long_type_node, endlink));
soft_ldiv_node
- = builtin_function ("_Jv_divJ",
- build_function_type (long_type_node, t),
- 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ = add_builtin_function ("_Jv_divJ",
+ build_function_type (long_type_node, t),
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
soft_lrem_node
- = builtin_function ("_Jv_remJ",
- build_function_type (long_type_node, t),
- 0, NOT_BUILT_IN, NULL, NULL_TREE);
-
- /* Initialize variables for except.c. */
- eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
- ? "__gcj_personality_sj0"
- : "__gcj_personality_v0");
- lang_eh_runtime_type = prepare_eh_table_type;
-
- init_jcf_parse ();
-
+ = add_builtin_function ("_Jv_remJ",
+ build_function_type (long_type_node, t),
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
+
initialize_builtins ();
soft_fmod_node = built_in_decls[BUILT_IN_FMOD];
-#if 0
- soft_fmodf_node = built_in_decls[BUILT_IN_FMODF];
-#endif
+
+ parse_version ();
}
tree
lookup_name (tree name)
{
- register tree val;
+ tree val;
if (current_binding_level != global_binding_level
&& IDENTIFIER_LOCAL_VALUE (name))
val = IDENTIFIER_LOCAL_VALUE (name);
}
/* Similar to `lookup_name' but look only at current binding level and
- the previous one if its the parameter level. */
+ the previous one if it's the parameter level. */
static tree
lookup_name_current_level (tree name)
{
- register tree t;
+ tree t;
if (current_binding_level == global_binding_level)
return IDENTIFIER_GLOBAL_VALUE (name);
return t;
}
-/* Use a binding level to record a labeled block declaration */
-
-void
-push_labeled_block (tree lb)
-{
- register tree name = DECL_NAME (LABELED_BLOCK_LABEL (lb));
- register struct binding_level *b = current_binding_level;
- tree oldlocal = IDENTIFIER_LOCAL_VALUE (name);
- if (oldlocal != 0)
- b->shadowed = tree_cons (name, oldlocal, b->shadowed);
- TREE_CHAIN (lb) = b->names;
- b->names = lb;
- IDENTIFIER_LOCAL_VALUE (name) = lb;
-}
-
-/* Pop the current binding level, reinstalling values for the previous
- labeled block */
-
-void
-pop_labeled_block (void)
-{
- struct binding_level *b = current_binding_level;
- tree label = b->names;
- IDENTIFIER_LOCAL_VALUE (DECL_NAME (LABELED_BLOCK_LABEL (label))) =
- NULL_TREE;
- if (b->shadowed)
- IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (b->shadowed)) =
- TREE_VALUE (b->shadowed);
-
- /* Pop the current level, and free the structure for reuse. */
- current_binding_level = current_binding_level->level_chain;
- b->level_chain = free_binding_level;
- free_binding_level = b;
-}
-
/* Record a decl-node X as belonging to the current lexical scope.
Check for errors (such as an incompatible declaration for the same
name already seen in the same scope).
tree
pushdecl (tree x)
{
- register tree t;
- register tree name = DECL_NAME (x);
- register struct binding_level *b = current_binding_level;
+ tree t;
+ tree name = DECL_NAME (x);
+ struct binding_level *b = current_binding_level;
if (TREE_CODE (x) != TYPE_DECL)
DECL_CONTEXT (x) = current_function_decl;
/* error_mark_node is 0 for a while during initialization! */
{
t = 0;
- error ("%J'%D' used prior to declaration", x, x);
+ error ("%q+D used prior to declaration", x);
}
/* If we're naming a hitherto-unnamed type, set its TYPE_NAME
tree oldlocal = IDENTIFIER_LOCAL_VALUE (name);
IDENTIFIER_LOCAL_VALUE (name) = x;
-#if 0
- /* Warn if shadowing an argument at the top level of the body. */
- if (oldlocal != 0 && !DECL_EXTERNAL (x)
- /* This warning doesn't apply to the parms of a nested fcn. */
- && ! current_binding_level->parm_flag
- /* Check that this is one level down from the parms. */
- && current_binding_level->level_chain->parm_flag
- /* Check that the decl being shadowed
- comes from the parm level, one level up. */
- && chain_member (oldlocal, current_binding_level->level_chain->names))
- {
- if (TREE_CODE (oldlocal) == PARM_DECL)
- pedwarn ("declaration of `%s' shadows a parameter",
- IDENTIFIER_POINTER (name));
- else
- pedwarn ("declaration of `%s' shadows a symbol from the parameter list",
- IDENTIFIER_POINTER (name));
- }
-
- /* Maybe warn if shadowing something else. */
- else if (warn_shadow && !DECL_EXTERNAL (x)
- /* No shadow warnings for internally generated vars. */
- && DECL_SOURCE_LINE (x) != 0
- /* No shadow warnings for vars made for inlining. */
- && ! DECL_FROM_INLINE (x))
- {
- const char *warnstring = 0;
-
- if (TREE_CODE (x) == PARM_DECL
- && current_binding_level->level_chain->parm_flag)
- /* Don't warn about the parm names in function declarator
- within a function declarator.
- It would be nice to avoid warning in any function
- declarator in a declaration, as opposed to a definition,
- but there is no way to tell it's not a definition. */
- ;
- else if (oldlocal != 0 && TREE_CODE (oldlocal) == PARM_DECL)
- warnstring = "declaration of `%s' shadows a parameter";
- else if (oldlocal != 0)
- warnstring = "declaration of `%s' shadows previous local";
- else if (IDENTIFIER_GLOBAL_VALUE (name) != 0
- && IDENTIFIER_GLOBAL_VALUE (name) != error_mark_node)
- warnstring = "declaration of `%s' shadows global declaration";
-
- if (warnstring)
- warning (warnstring, IDENTIFIER_POINTER (name));
- }
-#endif
-
/* If storing a local value, there may already be one (inherited).
If so, record it for restoration when this binding level ends. */
if (oldlocal != 0)
tree
pushdecl_top_level (tree x)
{
- register tree t;
- register struct binding_level *b = current_binding_level;
+ tree t;
+ struct binding_level *b = current_binding_level;
current_binding_level = global_binding_level;
t = pushdecl (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
make_binding_level (void)
{
/* NOSTRICT */
- return xmalloc (sizeof (struct binding_level));
+ return GGC_CNEW (struct binding_level);
}
void
pushlevel (int unused ATTRIBUTE_UNUSED)
{
- register struct binding_level *newlevel = NULL_BINDING_LEVEL;
-
-#if 0
- /* If this is the top level of a function,
- just make sure that NAMED_LABELS is 0. */
-
- if (current_binding_level == global_binding_level)
- named_labels = 0;
-#endif
+ struct binding_level *newlevel = NULL_BINDING_LEVEL;
/* Reuse or create a struct for this binding level. */
*newlevel = clear_binding_level;
newlevel->level_chain = current_binding_level;
- current_binding_level = newlevel;
+ newlevel->loc = input_location;
+ current_binding_level = newlevel;
#if defined(DEBUG_JAVA_BINDING_LEVELS)
newlevel->binding_depth = binding_depth;
indent ();
- fprintf (stderr, "push %s level 0x%08x pc %d\n",
+ fprintf (stderr, "push %s level %p pc %d\n",
(is_class_level) ? "class" : "block", newlevel, current_pc);
is_class_level = 0;
binding_depth++;
tree
poplevel (int keep, int reverse, int functionbody)
{
- register tree link;
+ tree link;
/* The chain of decls was accumulated in reverse order.
Put it into forward order, just for cleanliness. */
tree decls;
tree subblocks = current_binding_level->blocks;
tree block = 0;
tree decl;
- int block_previously_created;
- {
+ tree bind = 0;
#if defined(DEBUG_JAVA_BINDING_LEVELS)
binding_depth--;
indent ();
if (current_binding_level->end_pc != LARGEST_PC)
- fprintf (stderr, "pop %s level 0x%08x pc %d (end pc %d)\n",
+ fprintf (stderr, "pop %s level %p pc %d (end pc %d)\n",
(is_class_level) ? "class" : "block", current_binding_level, current_pc,
current_binding_level->end_pc);
else
- fprintf (stderr, "pop %s level 0x%08x pc %d\n",
+ fprintf (stderr, "pop %s level %p pc %d\n",
(is_class_level) ? "class" : "block", current_binding_level, current_pc);
-#if 0
- if (is_class_level != (current_binding_level == class_binding_level))
- {
- indent ();
- fprintf (stderr, "XXX is_class_level != (current_binding_level == class_binding_level)\n");
- }
- is_class_level = 0;
-#endif
#endif /* defined(DEBUG_JAVA_BINDING_LEVELS) */
/* Get the decls in the order they were written.
else
decls = current_binding_level->names;
- /* Output any nested inline functions within this block
- if they weren't already output. */
-
for (decl = decls; decl; decl = TREE_CHAIN (decl))
- if (TREE_CODE (decl) == FUNCTION_DECL
- && ! TREE_ASM_WRITTEN (decl)
- && DECL_INITIAL (decl) != 0
- && TREE_ADDRESSABLE (decl))
- {
- /* If this decl was copied from a file-scope decl on account
- of a block-scope extern decl, propagate TREE_ADDRESSABLE
- to the file-scope decl.
-
- DECL_ABSTRACT_ORIGIN can be set to itself if
- warn_return_type is true, since then the decl goes
- through save_for_inline_copying. */
- if (DECL_ABSTRACT_ORIGIN (decl) != 0
- && DECL_ABSTRACT_ORIGIN (decl) != decl)
- TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;
- else
- {
- push_function_context ();
- output_inline_function (decl);
- pop_function_context ();
- }
- }
- else if (TREE_CODE (decl) == VAR_DECL
- && DECL_LANG_SPECIFIC (decl) != NULL
- && DECL_LOCAL_SLOT_NUMBER (decl))
- LOCAL_VAR_OUT_OF_SCOPE_P (decl) = 1;
- }
+ if (TREE_CODE (decl) == VAR_DECL
+ && DECL_LANG_SPECIFIC (decl) != NULL
+ && DECL_LOCAL_SLOT_NUMBER (decl))
+ LOCAL_VAR_OUT_OF_SCOPE_P (decl) = 1;
/* If there were any declarations in that level,
or if this level is a function body,
create a BLOCK to record them for the life of this function. */
block = 0;
- block_previously_created = (current_binding_level->this_block != 0);
- if (block_previously_created)
- block = current_binding_level->this_block;
- else if (keep || functionbody)
- block = make_node (BLOCK);
+ if (keep || functionbody)
+ {
+ block = make_node (BLOCK);
+ TREE_TYPE (block) = void_type_node;
+ }
+
+ if (current_binding_level->exception_range)
+ expand_end_java_handler (current_binding_level->exception_range);
+
if (block != 0)
{
- BLOCK_VARS (block) = decls;
+ /* If any statements have been generated at this level, create a
+ BIND_EXPR to hold them and copy the variables to it. This
+ only applies to the bytecode compiler. */
+ if (current_binding_level->stmts)
+ {
+ tree decl = decls;
+ tree *var = &BLOCK_VARS (block);
+
+ /* Copy decls from names list, ignoring labels. */
+ while (decl)
+ {
+ tree next = TREE_CHAIN (decl);
+ if (TREE_CODE (decl) != LABEL_DECL)
+ {
+ *var = decl;
+ var = &TREE_CHAIN (decl);
+ }
+ decl = next;
+ }
+ *var = NULL;
+
+ bind = build3 (BIND_EXPR, TREE_TYPE (block), BLOCK_VARS (block),
+ BLOCK_EXPR_BODY (block), block);
+ BIND_EXPR_BODY (bind) = current_binding_level->stmts;
+
+ if (BIND_EXPR_BODY (bind)
+ && TREE_SIDE_EFFECTS (BIND_EXPR_BODY (bind)))
+ TREE_SIDE_EFFECTS (bind) = 1;
+
+ /* FIXME: gimplifier brain damage. */
+ if (BIND_EXPR_BODY (bind) == NULL)
+ BIND_EXPR_BODY (bind) = build_java_empty_stmt ();
+
+ SET_EXPR_LOCATION (bind, current_binding_level->loc);
+
+ current_binding_level->stmts = NULL;
+ }
+ else
+ {
+ BLOCK_VARS (block) = decls;
+ }
BLOCK_SUBBLOCKS (block) = subblocks;
- }
+ }
/* In each subblock, record that this is its superior. */
found in the FUNCTION_DECL instead. */
BLOCK_VARS (block) = 0;
-
- /* Clear out the definitions of all label names,
- since their scopes end here,
- and add them to BLOCK_VARS. */
-
-#if 0
- for (link = named_labels; link; link = TREE_CHAIN (link))
- {
- register tree label = TREE_VALUE (link);
-
- if (DECL_INITIAL (label) == 0)
- {
- error ("%Jlabel '%D' used but not defined", label, label);
- /* Avoid crashing later. */
- define_label (input_location, DECL_NAME (label));
- }
- else if (warn_unused[UNUSED_LABEL] && !TREE_USED (label))
- warning ("%Jlabel '%D' defined but not used", label, label);
- IDENTIFIER_LABEL_VALUE (DECL_NAME (label)) = 0;
-
- /* Put the labels into the "variables" of the
- top-level block, so debugger can see them. */
- TREE_CHAIN (label) = BLOCK_VARS (block);
- BLOCK_VARS (block) = label;
- }
-#endif
}
/* Pop the current level, and free the structure for reuse. */
{
- register struct binding_level *level = current_binding_level;
+ struct binding_level *level = current_binding_level;
current_binding_level = current_binding_level->level_chain;
level->level_chain = free_binding_level;
/* Dispose of the block that we just made inside some higher level. */
if (functionbody)
- DECL_INITIAL (current_function_decl) = block;
- else if (block)
{
- if (!block_previously_created)
- current_binding_level->blocks
- = chainon (current_binding_level->blocks, block);
+ DECL_INITIAL (current_function_decl) = block;
+ DECL_SAVED_TREE (current_function_decl) = bind;
+ }
+ else
+ {
+ if (block)
+ {
+ current_binding_level->blocks
+ = chainon (current_binding_level->blocks, block);
+ }
+ /* If we did not make a block for the level just exited,
+ any blocks made for inner levels
+ (since they cannot be recorded as subblocks in that level)
+ must be carried forward so they will later become subblocks
+ of something else. */
+ else if (subblocks)
+ current_binding_level->blocks
+ = chainon (current_binding_level->blocks, subblocks);
+
+ if (bind)
+ java_add_stmt (bind);
}
- /* If we did not make a block for the level just exited,
- any blocks made for inner levels
- (since they cannot be recorded as subblocks in that level)
- must be carried forward so they will later become subblocks
- of something else. */
- else if (subblocks)
- current_binding_level->blocks
- = chainon (current_binding_level->blocks, subblocks);
-
- /* Set the TYPE_CONTEXTs for all of the tagged types belonging to this
- binding contour so that they point to the appropriate construct, i.e.
- either to the current FUNCTION_DECL node, or else to the BLOCK node
- we just constructed.
-
- Note that for tagged types whose scope is just the formal parameter
- list for some function type specification, we can't properly set
- their TYPE_CONTEXTs here, because we don't have a pointer to the
- appropriate FUNCTION_TYPE node readily available to us. For those
- cases, the TYPE_CONTEXTs of the relevant tagged type nodes get set
- in `grokdeclarator' as soon as we have created the FUNCTION_TYPE
- node which will represent the "scope" for these "parameter list local"
- tagged types.
- */
if (block)
TREE_USED (block) = 1;
DECL_LOCAL_START_PC (pending_local_decls) <= pc)
{
tree *ptr = &pending_local_decls;
- tree decl = *ptr;
+ tree decl = *ptr, next;
int end_pc = DECL_LOCAL_END_PC (decl);
while (*ptr != NULL_TREE
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;
+ {
+ tree t;
+ end_pc = current_binding_level->end_pc;
+ for (t = decl; t != NULL_TREE; t = TREE_CHAIN (t))
+ DECL_LOCAL_END_PC (t) = end_pc;
+ }
maybe_start_try (pc, end_pc);
pushlevel (1);
- expand_start_bindings (0);
current_binding_level->end_pc = end_pc;
current_binding_level->start_pc = pc;
- current_binding_level->names = decl;
- for ( ; decl != NULL_TREE; decl = TREE_CHAIN (decl))
+ current_binding_level->names = NULL;
+ for ( ; decl != NULL_TREE; decl = next)
{
- push_jvm_slot (DECL_LOCAL_SLOT_NUMBER (decl), decl);
+ int index = DECL_LOCAL_SLOT_NUMBER (decl);
+ tree base_decl;
+ next = TREE_CHAIN (decl);
+ push_jvm_slot (index, decl);
+ pushdecl (decl);
+ base_decl
+ = find_local_variable (index, TREE_TYPE (decl), pc);
+ if (TREE_CODE (TREE_TYPE (base_decl)) == POINTER_TYPE)
+ base_decl = TREE_VEC_ELT (base_decl_map, index);
+ SET_DECL_VALUE_EXPR (decl, base_decl);
+ DECL_HAS_VALUE_EXPR_P (decl) = 1;
}
}
current_pc = pc;
#endif
+ /* FIXME: I'm pretty sure that this is wrong. Variable scopes are
+ inclusive, so a variable is live if pc == end_pc. Here, we
+ terminate a range if the current pc is equal to the end of the
+ range, and this is *before* we have generated code for the
+ instruction at end_pc. We're closing a binding level one
+ instruction too early.*/
while (current_binding_level->end_pc <= pc)
- {
- expand_end_bindings (getdecls (), 1, 0);
- maybe_end_try (current_binding_level->start_pc, pc);
- poplevel (1, 0, 0);
- }
- maybe_end_try (0, pc);
+ poplevel (1, 0, 0);
}
/* Terminate any binding which began during the range beginning at
while (current_binding_level->start_pc > start_pc)
{
if (pedantic && current_binding_level->start_pc > start_pc)
- warning ("%JIn %D: overlapped variable and exception ranges at %d",
- current_function_decl, current_function_decl,
+ warning (0, "In %+D: overlapped variable and exception ranges at %d",
+ current_function_decl,
current_binding_level->start_pc);
- expand_end_bindings (getdecls (), 1, 0);
poplevel (1, 0, 0);
}
}
-/* Insert BLOCK at the end of the list of subblocks of the
- current binding level. This is used when a BIND_EXPR is expanded,
- to handle the BLOCK node inside the BIND_EXPR. */
-
-void
-insert_block (tree block)
-{
- TREE_USED (block) = 1;
- current_binding_level->blocks
- = chainon (current_binding_level->blocks, block);
-}
-
-/* Set the BLOCK node for the innermost scope
- (the one we are currently in). */
-
-void
-set_block (tree block)
-{
- current_binding_level->this_block = block;
- current_binding_level->names = chainon (current_binding_level->names,
- BLOCK_VARS (block));
- current_binding_level->blocks = chainon (current_binding_level->blocks,
- BLOCK_SUBBLOCKS (block));
-}
-
/* integrate_decl_tree calls this function. */
void
return;
lang_decl_size = sizeof (struct lang_decl);
- x = ggc_alloc (lang_decl_size);
+ x = GGC_NEW (struct lang_decl);
memcpy (x, DECL_LANG_SPECIFIC (node), lang_decl_size);
DECL_LANG_SPECIFIC (node) = x;
}
{
tree decl = TREE_VEC_ELT (decl_map, slot);
DECL_NAME (decl) = name;
- SET_DECL_ASSEMBLER_NAME (decl, name);
if (TREE_CODE (decl) != PARM_DECL || TREE_TYPE (decl) != type)
- warning ("bad type in parameter debug info");
+ warning (0, "bad type in parameter debug info");
}
else
{
tree *ptr;
int end_pc = start_pc + length;
- tree decl = build_decl (VAR_DECL, name, type);
+ tree decl = build_decl (input_location, VAR_DECL, name, type);
if (end_pc > DECL_CODE_LENGTH (current_function_decl))
{
- warning ("%Jbad PC range for debug info for local '%D'",
- decl, decl);
+ warning (0, "bad PC range for debug info for local %q+D",
+ decl);
end_pc = DECL_CODE_LENGTH (current_function_decl);
}
MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
DECL_LOCAL_SLOT_NUMBER (decl) = slot;
DECL_LOCAL_START_PC (decl) = start_pc;
-#if 0
- /* FIXME: The range used internally for exceptions and local
- variable ranges, is a half-open interval:
- start_pc <= pc < end_pc. However, the range used in the
- Java VM spec is inclusive at both ends:
- start_pc <= pc <= end_pc. */
- end_pc++;
-#endif
DECL_LOCAL_END_PC (decl) = end_pc;
/* Now insert the new decl in the proper place in
sprintf (buffer, "ARG_%d", arg_i);
DECL_NAME (parm) = get_identifier (buffer);
}
- SET_DECL_ASSEMBLER_NAME (parm, DECL_NAME (parm));
}
}
}
tree result = DECL_RESULT (fndecl);
if (! result)
{
- /* To be compatible with C_PROMOTING_INTEGER_TYPE_P in cc1/cc1plus. */
- if (INTEGRAL_TYPE_P (restype)
- && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
- restype = integer_type_node;
- result = build_decl (RESULT_DECL, NULL_TREE, restype);
+ result = build_decl (DECL_SOURCE_LOCATION (fndecl),
+ RESULT_DECL, NULL_TREE, restype);
+ DECL_ARTIFICIAL (result) = 1;
+ DECL_IGNORED_P (result) = 1;
DECL_CONTEXT (result) = fndecl;
DECL_RESULT (fndecl) = result;
}
}
void
-complete_start_java_method (tree fndecl)
-{
- if (! flag_emit_class_files)
- {
- /* Initialize the RTL code for the function. */
- init_function_start (fndecl);
-
- /* Set up parameters and prepare for return, for the function. */
- expand_function_start (fndecl, 0);
- }
-
-#if 0
- /* If this fcn was already referenced via a block-scope `extern' decl (or
- an implicit decl), propagate certain information about the usage. */
- if (TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (current_function_decl)))
- TREE_ADDRESSABLE (current_function_decl) = 1;
-
-#endif
-
- if (METHOD_STATIC (fndecl) && ! METHOD_PRIVATE (fndecl)
- && ! flag_emit_class_files
- && ! DECL_CLINIT_P (fndecl)
- && ! CLASS_INTERFACE (TYPE_NAME (current_class)))
- {
- tree clas = DECL_CONTEXT (fndecl);
- tree init = build (CALL_EXPR, void_type_node,
- build_address_of (soft_initclass_node),
- build_tree_list (NULL_TREE, build_class_ref (clas)),
- NULL_TREE);
- TREE_SIDE_EFFECTS (init) = 1;
- expand_expr_stmt (init);
- }
-
- /* Push local variables. Function compiled from source code are
- using a different local variables management, and for them,
- pushlevel shouldn't be called from here. */
- if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (fndecl)))
- {
- pushlevel (2);
- if (! flag_emit_class_files)
- expand_start_bindings (1);
- }
-
- if (METHOD_SYNCHRONIZED (fndecl) && ! flag_emit_class_files)
- {
- /* Wrap function body with a monitorenter plus monitorexit cleanup. */
- tree enter, exit, lock;
- if (METHOD_STATIC (fndecl))
- lock = build_class_ref (DECL_CONTEXT (fndecl));
- else
- lock = DECL_ARGUMENTS (fndecl);
- BUILD_MONITOR_ENTER (enter, lock);
- BUILD_MONITOR_EXIT (exit, lock);
- if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (fndecl)))
- {
- expand_expr_stmt (enter);
- expand_decl_cleanup (NULL_TREE, exit);
- }
- else
- {
- tree function_body = DECL_FUNCTION_BODY (fndecl);
- tree body = BLOCK_EXPR_BODY (function_body);
- lock = build (COMPOUND_EXPR, void_type_node,
- enter,
- build (TRY_FINALLY_EXPR, void_type_node, body, exit));
- TREE_SIDE_EFFECTS (lock) = 1;
- BLOCK_EXPR_BODY (function_body) = lock;
- }
- }
-}
-
-void
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);
- type_map = xrealloc (type_map, i * sizeof (tree));
+ base_decl_map = make_tree_vec (i);
+ type_map = XRESIZEVEC (tree, type_map, i);
#if defined(DEBUG_JAVA_BINDING_LEVELS)
fprintf (stderr, "%s:\n", lang_printable_name (fndecl, 2));
{
tree parm_name = NULL_TREE, parm_decl;
tree parm_type = TREE_VALUE (tem);
- if (i >= DECL_MAX_LOCALS (fndecl))
- abort ();
+ gcc_assert (i < DECL_MAX_LOCALS (fndecl));
- parm_decl = build_decl (PARM_DECL, parm_name, parm_type);
+ parm_decl = build_decl (input_location, PARM_DECL, parm_name, parm_type);
DECL_CONTEXT (parm_decl) = fndecl;
- if (PROMOTE_PROTOTYPES
+ if (targetm.calls.promote_prototypes (parm_type)
&& TYPE_PRECISION (parm_type) < TYPE_PRECISION (integer_type_node)
&& INTEGRAL_TYPE_P (parm_type))
parm_type = integer_type_node;
/* Add parm_decl to the decl_map. */
push_jvm_slot (i, parm_decl);
+ /* The this parameter of methods is artificial. */
+ if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE && i == 0)
+ DECL_ARTIFICIAL (parm_decl) = 1;
+
type_map[i] = TREE_TYPE (parm_decl);
if (TYPE_IS_WIDE (TREE_TYPE (parm_decl)))
{
type_map[i++] = NULL_TREE;
build_result_decl (fndecl);
- complete_start_java_method (fndecl);
+ DECL_SOURCE_LOCATION (fndecl) = input_location;
+
+ /* Push local variables. */
+ pushlevel (2);
+
+ function_binding_level = current_binding_level;
}
void
{
tree fndecl = current_function_decl;
- expand_end_bindings (getdecls (), 1, 0);
/* pop out of function */
poplevel (1, 1, 0);
poplevel (1, 0, 1);
BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
+
+ if (DECL_SAVED_TREE (fndecl))
+ {
+ tree fbody, block_body;
+ /* Before we check initialization, attached all class initialization
+ variable to the block_body */
+ fbody = DECL_SAVED_TREE (fndecl);
+ block_body = BIND_EXPR_BODY (fbody);
+ htab_traverse (DECL_FUNCTION_INIT_TEST_TABLE (fndecl),
+ attach_init_test_initialization_flags, block_body);
+ }
- /* Generate rtl for function exit. */
- expand_function_end ();
-
- /* Run the optimizers and output assembler code for this function. */
- rest_of_compilation (fndecl);
+ finish_method (fndecl);
current_function_decl = NULL_TREE;
+ base_decl_map = NULL_TREE;
}
-/* Expand a function's body. */
+/* Prepare a method for expansion. */
void
-java_expand_body (tree fndecl)
+finish_method (tree fndecl)
{
- location_t saved_location = input_location;
-
- current_function_decl = fndecl;
- input_location = DECL_SOURCE_LOCATION (fndecl);
+ tree *tp = &DECL_SAVED_TREE (fndecl);
- timevar_push (TV_EXPAND);
-
- /* Prepare the function for tree completion. */
- start_complete_expand_method (fndecl);
-
- if (! flag_emit_class_files && ! flag_emit_xref)
+ /* Wrap body of synchronized methods in a monitorenter,
+ plus monitorexit cleanup. */
+ if (METHOD_SYNCHRONIZED (fndecl))
{
- /* Initialize the RTL code for the function. */
- init_function_start (fndecl);
-
- /* Set up parameters and prepare for return, for the function. */
- expand_function_start (fndecl, 0);
-
- /* Generate the RTL for this function. */
- expand_expr_stmt_value (DECL_SAVED_TREE (fndecl), 0, 1);
- }
-
- /* Pop out of its parameters. */
- pushdecl_force_head (DECL_ARGUMENTS (fndecl));
- poplevel (1, 0, 1);
- BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
-
- if (! flag_emit_class_files && ! flag_emit_xref)
- {
- /* Generate RTL for function exit. */
- input_line = DECL_FUNCTION_LAST_LINE (fndecl);
- expand_function_end ();
-
- /* Run the optimizers and output the assembler code
- for this function. */
- rest_of_compilation (fndecl);
+ tree enter, exit, lock;
+ if (METHOD_STATIC (fndecl))
+ lock = build_class_ref (DECL_CONTEXT (fndecl));
+ else
+ lock = DECL_ARGUMENTS (fndecl);
+ BUILD_MONITOR_ENTER (enter, lock);
+ BUILD_MONITOR_EXIT (exit, lock);
+ *tp = build2 (COMPOUND_EXPR, void_type_node, enter,
+ build2 (TRY_FINALLY_EXPR, void_type_node, *tp, exit));
}
- timevar_pop (TV_EXPAND);
+ /* Convert function tree to GENERIC prior to inlining. */
+ java_genericize (fndecl);
- input_location = saved_location;
+ /* Store the end of the function, so that we get good line number
+ info for the epilogue. */
+ if (DECL_STRUCT_FUNCTION (fndecl))
+ set_cfun (DECL_STRUCT_FUNCTION (fndecl));
+ else
+ allocate_struct_function (fndecl, false);
+ cfun->function_end_locus = DECL_FUNCTION_LAST_LINE (fndecl);
- current_function_decl = NULL_TREE;
+ /* Defer inlining and expansion to the cgraph optimizers. */
+ cgraph_finalize_function (fndecl, false);
}
/* We pessimistically marked all methods and fields external until we
{
DECL_EXTERNAL (decl) = 0;
- /* If we've already constructed DECL_RTL, give encode_section_info
- a second chance, now that we've changed the flags. */
+#ifdef ENABLE_CHECKING
+ /* Double check that we didn't pass the function to the callgraph early. */
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ gcc_assert (!cgraph_node (decl)->local.finalized);
+#endif
+ gcc_assert (!DECL_RTL_SET_P (decl));
+}
+
+/* Given appropriate target support, G++ will emit hidden aliases for native
+ methods. Using this hidden name is required for proper operation of
+ _Jv_Method::ncode, but it doesn't hurt to use it everywhere. Look for
+ proper target support, then mark the method for aliasing. */
+
+static void
+java_mark_cni_decl_local (tree decl)
+{
+#if !defined(HAVE_GAS_HIDDEN) || !defined(ASM_OUTPUT_DEF)
+ return;
+#endif
+
+ DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
+ DECL_LOCAL_CNI_METHOD_P (decl) = 1;
+
+ /* Setting DECL_LOCAL_CNI_METHOD_P changes the behavior of the
+ mangler. We might have already referenced this native method and
+ therefore created its name, but even if we have it won't hurt.
+ We'll just go via its externally visible name, rather than its
+ hidden alias. However, we must force things so that the correct
+ mangling is done. */
+
+ if (DECL_ASSEMBLER_NAME_SET_P (decl))
+ java_mangle_decl (decl);
if (DECL_RTL_SET_P (decl))
- make_decl_rtl (decl, NULL);
+ {
+ SET_DECL_RTL (decl, 0);
+ make_decl_rtl (decl);
+ }
}
+/* Use the preceding two functions and mark all members of the class. */
+
void
-java_mark_class_local (tree class)
+java_mark_class_local (tree klass)
{
tree t;
- for (t = TYPE_FIELDS (class); t ; t = TREE_CHAIN (t))
+ for (t = TYPE_FIELDS (klass); t ; t = TREE_CHAIN (t))
if (FIELD_STATIC (t))
java_mark_decl_local (t);
- for (t = TYPE_METHODS (class); t ; t = TREE_CHAIN (t))
- if (!METHOD_ABSTRACT (t) && (!METHOD_NATIVE (t) || flag_jni))
- java_mark_decl_local (t);
+ for (t = TYPE_METHODS (klass); t ; t = TREE_CHAIN (t))
+ if (!METHOD_ABSTRACT (t))
+ {
+ if (METHOD_NATIVE (t) && !flag_jni)
+ java_mark_cni_decl_local (t);
+ else
+ java_mark_decl_local (t);
+ }
+}
+
+/* Add a statement to a compound_expr. */
+
+tree
+add_stmt_to_compound (tree existing, tree type, tree stmt)
+{
+ if (!stmt)
+ return existing;
+ else if (existing)
+ {
+ tree expr = build2 (COMPOUND_EXPR, type, existing, stmt);
+ TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (existing)
+ | TREE_SIDE_EFFECTS (stmt);
+ return expr;
+ }
+ else
+ return stmt;
+}
+
+/* If this node is an expr, mark its input location. Called from
+ walk_tree(). */
+
+static tree
+set_input_location (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED)
+{
+ tree t = *tp;
+
+ if (CAN_HAVE_LOCATION_P (t))
+ {
+ if (EXPR_HAS_LOCATION(t))
+ return t; /* Don't walk any further into this expr. */
+ else
+ SET_EXPR_LOCATION (t, input_location);
+ }
+
+ return NULL_TREE; /* Continue walking this expr. */
+}
+
+/* Add a statement to the statement_list currently being constructed.
+ If the statement_list is null, we don't create a singleton list.
+ This is necessary because poplevel() assumes that adding a
+ statement to a null statement_list returns the statement. */
+
+tree
+java_add_stmt (tree new_stmt)
+{
+ tree stmts = current_binding_level->stmts;
+ tree_stmt_iterator i;
+
+ if (input_filename)
+ walk_tree (&new_stmt, set_input_location, NULL, NULL);
+
+ if (stmts == NULL)
+ return current_binding_level->stmts = new_stmt;
+
+ /* Force STMTS to be a statement_list. */
+ if (TREE_CODE (stmts) != STATEMENT_LIST)
+ {
+ tree t = make_node (STATEMENT_LIST);
+ i = tsi_last (t);
+ tsi_link_after (&i, stmts, TSI_CONTINUE_LINKING);
+ stmts = t;
+ }
+
+ i = tsi_last (stmts);
+ tsi_link_after (&i, new_stmt, TSI_CONTINUE_LINKING);
+ TREE_TYPE (stmts) = void_type_node;
+
+ return current_binding_level->stmts = stmts;
+}
+
+/* Add a variable to the current scope. */
+
+tree
+java_add_local_var (tree decl)
+{
+ tree *vars = ¤t_binding_level->names;
+ tree next = *vars;
+ TREE_CHAIN (decl) = next;
+ *vars = decl;
+ DECL_CONTEXT (decl) = current_function_decl;
+ MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
+ return decl;
+}
+
+/* Return a pointer to the compound_expr currently being
+ constructed. */
+
+tree *
+get_stmts (void)
+{
+ return ¤t_binding_level->stmts;
+}
+
+/* Register an exception range as belonging to the current binding
+ level. There may only be one: if there are more, we'll create more
+ binding levels. However, each range can have multiple handlers,
+ and these are expanded when we call expand_end_java_handler(). */
+
+void
+register_exception_range (struct eh_range *range, int pc, int end_pc)
+{
+ gcc_assert (! current_binding_level->exception_range);
+ current_binding_level->exception_range = range;
+ current_binding_level->end_pc = end_pc;
+ current_binding_level->start_pc = pc;
}
#include "gt-java-decl.h"