mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-31 15:11:04 +08:00
class.c (assume_compiled_node_struct): Rename type to class_flag_node_struct, as it is now also used for enable_assertions.
* class.c (assume_compiled_node_struct): Rename type to class_flag_node_struct, as it is now also used for enable_assertions. Rename assume_compiled_node typedef. Rename excludep field to value. (find_assume_compiled_node): Rename function to find_class_flag_node. Minor optimization - avoid needless strlen. (add_assume_compiled): Some tweaking and optimization. Rename and generalize to add_class_flag takem an extra parameter. (add_assume_compled): New just calls add_class_flag. (add_enable_assert, enable_assertions): New functions. (enable_assert_tree): New static. * java-tree.h (add_enable_assert, enable_assertions): New declarations. * lang.opt (fenable-assertions, fenable-assertions=, fdisable-assertions, fdisable-assertions=): New options. * lang.c (java_handle_option): Handle new options. * parse.y (build_incomplete_class_ref): Handle class$ in an inner class in an interface - create helper class nested in outer interface. (build_assertion): Short-circuit if enable_assertions is false. From-SVN: r79710
This commit is contained in:
parent
73c4ab99de
commit
24d82bce7a
@ -1,3 +1,23 @@
|
||||
2004-03-19 Per Bothner <per@bothner.com>
|
||||
|
||||
* class.c (assume_compiled_node_struct): Rename type to
|
||||
class_flag_node_struct, as it is now also used for enable_assertions.
|
||||
Rename assume_compiled_node typedef. Rename excludep field to value.
|
||||
(find_assume_compiled_node): Rename function to find_class_flag_node.
|
||||
Minor optimization - avoid needless strlen.
|
||||
(add_assume_compiled): Some tweaking and optimization.
|
||||
Rename and generalize to add_class_flag takem an extra parameter.
|
||||
(add_assume_compled): New just calls add_class_flag.
|
||||
(add_enable_assert, enable_assertions): New functions.
|
||||
(enable_assert_tree): New static.
|
||||
* java-tree.h (add_enable_assert, enable_assertions): New declarations.
|
||||
* lang.opt (fenable-assertions, fenable-assertions=,
|
||||
fdisable-assertions, fdisable-assertions=): New options.
|
||||
* lang.c (java_handle_option): Handle new options.
|
||||
* parse.y (build_incomplete_class_ref): Handle class$ in an inner
|
||||
class in an interface - create helper class nested in outer interface.
|
||||
(build_assertion): Short-circuit if enable_assertions is false.
|
||||
|
||||
2004-03-18 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
|
||||
|
||||
* java-tree.h: Changes throughout to add checking to macros
|
||||
|
141
gcc/java/class.c
141
gcc/java/class.c
@ -70,30 +70,32 @@ struct obstack temporary_obstack;
|
||||
it can assume certain classes have been compiled down to native
|
||||
code or not. The compiler options -fassume-compiled= and
|
||||
-fno-assume-compiled= are used to create a tree of
|
||||
assume_compiled_node objects. This tree is queried to determine if
|
||||
class_flag_node objects. This tree is queried to determine if
|
||||
a class is assume to be compiled or not. Each node in the tree
|
||||
represents either a package or a specific class. */
|
||||
|
||||
typedef struct assume_compiled_node_struct
|
||||
typedef struct class_flag_node_struct
|
||||
{
|
||||
/* The class or package name. */
|
||||
const char *ident;
|
||||
|
||||
/* Nonzero if this represents an exclusion. */
|
||||
int excludep;
|
||||
int value;
|
||||
|
||||
/* Pointers to other nodes in the tree. */
|
||||
struct assume_compiled_node_struct *parent;
|
||||
struct assume_compiled_node_struct *sibling;
|
||||
struct assume_compiled_node_struct *child;
|
||||
} assume_compiled_node;
|
||||
struct class_flag_node_struct *parent;
|
||||
struct class_flag_node_struct *sibling;
|
||||
struct class_flag_node_struct *child;
|
||||
} class_flag_node;
|
||||
|
||||
static assume_compiled_node *find_assume_compiled_node (assume_compiled_node *,
|
||||
const char *);
|
||||
static class_flag_node *find_class_flag_node (class_flag_node *, const char *);
|
||||
static void add_class_flag (class_flag_node **, const char *, int);
|
||||
|
||||
/* This is the root of the include/exclude tree. */
|
||||
|
||||
static assume_compiled_node *assume_compiled_tree;
|
||||
static class_flag_node *assume_compiled_tree;
|
||||
|
||||
static class_flag_node *enable_assert_tree;
|
||||
|
||||
static GTY(()) tree class_roots[5];
|
||||
#define registered_class class_roots[0]
|
||||
@ -103,11 +105,11 @@ static GTY(()) tree class_roots[5];
|
||||
#define class_dtable_decl class_roots[4]
|
||||
|
||||
/* Return the node that most closely represents the class whose name
|
||||
is IDENT. Start the search from NODE. Return NULL if an
|
||||
appropriate node does not exist. */
|
||||
is IDENT. Start the search from NODE (followed by its siblings).
|
||||
Return NULL if an appropriate node does not exist. */
|
||||
|
||||
static assume_compiled_node *
|
||||
find_assume_compiled_node (assume_compiled_node *node, const char *ident)
|
||||
static class_flag_node *
|
||||
find_class_flag_node (class_flag_node *node, const char *ident)
|
||||
{
|
||||
while (node)
|
||||
{
|
||||
@ -120,14 +122,13 @@ find_assume_compiled_node (assume_compiled_node *node, const char *ident)
|
||||
|
||||
if (node_ident_length == 0
|
||||
|| (strncmp (ident, node->ident, node_ident_length) == 0
|
||||
&& (strlen (ident) == node_ident_length
|
||||
&& (ident[node_ident_length] == '\0'
|
||||
|| ident[node_ident_length] == '.')))
|
||||
{
|
||||
/* We've found a match, however, there might be a more
|
||||
specific match. */
|
||||
|
||||
assume_compiled_node *found = find_assume_compiled_node (node->child,
|
||||
ident);
|
||||
class_flag_node *found = find_class_flag_node (node->child, ident);
|
||||
if (found)
|
||||
return found;
|
||||
else
|
||||
@ -142,54 +143,77 @@ find_assume_compiled_node (assume_compiled_node *node, const char *ident)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Add a new IDENT to the include/exclude tree. It's an exclusion
|
||||
if EXCLUDEP is nonzero. */
|
||||
|
||||
void
|
||||
add_assume_compiled (const char *ident, int excludep)
|
||||
add_class_flag (class_flag_node **rootp, const char *ident, int value)
|
||||
{
|
||||
int len;
|
||||
assume_compiled_node *parent;
|
||||
assume_compiled_node *node = xmalloc (sizeof (assume_compiled_node));
|
||||
|
||||
node->ident = xstrdup (ident);
|
||||
node->excludep = excludep;
|
||||
node->child = NULL;
|
||||
class_flag_node *root = *rootp;
|
||||
class_flag_node *parent, *node;
|
||||
|
||||
/* Create the root of the tree if it doesn't exist yet. */
|
||||
|
||||
if (NULL == assume_compiled_tree)
|
||||
if (NULL == root)
|
||||
{
|
||||
assume_compiled_tree = xmalloc (sizeof (assume_compiled_node));
|
||||
assume_compiled_tree->ident = "";
|
||||
assume_compiled_tree->excludep = 0;
|
||||
assume_compiled_tree->sibling = NULL;
|
||||
assume_compiled_tree->child = NULL;
|
||||
assume_compiled_tree->parent = NULL;
|
||||
root = xmalloc (sizeof (class_flag_node));
|
||||
root->ident = "";
|
||||
root->value = 0;
|
||||
root->sibling = NULL;
|
||||
root->child = NULL;
|
||||
root->parent = NULL;
|
||||
*rootp = root;
|
||||
}
|
||||
|
||||
/* Calling the function with the empty string means we're setting
|
||||
excludep for the root of the hierarchy. */
|
||||
value for the root of the hierarchy. */
|
||||
|
||||
if (0 == ident[0])
|
||||
{
|
||||
assume_compiled_tree->excludep = excludep;
|
||||
root->value = value;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find the parent node for this new node. PARENT will either be a
|
||||
class or a package name. Adjust PARENT accordingly. */
|
||||
|
||||
parent = find_assume_compiled_node (assume_compiled_tree, ident);
|
||||
len = strlen (parent->ident);
|
||||
if (parent->ident[len] && parent->ident[len] != '.')
|
||||
parent = parent->parent;
|
||||
parent = find_class_flag_node (root, ident);
|
||||
if (strcmp (ident, parent->ident) == 0)
|
||||
parent->value = value;
|
||||
else
|
||||
{
|
||||
/* Insert new node into the tree. */
|
||||
node = xmalloc (sizeof (class_flag_node));
|
||||
|
||||
/* Insert NODE into the tree. */
|
||||
node->ident = xstrdup (ident);
|
||||
node->value = value;
|
||||
node->child = NULL;
|
||||
|
||||
node->parent = parent;
|
||||
node->sibling = parent->child;
|
||||
parent->child = node;
|
||||
node->parent = parent;
|
||||
node->sibling = parent->child;
|
||||
parent->child = node;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add a new IDENT to the include/exclude tree. It's an exclusion
|
||||
if EXCLUDEP is nonzero. */
|
||||
|
||||
void
|
||||
add_assume_compiled (const char *ident, int excludep)
|
||||
{
|
||||
add_class_flag (&assume_compiled_tree, ident, excludep);
|
||||
}
|
||||
|
||||
/* The default value returned by enable_asserstions. */
|
||||
|
||||
#define DEFAULT_ENABLE_ASSERT (flag_emit_class_files || optimize == 0)
|
||||
|
||||
/* Enter IDENT (a class or package name) into the enable-assertions table.
|
||||
VALUE is true to enable and false to disable. */
|
||||
|
||||
void
|
||||
add_enable_assert (const char *ident, int value)
|
||||
{
|
||||
if (enable_assert_tree == NULL)
|
||||
add_class_flag (&enable_assert_tree, "", DEFAULT_ENABLE_ASSERT);
|
||||
add_class_flag (&enable_assert_tree, ident, value);
|
||||
}
|
||||
|
||||
/* Returns nonzero if IDENT is the name of a class that the compiler
|
||||
@ -198,20 +222,39 @@ add_assume_compiled (const char *ident, int excludep)
|
||||
static int
|
||||
assume_compiled (const char *ident)
|
||||
{
|
||||
assume_compiled_node *i;
|
||||
class_flag_node *i;
|
||||
int result;
|
||||
|
||||
if (NULL == assume_compiled_tree)
|
||||
return 1;
|
||||
|
||||
i = find_assume_compiled_node (assume_compiled_tree,
|
||||
ident);
|
||||
i = find_class_flag_node (assume_compiled_tree, ident);
|
||||
|
||||
result = ! i->excludep;
|
||||
result = ! i->value;
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* Return true if we should generate code to check assertions within KLASS. */
|
||||
|
||||
bool
|
||||
enable_assertions (tree klass)
|
||||
{
|
||||
/* Check if command-line specifies whether we should check asserrtions. */
|
||||
|
||||
if (klass != NULL_TREE && DECL_NAME (klass) && enable_assert_tree != NULL)
|
||||
{
|
||||
const char *ident = IDENTIFIER_POINTER (DECL_NAME (klass));
|
||||
class_flag_node *node
|
||||
= find_class_flag_node (enable_assert_tree, ident);
|
||||
return node->value;
|
||||
}
|
||||
|
||||
/* The default is to enable assertions if generating class files,
|
||||
or not optimizing. */
|
||||
return DEFAULT_ENABLE_ASSERT;
|
||||
}
|
||||
|
||||
/* Return an IDENTIFIER_NODE the same as (OLD_NAME, OLD_LENGTH).
|
||||
except that characters matching OLD_CHAR are substituted by NEW_CHAR.
|
||||
Also, PREFIX is prepended, and SUFFIX is appended. */
|
||||
|
@ -1127,6 +1127,8 @@ extern tree java_signed_type (tree);
|
||||
extern tree java_signed_or_unsigned_type (int, tree);
|
||||
extern tree java_truthvalue_conversion (tree);
|
||||
extern void add_assume_compiled (const char *, int);
|
||||
extern void add_enable_assert (const char *, int);
|
||||
extern bool enable_assertions (tree);
|
||||
extern tree lookup_class (tree);
|
||||
extern tree lookup_java_constructor (tree, tree);
|
||||
extern tree lookup_java_method (tree, tree, tree);
|
||||
|
@ -354,6 +354,22 @@ java_handle_option (size_t scode, const char *arg, int value)
|
||||
flag_assert = value;
|
||||
break;
|
||||
|
||||
case OPT_fenable_assertions_:
|
||||
add_enable_assert (arg, value);
|
||||
break;
|
||||
|
||||
case OPT_fenable_assertions:
|
||||
add_enable_assert ("", value);
|
||||
break;
|
||||
|
||||
case OPT_fdisable_assertions_:
|
||||
add_enable_assert (arg, !value);
|
||||
break;
|
||||
|
||||
case OPT_fdisable_assertions:
|
||||
add_enable_assert ("", !value);
|
||||
break;
|
||||
|
||||
case OPT_fassume_compiled_:
|
||||
add_assume_compiled (arg, !value);
|
||||
break;
|
||||
|
@ -90,6 +90,18 @@ Java
|
||||
fassume-compiled=
|
||||
Java JoinedOrMissing
|
||||
|
||||
fenable-assertions
|
||||
Java
|
||||
|
||||
fenable-assertions=
|
||||
Java JoinedOrMissing
|
||||
|
||||
fdisable-assertions
|
||||
Java
|
||||
|
||||
fdisable-assertions=
|
||||
Java JoinedOrMissing
|
||||
|
||||
fbootclasspath=
|
||||
Java JoinedOrMissing RejectNegative
|
||||
--bootclasspath=<path> Replace system path
|
||||
|
@ -13992,25 +13992,32 @@ build_incomplete_class_ref (int location, tree class_name)
|
||||
&& !JPRIMITIVE_TYPE_P (class_name)
|
||||
&& !(TREE_CODE (class_name) == VOID_TYPE))
|
||||
{
|
||||
tree cpc_list = GET_CPC_LIST();
|
||||
tree cpc = cpc_list;
|
||||
tree target_class;
|
||||
|
||||
if (CLASS_INTERFACE (TYPE_NAME (this_class)))
|
||||
/* For inner classes, add a 'class$' method to their outermost
|
||||
context, creating it if necessary. */
|
||||
|
||||
while (GET_NEXT_ENCLOSING_CPC(cpc))
|
||||
cpc = GET_NEXT_ENCLOSING_CPC(cpc);
|
||||
class_decl = TREE_VALUE (cpc);
|
||||
|
||||
target_class = TREE_TYPE (class_decl);
|
||||
|
||||
if (CLASS_INTERFACE (TYPE_NAME (target_class)))
|
||||
{
|
||||
/* For interfaces, adding a static 'class$' method directly
|
||||
is illegal. So create an inner class to contain the new
|
||||
method. Empirically this matches the behavior of javac. */
|
||||
tree t = build_wfl_node (DECL_NAME (TYPE_NAME (object_type_node)));
|
||||
tree inner = create_anonymous_class (0, t);
|
||||
tree t, inner;
|
||||
/* We want the generated inner class inside the outermost class. */
|
||||
GET_CPC_LIST() = cpc;
|
||||
t = build_wfl_node (DECL_NAME (TYPE_NAME (object_type_node)));
|
||||
inner = create_anonymous_class (0, t);
|
||||
target_class = TREE_TYPE (inner);
|
||||
end_class_declaration (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* For inner classes, add a 'class$' method to their outermost
|
||||
context, creating it if necessary. */
|
||||
while (INNER_CLASS_DECL_P (class_decl))
|
||||
class_decl = DECL_CONTEXT (class_decl);
|
||||
target_class = TREE_TYPE (class_decl);
|
||||
GET_CPC_LIST() = cpc_list;
|
||||
}
|
||||
|
||||
if (TYPE_DOT_CLASS (target_class) == NULL_TREE)
|
||||
@ -15299,6 +15306,16 @@ build_assertion (int location, tree condition, tree value)
|
||||
tree node;
|
||||
tree klass = GET_CPC ();
|
||||
|
||||
if (! enable_assertions (klass))
|
||||
{
|
||||
condition = build (TRUTH_ANDIF_EXPR, NULL_TREE,
|
||||
boolean_false_node, condition);
|
||||
if (value == NULL_TREE)
|
||||
value = empty_stmt_node;
|
||||
return build_if_else_statement (location, condition,
|
||||
value, NULL_TREE);
|
||||
}
|
||||
|
||||
if (! CLASS_USES_ASSERTIONS (klass))
|
||||
{
|
||||
tree field, classdollar, id, call;
|
||||
|
Loading…
x
Reference in New Issue
Block a user