示例#1
0
文件: check-init.c 项目: aosm/gcc_40
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;
}
示例#2
0
文件: typeck.c 项目: AHelper/gcc
tree
build_java_array_type (tree element_type, HOST_WIDE_INT length)
{
  tree sig, t, fld, atype, arfld;
  char buf[23];
  tree elsig = build_java_signature (element_type);
  tree el_name = element_type;
  buf[0] = '[';
  if (length >= 0)
    sprintf (buf+1, HOST_WIDE_INT_PRINT_DEC, length);
  else
    buf[1] = '\0';
  sig = ident_subst (IDENTIFIER_POINTER (elsig), IDENTIFIER_LENGTH (elsig),
		     buf, 0, 0, "");
  t = IDENTIFIER_SIGNATURE_TYPE (sig);
  if (t != NULL_TREE)
    return TREE_TYPE (t);
  t = make_class ();
  IDENTIFIER_SIGNATURE_TYPE (sig) = build_pointer_type (t);
  TYPE_ARRAY_P (t) = 1;

  if (TREE_CODE (el_name) == POINTER_TYPE)
    el_name = TREE_TYPE (el_name);
  el_name = TYPE_NAME (el_name);
  if (TREE_CODE (el_name) == TYPE_DECL)
    el_name = DECL_NAME (el_name);
  {
    char suffix[23];
    if (length >= 0)
      sprintf (suffix, "[%d]", (int)length); 
    else
      strcpy (suffix, "[]");
    TYPE_NAME (t) 
      = TYPE_STUB_DECL (t)
      = build_decl (input_location, TYPE_DECL,
		    identifier_subst (el_name, "", '.', '.', suffix),
                             t);
    TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (t)) = true;
  }

  set_java_signature (t, sig);
  set_super_info (0, t, object_type_node, 0);
  if (TREE_CODE (element_type) == RECORD_TYPE)
    element_type = promote_type (element_type);
  TYPE_ARRAY_ELEMENT (t) = element_type;

  /* Add length pseudo-field. */
  fld = build_decl (input_location,
		    FIELD_DECL, get_identifier ("length"), int_type_node);
  TYPE_FIELDS (t) = fld;
  DECL_CONTEXT (fld) = t;
  FIELD_PUBLIC (fld) = 1;
  FIELD_FINAL (fld) = 1;
  TREE_READONLY (fld) = 1;

  atype = build_prim_array_type (element_type, length);
  arfld = build_decl (input_location,
		      FIELD_DECL, get_identifier ("data"), atype);
  DECL_CONTEXT (arfld) = t;
  DECL_CHAIN (fld) = arfld;
  DECL_ALIGN (arfld) = TYPE_ALIGN (element_type);

  /* We could layout_class, but that loads java.lang.Object prematurely.
   * This is called by the parser, and it is a bad idea to do load_class
   * in the middle of parsing, because of possible circularity problems. */
  push_super_field (t, object_type_node);
  layout_type (t);

  return t;
}
示例#3
0
文件: check-init.c 项目: aosm/gcc_40
void
check_for_initialization (tree body, tree mdecl)
{
  tree decl;
  word buf[2];
  words before = buf;
  tree owner = DECL_CONTEXT (mdecl);
  int is_static_method = METHOD_STATIC (mdecl);
  /* We don't need to check final fields of <init> it it calls this(). */
  int is_finit_method = DECL_FINIT_P (mdecl) || DECL_INSTINIT_P (mdecl);
  int is_init_method
    = (is_finit_method || DECL_CLINIT_P (mdecl)
       || (DECL_INIT_P (mdecl) && ! DECL_INIT_CALLS_THIS (mdecl)));

  start_current_locals = num_current_locals = 0;
  num_current_words = 2;

  if (is_init_method)
    {
      int words_needed, i;
      for (decl = TYPE_FIELDS (owner);
	   decl != NULL_TREE;  decl = TREE_CHAIN (decl))
	{
	  if (DECL_FINAL (decl) && FIELD_STATIC (decl) == is_static_method)
	    {
	      if (DECL_FIELD_FINAL_IUD (decl))
		DECL_BIT_INDEX (decl) = -1;
	      else
		DECL_BIT_INDEX (decl) = num_current_locals++;
	    }
	}
      words_needed = WORDS_NEEDED (2 * num_current_locals);
      if (words_needed > 2)
	{
	  num_current_words = words_needed;
	  before = ALLOC_WORDS(words_needed);
	}
      i = 0;
      for (decl = TYPE_FIELDS (owner);
	   decl != NULL_TREE;  decl = TREE_CHAIN (decl))
	{
	  if (FIELD_FINAL (decl) && FIELD_STATIC (decl) == is_static_method)
	    {
	      if (! DECL_FIELD_FINAL_IUD (decl))
		{
		  CLEAR_ASSIGNED (before, i);
		  SET_UNASSIGNED (before, i);
		  i++;
		}
	    }
	}

    }

  check_init (body, before);

  if (is_init_method)
    {
      for (decl = TYPE_FIELDS (owner);
	   decl != NULL_TREE;  decl = TREE_CHAIN (decl))
	{
	  if (FIELD_FINAL (decl) && FIELD_STATIC (decl) == is_static_method)
	    {
	      int index = DECL_BIT_INDEX (decl);
	      if (index >= 0 && ! ASSIGNED_P (before, index))
		{
		  if (! is_finit_method)
		    error ("%Jfinal field %qD may not have been initialized",
                           decl, decl);
		}
	      else if (is_finit_method)
		DECL_FIELD_FINAL_IUD (decl) = 1;

	      /* Re-set to initial state, since we later may use the
		 same bit for DECL_POINTER_ALIAS_SET. */
	      DECL_BIT_INDEX (decl) = -1;
	    }
	}
    }

  start_current_locals = num_current_locals = 0;
}
示例#4
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;
}