From 24d82bce7ab29c1616b961d79f676bb08d339719 Mon Sep 17 00:00:00 2001 From: Per Bothner Date: Fri, 19 Mar 2004 15:10:55 -0800 Subject: [PATCH] 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 --- gcc/java/ChangeLog | 20 ++++++ gcc/java/class.c | 141 ++++++++++++++++++++++++++++--------------- gcc/java/java-tree.h | 2 + gcc/java/lang.c | 16 +++++ gcc/java/lang.opt | 12 ++++ gcc/java/parse.y | 39 ++++++++---- 6 files changed, 170 insertions(+), 60 deletions(-) diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 39e3aef3b00..0c73353188d 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,23 @@ +2004-03-19 Per Bothner + + * 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 * java-tree.h: Changes throughout to add checking to macros diff --git a/gcc/java/class.c b/gcc/java/class.c index be9958b31e4..dc1659cf5ee 100644 --- a/gcc/java/class.c +++ b/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. */ diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h index 57931b8d16e..169f0ad4007 100644 --- a/gcc/java/java-tree.h +++ b/gcc/java/java-tree.h @@ -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); diff --git a/gcc/java/lang.c b/gcc/java/lang.c index 0fe68def937..20afb504e72 100644 --- a/gcc/java/lang.c +++ b/gcc/java/lang.c @@ -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; diff --git a/gcc/java/lang.opt b/gcc/java/lang.opt index 987eb82e444..3e9cdf1250a 100644 --- a/gcc/java/lang.opt +++ b/gcc/java/lang.opt @@ -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= Replace system path diff --git a/gcc/java/parse.y b/gcc/java/parse.y index 049e50b08ff..a21fc2a0919 100644 --- a/gcc/java/parse.y +++ b/gcc/java/parse.y @@ -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; -- 2.30.2