Exemplo n.º 1
0
bool
is_gimple_min_lval (tree t)
{
  if (!(t = CONST_CAST_TREE (strip_invariant_refs (t))))
    return false;
  return (is_gimple_id (t) || TREE_CODE (t) == MEM_REF);
}
Exemplo n.º 2
0
static tree
fold_cplus_constants (const_tree c)
{
  tree folded_elems, elems = CONST_CAST_TREE (c);
  int vec_len, i;

  if (elems == NULL_TREE || elems == error_mark_node)
    return elems;

  vec_len = TREE_VEC_LENGTH (elems);

  /* First check if there is at least one element that needs
     folding. If there is none, we just return ELEMS. Otherwise create
     and return a new tree vector that contains the folded versions of
     ELEMS. This is to avoid allocating memory if we don't need
     to.  */
  for (i = 0; i < vec_len; ++i)
    {
      if (template_arg_needs_folding (TREE_VEC_ELT (elems, i)))
	break;
    }
  if (i == vec_len)
    return elems;

  folded_elems = make_tree_vec (vec_len);
  for (i = 0; i < vec_len; ++i)
    {
      tree elem = TREE_VEC_ELT (elems, i);
      TREE_VEC_ELT (folded_elems, i) =  
	(elem && !TYPE_P (elem)) ? cplus_expand_constant (elem) : elem;

    }
  return folded_elems;
}
Exemplo n.º 3
0
tree
cp_get_debug_type (const_tree type)
{
  tree dtype = NULL_TREE;

  if (TYPE_PTRMEMFUNC_P (type) && !typedef_variant_p (type))
    dtype = build_offset_type (TYPE_PTRMEMFUNC_OBJECT_TYPE (type),
			       TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (type)));

  /* We cannot simply return the debug type here because the function uses
     the type canonicalization hashtable, which is GC-ed, so its behavior
     depends on the actual collection points.  Since we are building these
     types on the fly for the debug info only, they would not be attached
     to any GC root and always be swept, so we would make the contents of
     the debug info depend on the collection points.  */
  if (dtype)
    {
      tree ktype = CONST_CAST_TREE (type);
      if (debug_type_map == NULL)
	debug_type_map = tree_cache_map::create_ggc (512);
      else if (tree *slot = debug_type_map->get (ktype))
	return *slot;
      debug_type_map->put (ktype, dtype);
    }

  return dtype;
}
Exemplo n.º 4
0
bool
block_may_fallthru (const_tree block)
{
  /* This CONST_CAST is okay because expr_last returns its argument
     unmodified and we assign it to a const_tree.  */
  const_tree stmt = expr_last (CONST_CAST_TREE(block));

  switch (stmt ? TREE_CODE (stmt) : ERROR_MARK)
    {
    case GOTO_EXPR:
    case RETURN_EXPR:
      /* Easy cases.  If the last statement of the block implies
	 control transfer, then we can't fall through.  */
      return false;

    case SWITCH_EXPR:
      /* If SWITCH_LABELS is set, this is lowered, and represents a
	 branch to a selected label and hence can not fall through.
	 Otherwise SWITCH_BODY is set, and the switch can fall
	 through.  */
      return SWITCH_LABELS (stmt) == NULL_TREE;

    case COND_EXPR:
      if (block_may_fallthru (COND_EXPR_THEN (stmt)))
	return true;
      return block_may_fallthru (COND_EXPR_ELSE (stmt));

    case BIND_EXPR:
      return block_may_fallthru (BIND_EXPR_BODY (stmt));

    case TRY_CATCH_EXPR:
      return try_catch_may_fallthru (stmt);

    case TRY_FINALLY_EXPR:
      /* The finally clause is always executed after the try clause,
	 so if it does not fall through, then the try-finally will not
	 fall through.  Otherwise, if the try clause does not fall
	 through, then when the finally clause falls through it will
	 resume execution wherever the try clause was going.  So the
	 whole try-finally will only fall through if both the try
	 clause and the finally clause fall through.  */
      return (block_may_fallthru (TREE_OPERAND (stmt, 0))
	      && block_may_fallthru (TREE_OPERAND (stmt, 1)));

    case MODIFY_EXPR:
      if (TREE_CODE (TREE_OPERAND (stmt, 1)) == CALL_EXPR)
	stmt = TREE_OPERAND (stmt, 1);
      else
	return true;
      /* FALLTHRU */

    case CALL_EXPR:
      /* Functions that do not return do not fall through.  */
      return (call_expr_flags (stmt) & ECF_NORETURN) == 0;

    case CLEANUP_POINT_EXPR:
      return block_may_fallthru (TREE_OPERAND (stmt, 0));

    case TARGET_EXPR:
      return block_may_fallthru (TREE_OPERAND (stmt, 1));

    case ERROR_MARK:
      return true;

    default:
      return lang_hooks.block_may_fallthru (stmt);
    }
}
Exemplo n.º 5
0
void
print_mem_expr (FILE *outfile, const_tree expr)
{
  fputc (' ', outfile);
  print_generic_expr (outfile, CONST_CAST_TREE (expr), dump_flags);
}
Exemplo n.º 6
0
static tree
compute_object_offset (const_tree expr, const_tree var)
{
  enum tree_code code = PLUS_EXPR;
  tree base, off, t;

  if (expr == var)
    return size_zero_node;

  switch (TREE_CODE (expr))
    {
    case COMPONENT_REF:
      base = compute_object_offset (TREE_OPERAND (expr, 0), var);
      if (base == error_mark_node)
	return base;

      t = TREE_OPERAND (expr, 1);
      off = size_binop (PLUS_EXPR, DECL_FIELD_OFFSET (t),
			size_int (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (t))
				  / BITS_PER_UNIT));
      break;

    case REALPART_EXPR:
    CASE_CONVERT:
    case VIEW_CONVERT_EXPR:
    case NON_LVALUE_EXPR:
      return compute_object_offset (TREE_OPERAND (expr, 0), var);

    case IMAGPART_EXPR:
      base = compute_object_offset (TREE_OPERAND (expr, 0), var);
      if (base == error_mark_node)
	return base;

      off = TYPE_SIZE_UNIT (TREE_TYPE (expr));
      break;

    case ARRAY_REF:
      base = compute_object_offset (TREE_OPERAND (expr, 0), var);
      if (base == error_mark_node)
	return base;

      t = TREE_OPERAND (expr, 1);
      tree low_bound, unit_size;
      low_bound = array_ref_low_bound (CONST_CAST_TREE (expr));
      unit_size = array_ref_element_size (CONST_CAST_TREE (expr));
      if (! integer_zerop (low_bound))
	t = fold_build2 (MINUS_EXPR, TREE_TYPE (t), t, low_bound);
      if (TREE_CODE (t) == INTEGER_CST && tree_int_cst_sgn (t) < 0)
	{
	  code = MINUS_EXPR;
	  t = fold_build1 (NEGATE_EXPR, TREE_TYPE (t), t);
	}
      t = fold_convert (sizetype, t);
      off = size_binop (MULT_EXPR, unit_size, t);
      break;

    case MEM_REF:
      gcc_assert (TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR);
      return wide_int_to_tree (sizetype, mem_ref_offset (expr));

    default:
      return error_mark_node;
    }

  return size_binop (code, base, off);
}