gcj/131

Alexandre Petit-Bianco apbianco@cygnus.com
Wed Apr 19 20:50:00 GMT 2000


The following reply was made to PR gcj/131; it has been noted by GNATS.

From: Alexandre Petit-Bianco <apbianco@cygnus.com>
To: java-gnats@sourceware.cygnus.com
Cc:  
Subject: Re: gcj/131
Date: Wed, 19 Apr 2000 20:42:12 -0700 (PDT)

 Alexandre Petit-Bianco writes:
 >  Oops. The patch triggered regressions. Here's a new patch.
 
 Maybe someday I'll get it right. Third patch.
 
 ./A
 
 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.
 	(fold_constant_for_init): Let VAR_DECL and FIELD_DECL be processed
 	by the method's switch statement.
 
 Index: parse.y
 ===================================================================
 RCS file: /cvs/gcc/egcs/gcc/java/parse.y,v
 retrieving revision 1.152
 diff -u -p -r1.152 parse.y
 --- parse.y	2000/04/20 02:52:26	1.152
 +++ parse.y	2000/04/20 03:38:46
 @@ -136,6 +136,7 @@ static tree obtain_incomplete_type PARAM
  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 *));
 @@ -7343,17 +7344,17 @@ maybe_generate_pre_expand_clinit (class_
  
    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;
      }
 @@ -7361,12 +7362,63 @@ maybe_generate_pre_expand_clinit (class_
    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))
 @@ -7414,15 +7466,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);
  	}
  
 @@ -14529,8 +14585,6 @@ fold_constant_for_init (node, context)
  
    if (code == INTEGER_CST || code == REAL_CST)
      return convert (TREE_TYPE (context), node);
 -  if (TREE_TYPE (node) != NULL_TREE && code != VAR_DECL && code != FIELD_DECL)
 -    return NULL_TREE;
  
    switch (code)
      {


More information about the Java-prs mailing list