Commit 24d82bce by Per Bothner Committed by Per Bothner

class.c (assume_compiled_node_struct): Rename type to class_flag_node_struct, as…

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
parent 73c4ab99
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> 2004-03-18 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* java-tree.h: Changes throughout to add checking to macros * java-tree.h: Changes throughout to add checking to macros
......
...@@ -70,30 +70,32 @@ struct obstack temporary_obstack; ...@@ -70,30 +70,32 @@ struct obstack temporary_obstack;
it can assume certain classes have been compiled down to native it can assume certain classes have been compiled down to native
code or not. The compiler options -fassume-compiled= and code or not. The compiler options -fassume-compiled= and
-fno-assume-compiled= are used to create a tree of -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 a class is assume to be compiled or not. Each node in the tree
represents either a package or a specific class. */ 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. */ /* The class or package name. */
const char *ident; const char *ident;
/* Nonzero if this represents an exclusion. */ /* Nonzero if this represents an exclusion. */
int excludep; int value;
/* Pointers to other nodes in the tree. */ /* Pointers to other nodes in the tree. */
struct assume_compiled_node_struct *parent; struct class_flag_node_struct *parent;
struct assume_compiled_node_struct *sibling; struct class_flag_node_struct *sibling;
struct assume_compiled_node_struct *child; struct class_flag_node_struct *child;
} assume_compiled_node; } class_flag_node;
static assume_compiled_node *find_assume_compiled_node (assume_compiled_node *, static class_flag_node *find_class_flag_node (class_flag_node *, const char *);
const char *); static void add_class_flag (class_flag_node **, const char *, int);
/* This is the root of the include/exclude tree. */ /* 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]; static GTY(()) tree class_roots[5];
#define registered_class class_roots[0] #define registered_class class_roots[0]
...@@ -103,11 +105,11 @@ static GTY(()) tree class_roots[5]; ...@@ -103,11 +105,11 @@ static GTY(()) tree class_roots[5];
#define class_dtable_decl class_roots[4] #define class_dtable_decl class_roots[4]
/* Return the node that most closely represents the class whose name /* Return the node that most closely represents the class whose name
is IDENT. Start the search from NODE. Return NULL if an is IDENT. Start the search from NODE (followed by its siblings).
appropriate node does not exist. */ Return NULL if an appropriate node does not exist. */
static assume_compiled_node * static class_flag_node *
find_assume_compiled_node (assume_compiled_node *node, const char *ident) find_class_flag_node (class_flag_node *node, const char *ident)
{ {
while (node) while (node)
{ {
...@@ -120,14 +122,13 @@ find_assume_compiled_node (assume_compiled_node *node, const char *ident) ...@@ -120,14 +122,13 @@ find_assume_compiled_node (assume_compiled_node *node, const char *ident)
if (node_ident_length == 0 if (node_ident_length == 0
|| (strncmp (ident, node->ident, 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] == '.'))) || ident[node_ident_length] == '.')))
{ {
/* We've found a match, however, there might be a more /* We've found a match, however, there might be a more
specific match. */ specific match. */
assume_compiled_node *found = find_assume_compiled_node (node->child, class_flag_node *found = find_class_flag_node (node->child, ident);
ident);
if (found) if (found)
return found; return found;
else else
...@@ -142,54 +143,77 @@ find_assume_compiled_node (assume_compiled_node *node, const char *ident) ...@@ -142,54 +143,77 @@ find_assume_compiled_node (assume_compiled_node *node, const char *ident)
return NULL; return NULL;
} }
/* Add a new IDENT to the include/exclude tree. It's an exclusion
if EXCLUDEP is nonzero. */
void void
add_assume_compiled (const char *ident, int excludep) add_class_flag (class_flag_node **rootp, const char *ident, int value)
{ {
int len; class_flag_node *root = *rootp;
assume_compiled_node *parent; class_flag_node *parent, *node;
assume_compiled_node *node = xmalloc (sizeof (assume_compiled_node));
node->ident = xstrdup (ident);
node->excludep = excludep;
node->child = NULL;
/* Create the root of the tree if it doesn't exist yet. */ /* 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)); root = xmalloc (sizeof (class_flag_node));
assume_compiled_tree->ident = ""; root->ident = "";
assume_compiled_tree->excludep = 0; root->value = 0;
assume_compiled_tree->sibling = NULL; root->sibling = NULL;
assume_compiled_tree->child = NULL; root->child = NULL;
assume_compiled_tree->parent = NULL; root->parent = NULL;
*rootp = root;
} }
/* Calling the function with the empty string means we're setting /* 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]) if (0 == ident[0])
{ {
assume_compiled_tree->excludep = excludep; root->value = value;
return; return;
} }
/* Find the parent node for this new node. PARENT will either be a /* Find the parent node for this new node. PARENT will either be a
class or a package name. Adjust PARENT accordingly. */ class or a package name. Adjust PARENT accordingly. */
parent = find_assume_compiled_node (assume_compiled_tree, ident); parent = find_class_flag_node (root, ident);
len = strlen (parent->ident); if (strcmp (ident, parent->ident) == 0)
if (parent->ident[len] && parent->ident[len] != '.') parent->value = value;
parent = parent->parent; 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->parent = parent;
node->sibling = parent->child; node->sibling = parent->child;
parent->child = node; 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 /* 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) ...@@ -198,20 +222,39 @@ add_assume_compiled (const char *ident, int excludep)
static int static int
assume_compiled (const char *ident) assume_compiled (const char *ident)
{ {
assume_compiled_node *i; class_flag_node *i;
int result; int result;
if (NULL == assume_compiled_tree) if (NULL == assume_compiled_tree)
return 1; return 1;
i = find_assume_compiled_node (assume_compiled_tree, i = find_class_flag_node (assume_compiled_tree, ident);
ident);
result = ! i->excludep; result = ! i->value;
return (result); 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). /* Return an IDENTIFIER_NODE the same as (OLD_NAME, OLD_LENGTH).
except that characters matching OLD_CHAR are substituted by NEW_CHAR. except that characters matching OLD_CHAR are substituted by NEW_CHAR.
Also, PREFIX is prepended, and SUFFIX is appended. */ Also, PREFIX is prepended, and SUFFIX is appended. */
......
...@@ -1127,6 +1127,8 @@ extern tree java_signed_type (tree); ...@@ -1127,6 +1127,8 @@ extern tree java_signed_type (tree);
extern tree java_signed_or_unsigned_type (int, tree); extern tree java_signed_or_unsigned_type (int, tree);
extern tree java_truthvalue_conversion (tree); extern tree java_truthvalue_conversion (tree);
extern void add_assume_compiled (const char *, int); 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_class (tree);
extern tree lookup_java_constructor (tree, tree); extern tree lookup_java_constructor (tree, tree);
extern tree lookup_java_method (tree, 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) ...@@ -354,6 +354,22 @@ java_handle_option (size_t scode, const char *arg, int value)
flag_assert = value; flag_assert = value;
break; 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_: case OPT_fassume_compiled_:
add_assume_compiled (arg, !value); add_assume_compiled (arg, !value);
break; break;
......
...@@ -90,6 +90,18 @@ Java ...@@ -90,6 +90,18 @@ Java
fassume-compiled= fassume-compiled=
Java JoinedOrMissing Java JoinedOrMissing
fenable-assertions
Java
fenable-assertions=
Java JoinedOrMissing
fdisable-assertions
Java
fdisable-assertions=
Java JoinedOrMissing
fbootclasspath= fbootclasspath=
Java JoinedOrMissing RejectNegative Java JoinedOrMissing RejectNegative
--bootclasspath=<path> Replace system path --bootclasspath=<path> Replace system path
......
...@@ -13992,25 +13992,32 @@ build_incomplete_class_ref (int location, tree class_name) ...@@ -13992,25 +13992,32 @@ build_incomplete_class_ref (int location, tree class_name)
&& !JPRIMITIVE_TYPE_P (class_name) && !JPRIMITIVE_TYPE_P (class_name)
&& !(TREE_CODE (class_name) == VOID_TYPE)) && !(TREE_CODE (class_name) == VOID_TYPE))
{ {
tree cpc_list = GET_CPC_LIST();
tree cpc = cpc_list;
tree target_class; 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 /* For interfaces, adding a static 'class$' method directly
is illegal. So create an inner class to contain the new is illegal. So create an inner class to contain the new
method. Empirically this matches the behavior of javac. */ method. Empirically this matches the behavior of javac. */
tree t = build_wfl_node (DECL_NAME (TYPE_NAME (object_type_node))); tree t, inner;
tree inner = create_anonymous_class (0, t); /* 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); target_class = TREE_TYPE (inner);
end_class_declaration (1); end_class_declaration (1);
} GET_CPC_LIST() = cpc_list;
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);
} }
if (TYPE_DOT_CLASS (target_class) == NULL_TREE) if (TYPE_DOT_CLASS (target_class) == NULL_TREE)
...@@ -15299,6 +15306,16 @@ build_assertion (int location, tree condition, tree value) ...@@ -15299,6 +15306,16 @@ build_assertion (int location, tree condition, tree value)
tree node; tree node;
tree klass = GET_CPC (); 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)) if (! CLASS_USES_ASSERTIONS (klass))
{ {
tree field, classdollar, id, call; tree field, classdollar, id, call;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment