Esempio n. 1
0
static tree
get_variable_decl (tree exp)
{
  if (TREE_CODE (exp) == VAR_DECL)
    {
      if (! TREE_STATIC (exp) ||  FIELD_FINAL (exp))
	return exp;
    }
  /* We only care about final parameters. */
  else if (TREE_CODE (exp) == PARM_DECL)
    {
      if (DECL_FINAL (exp))
	return exp;
    }
  /* See if exp is this.field. */
  else if (TREE_CODE (exp) == COMPONENT_REF)
    {
      tree op0 = TREE_OPERAND (exp, 0);
      tree op1 = TREE_OPERAND (exp, 1);
      tree mdecl = current_function_decl;
      if (TREE_CODE (op0) == INDIRECT_REF
	  && TREE_CODE (op1) == FIELD_DECL
	  && ! METHOD_STATIC (mdecl)
	  && FIELD_FINAL (op1))
	{
	  op0 = TREE_OPERAND (op0, 0);
	  if (op0 == BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl)))
	    return op1;
	}
    }
  return NULL_TREE;
}
Esempio n. 2
0
static tree
get_variable_decl (tree exp)
{
  /* A static field can be wrapped in a COMPOUND_EXPR where the first
     argument initializes the class.  */
  if (TREE_CODE (exp) == COMPOUND_EXPR)
    exp = extract_field_decl (exp);

  if (TREE_CODE (exp) == VAR_DECL)
    {
      if (! TREE_STATIC (exp) ||  FIELD_FINAL (exp))
	return exp;
    }
  /* We only care about final parameters. */
  else if (TREE_CODE (exp) == PARM_DECL)
    {
      if (DECL_FINAL (exp))
	return exp;
    }
  /* See if exp is this.field. */
  else if (TREE_CODE (exp) == COMPONENT_REF)
    {
      tree op0 = TREE_OPERAND (exp, 0);
      tree op1 = TREE_OPERAND (exp, 1);
      tree mdecl = current_function_decl;
      if (TREE_CODE (op0) == INDIRECT_REF
	  && TREE_CODE (op1) == FIELD_DECL
	  && ! METHOD_STATIC (mdecl)
	  && FIELD_FINAL (op1))
	{
	  op0 = TREE_OPERAND (op0, 0);
	  if (op0 == BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl)))
	    return op1;
	}
    }
  else if (TREE_CODE (exp) == INDIRECT_REF)
    {
      /* For indirect dispatch, look for an expression of the form 
      (indirect_ref (+ (array_ref otable <N>) this)).  
      FIXME: it would probably be better to generate a JAVA_FIELD_REF
      expression that gets converted to OTABLE access at
      gimplification time.  */
      exp = TREE_OPERAND (exp, 0);
      if (TREE_CODE (exp) == PLUS_EXPR)
	{
	  tree op0 = TREE_OPERAND (exp, 0);
	  STRIP_NOPS (op0);
	  if (TREE_CODE (op0) == ARRAY_REF)
	    {
	      tree table = TREE_OPERAND (op0, 0);
	      if (TREE_CODE (table) == VAR_DECL
		  && DECL_LANG_SPECIFIC (table)
		  && DECL_OWNER (table) 
		  && TYPE_OTABLE_DECL (DECL_OWNER (table)) == table)
		{
		  HOST_WIDE_INT index 
		    = TREE_INT_CST_LOW (TREE_OPERAND (op0, 1));
		  tree otable_methods 
		    = TYPE_OTABLE_METHODS (DECL_OWNER (table));
		  tree element;
		  for (element = otable_methods; 
		       element; 
		       element = TREE_CHAIN (element))
		    {
		      if (index == 1)
			{
			  tree purpose = TREE_PURPOSE (element);
			  if (TREE_CODE (purpose) == FIELD_DECL)
			    return purpose;
			  else
			    return NULL_TREE;
			}
		      --index;
		    }
		}
	    }
	}
    }

  return NULL_TREE;
}