aboutsummaryrefslogtreecommitdiff
path: root/gcc/java/parse.y
diff options
context:
space:
mode:
authorAlexandre Petit-Bianco <apbianco@cygnus.com>2000-06-01 05:54:26 +0000
committerAlexandre Petit-Bianco <apbianco@gcc.gnu.org>2000-05-31 22:54:26 -0700
commit92d8351549902259fb219f089e37f4cde3aec9a8 (patch)
tree6cf542ccff05777410e2360cd160b2c2e8fff490 /gcc/java/parse.y
parent64cdd351dda48323a0a04beda01757e8b2bcbb7f (diff)
downloadgcc-92d8351549902259fb219f089e37f4cde3aec9a8.zip
gcc-92d8351549902259fb219f089e37f4cde3aec9a8.tar.gz
gcc-92d8351549902259fb219f089e37f4cde3aec9a8.tar.bz2
parse.y (maybe_yank_clinit): New function.
2000-04-17 Alexandre Petit-Bianco <apbianco@cygnus.com> * parse.y (maybe_yank_clinit): New function. (maybe_generate_pre_expand_clinit): Always link <clinit> at the end of the list of methods belonging to a class. (java_complete_expand_method): Check whether <clinit> is really necessary and expand it accordingly. From-SVN: r34329
Diffstat (limited to 'gcc/java/parse.y')
-rw-r--r--gcc/java/parse.y80
1 files changed, 68 insertions, 12 deletions
diff --git a/gcc/java/parse.y b/gcc/java/parse.y
index 0681e84..e14ec75 100644
--- a/gcc/java/parse.y
+++ b/gcc/java/parse.y
@@ -136,6 +136,7 @@ static tree obtain_incomplete_type PARAMS ((tree));
static tree java_complete_lhs PARAMS ((tree));
static tree java_complete_tree PARAMS ((tree));
static tree maybe_generate_pre_expand_clinit PARAMS ((tree));
+static int maybe_yank_clinit PARAMS ((tree));
static void java_complete_expand_method PARAMS ((tree));
static int unresolved_type_p PARAMS ((tree, tree *));
static void create_jdep_list PARAMS ((struct parser_ctxt *));
@@ -7387,17 +7388,17 @@ maybe_generate_pre_expand_clinit (class_type)
end_artificial_method_body (mdecl);
- /* Now we want to place <clinit> as the last method for interface so
- that it doesn't interfere with the dispatch table based
- lookup. */
- if (CLASS_INTERFACE (TYPE_NAME (class_type))
- && TREE_CHAIN (TYPE_METHODS (class_type)))
+ /* Now we want to place <clinit> as the last method (because we need
+ it at least for interface so that it doesn't interfere with the
+ dispatch table based lookup. */
+ if (TREE_CHAIN (TYPE_METHODS (class_type)))
{
- tree current =
- TYPE_METHODS (class_type) = TREE_CHAIN (TYPE_METHODS (class_type));
+ current = TREE_CHAIN (TYPE_METHODS (class_type));
+ TYPE_METHODS (class_type) = current;
while (TREE_CHAIN (current))
current = TREE_CHAIN (current);
+
TREE_CHAIN (current) = mdecl;
TREE_CHAIN (mdecl) = NULL_TREE;
}
@@ -7405,12 +7406,63 @@ maybe_generate_pre_expand_clinit (class_type)
return mdecl;
}
+/* See whether we could get rid of <clinit>. Criteria are: all static
+ final fields have constant initial values and the body of <clinit>
+ is empty. Return 1 if <clinit> was discarded, 0 otherwise. */
+
+static int
+maybe_yank_clinit (mdecl)
+ tree mdecl;
+{
+ tree type, current;
+ tree fbody, bbody;
+
+ if (!DECL_CLINIT_P (mdecl))
+ return 0;
+
+ /* If the body isn't empty, then we keep <clinit> */
+ fbody = DECL_FUNCTION_BODY (mdecl);
+ if ((bbody = BLOCK_EXPR_BODY (fbody)))
+ bbody = BLOCK_EXPR_BODY (bbody);
+ if (bbody && bbody != empty_stmt_node)
+ return 0;
+
+ type = DECL_CONTEXT (mdecl);
+ current = TYPE_FIELDS (type);
+
+ for (current = (current ? TREE_CHAIN (current) : current);
+ current; current = TREE_CHAIN (current))
+ if (!(FIELD_STATIC (current) && FIELD_FINAL (current)
+ && DECL_INITIAL (current) && TREE_CONSTANT (DECL_INITIAL (current))))
+ break;
+
+ if (current)
+ return 0;
+
+ /* Get rid of <clinit> in the class' list of methods */
+ if (TYPE_METHODS (type) == mdecl)
+ TYPE_METHODS (type) = TREE_CHAIN (mdecl);
+ else
+ for (current = TYPE_METHODS (type); current;
+ current = TREE_CHAIN (current))
+ if (TREE_CHAIN (current) == mdecl)
+ {
+ TREE_CHAIN (current) = TREE_CHAIN (mdecl);
+ break;
+ }
+
+ return 1;
+}
+
+
/* Complete and expand a method. */
static void
java_complete_expand_method (mdecl)
tree mdecl;
{
+ int yank_clinit = 0;
+
current_function_decl = mdecl;
/* Fix constructors before expanding them */
if (DECL_CONSTRUCTOR_P (mdecl))
@@ -7459,15 +7511,19 @@ java_complete_expand_method (mdecl)
&& !flag_emit_xref)
missing_return_error (current_function_decl);
- complete_start_java_method (mdecl);
-
+ /* Check wether we could just get rid of clinit, now the picture
+ is complete. */
+ if (!(yank_clinit = maybe_yank_clinit (mdecl)))
+ complete_start_java_method (mdecl);
+
/* Don't go any further if we've found error(s) during the
- expansion */
- if (!java_error_count)
+ expansion */
+ if (!java_error_count && !yank_clinit)
source_end_java_method ();
else
{
- pushdecl_force_head (DECL_ARGUMENTS (mdecl));
+ if (java_error_count)
+ pushdecl_force_head (DECL_ARGUMENTS (mdecl));
poplevel (1, 0, 1);
}