class.c (assume_compiled_node_struct): Rename type to class_flag_node_struct, as...
authorPer Bothner <per@bothner.com>
Fri, 19 Mar 2004 23:10:55 +0000 (15:10 -0800)
committerPer Bothner <bothner@gcc.gnu.org>
Fri, 19 Mar 2004 23:10:55 +0000 (15:10 -0800)
* 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
gcc/java/class.c
gcc/java/java-tree.h
gcc/java/lang.c
gcc/java/lang.opt
gcc/java/parse.y

index 39e3aef3b00d50306e3ca3938bd141e00f0500b9..0c73353188dd7d1fe7b96e3d48be890598bdfc8c 100644 (file)
@@ -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
index be9958b31e4e172999250e383e6981a272756a80..dc1659cf5ee5850a90a020bb33309ad38c43907e 100644 (file)
@@ -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. */
index 57931b8d16e3dbd2f615904f7de600c3f1347f25..169f0ad4007213fd23c07b497b2c39c1de91f3b6 100644 (file)
@@ -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);
index 0fe68def937ede453a09f124c0d23e4c93a3f27a..20afb504e7268569087be8e86cb4892be463dad5 100644 (file)
@@ -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;
index 987eb82e444147415ab379d3598266fb4a1fb0db..3e9cdf1250a0a5ca38de69819374abd6bbb65b59 100644 (file)
@@ -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
index 049e50b08ffb024ff8d720439503771b1dde0da4..a21fc2a09195edc132ec7e41e62f81b0e95221dc 100644 (file)
@@ -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;