Пример #1
0
type default_conversion_for_assignment(expression e)
{
  if (type_array(e->type) || type_function(e->type))
    return default_conversion(e);
  else
    return e->type;
}
Пример #2
0
void check_condition(const char *context, expression e)
{
  type etype = default_conversion(e);

  if (etype != error_type && !type_scalar(etype))
    error("%s condition must be scalar", context);
}
Пример #3
0
expression make_dereference(location loc, expression e)
{
  expression result = CAST(expression, new_dereference(parse_region, loc, e));

  result->side_effects = e->side_effects;
  check_dereference(result, default_conversion(e), "unary *");
  result->static_address = e->cst;

  return result;
}
Пример #4
0
expression make_comma(location loc, expression elist)
{
  expression result = CAST(expression, new_comma(parse_region, loc, elist));
  expression e;

  scan_expression (e, elist)
    if (e->next) /* Not last */
      {
#if 0
	if (!e->side_effects)
	  {
	    /* The left-hand operand of a comma expression is like an expression
	       statement: with -W or -Wunused, we should warn if it doesn't have
	       any side-effects, unless it was explicitly cast to (void).  */
	    if ((extra_warnings || warn_unused)
		&& !(TREE_CODE (TREE_VALUE (list)) == CONVERT_EXPR
		      && TREE_TYPE (TREE_VALUE (list)) == void_type_node))
	      warning ("left-hand operand of comma expression has no effect");
	  }
	else if (warn_unused)
	  warn_if_unused_value(e);
#endif
      }
    else
      {
	if (type_array(e->type))
	  result->type = default_conversion(e);
	else
	  result->type = e->type;

	if (!pedantic)
	  {
	    /* XXX: I seemed to believe that , could be a constant expr in GCC,
	       but cst3.c seems to disagree. Check gcc code again ?
	       (It's a bad idea anyway) */
	    result->lvalue = e->lvalue;
	    result->isregister = e->isregister;
	    result->bitfield = e->bitfield;
	  }
      }

  return result;
}
Пример #5
0
struct c_expr
c_parser_binary_expression (c_parser *parser, struct c_expr *after)
{
  /* A binary expression is parsed using operator-precedence parsing,
     with the operands being cast expressions.  All the binary
     operators are left-associative.  Thus a binary expression is of
     form:

     E0 op1 E1 op2 E2 ...

     which we represent on a stack.  On the stack, the precedence
     levels are strictly increasing.  When a new operator is
     encountered of higher precedence than that at the top of the
     stack, it is pushed; its LHS is the top expression, and its RHS
     is everything parsed until it is popped.  When a new operator is
     encountered with precedence less than or equal to that at the top
     of the stack, triples E[i-1] op[i] E[i] are popped and replaced
     by the result of the operation until the operator at the top of
     the stack has lower precedence than the new operator or there is
     only one element on the stack; then the top expression is the LHS
     of the new operator.  In the case of logical AND and OR
     expressions, we also need to adjust skip_evaluation as
     appropriate when the operators are pushed and popped.  */

  /* The precedence levels, where 0 is a dummy lowest level used for
     the bottom of the stack.  */
  enum prec {
    PREC_NONE,
    PREC_LOGOR,
    PREC_LOGAND,
    PREC_BITOR,
    PREC_BITXOR,
    PREC_BITAND,
    PREC_LOGNOT,
    PREC_EQ,
    PREC_REL,
    PREC_SHIFT,
    PREC_ADD,
    PREC_MULT,
    NUM_PRECS
  };
  struct {
    /* The expression at this stack level.  */
    struct c_expr expr;
    /* The precedence of the operator on its left, PREC_NONE at the
       bottom of the stack.  */
    enum prec prec;
    /* The operation on its left.  */
#if 0
    enum tree_code op;
#else
    int op;
#endif
  } stack[NUM_PRECS];
  int sp;
#define POP								      \
  do {									      \
    /*switch (stack[sp].op)						      \
      {									      \
      case TRUTH_ANDIF_EXPR:						      \
	skip_evaluation -= stack[sp - 1].expr.value == truthvalue_false_node; \
	break;								      \
      case TRUTH_ORIF_EXPR:						      \
	skip_evaluation -= stack[sp - 1].expr.value == truthvalue_true_node;  \
	break;								      \
      default:								      \
	break;								      \
	}*/									      \
    stack[sp - 1].expr							      \
      = default_function_array_conversion (stack[sp - 1].expr);		      \
    stack[sp].expr							      \
      = default_function_array_conversion (stack[sp].expr);		      \
    stack[sp - 1].expr = parser_build_binary_op (stack[sp].op,		      \
						 stack[sp - 1].expr,	      \
						 stack[sp].expr);	      \
    sp--;								      \
  } while (0)
#if 0
  gcc_assert (!after || c_dialect_objc ());
#endif
  ;
  stack[0].expr = c_parser_cast_expression (parser, after);
  stack[0].prec = PREC_NONE;
  sp = 0;
  while (true)
    {
      enum prec oprec;
#if 0
      enum tree_code ocode;
#else
      int ocode;
#endif
      if (parser->error)
	goto out;
      switch (c_parser_peek_token (parser)->type)
	{
	case '*':
	case CPP_MULT:
	  oprec = PREC_MULT;
	  ocode = MULT_EXPR;
	  break;
#if 0
	case '/':
	case CPP_DIV:
	  oprec = PREC_MULT;
	  ocode = TRUNC_DIV_EXPR;
	  break;
	case CPP_MOD:
	  oprec = PREC_MULT;
	  ocode = TRUNC_MOD_EXPR;
	  break;
#endif
	case '+':
	case CPP_PLUS:
	  oprec = PREC_ADD;
	  ocode = PLUS_EXPR;
	  break;
	case '-':
	case CPP_MINUS:
	  oprec = PREC_ADD;
	  ocode = MINUS_EXPR;
	  break;
#if 0
	case CPP_LSHIFT:
	  oprec = PREC_SHIFT;
	  ocode = LSHIFT_EXPR;
	  break;
	case CPP_RSHIFT:
	  oprec = PREC_SHIFT;
	  ocode = RSHIFT_EXPR;
	  break;
#endif
	case K_LT:
	case CPP_LESS:
	  oprec = PREC_REL;
	  ocode = LT_EXPR;
	  break;
	case K_GT:
	case CPP_GREATER:
	  oprec = PREC_REL;
	  ocode = GT_EXPR;
	  break;
	case K_LE:
	case CPP_LESS_EQ:
	  oprec = PREC_REL;
	  ocode = LE_EXPR;
	  break;
	case K_GE:
	case CPP_GREATER_EQ:
	  oprec = PREC_REL;
	  ocode = GE_EXPR;
	  break;
	case K_EQ:
	case CPP_EQ_EQ:
	  oprec = PREC_EQ;
	  ocode = EQ_EXPR;
	  break;
	case K_NE:
	case CPP_NOT_EQ:
	  oprec = PREC_EQ;
	  ocode = NE_EXPR;
	  break;
	case K_EQS:
	case K_NES:
	case K_LES:
	case K_LTS:
	case K_GES:
	case K_GTS:
	  oprec = PREC_EQ;
	  ocode = c_parser_peek_token (parser)->type;
	  break;
	case K_AND:
	case CPP_AND:
	  oprec = PREC_BITAND;
	  ocode = BIT_AND_EXPR;
	  break;
	case CPP_XOR:
	  oprec = PREC_BITXOR;
	  ocode = BIT_XOR_EXPR;
	  break;
	case K_OR:
	case CPP_OR:
	  oprec = PREC_BITOR;
	  ocode = BIT_IOR_EXPR;
	  break;
	case CPP_AND_AND:
	  oprec = PREC_LOGAND;
	  ocode = TRUTH_ANDIF_EXPR;
	  break;
	case CPP_OR_OR:
	  oprec = PREC_LOGOR;
	  ocode = TRUTH_ORIF_EXPR;
	  break;
	default:
	  /* Not a binary operator, so end of the binary
	     expression.  */
	  goto out;
	}
      c_parser_consume_token (parser);
      while (oprec <= stack[sp].prec)
	POP;
      switch (ocode)
	{
#if 0
	case TRUTH_ANDIF_EXPR:
	  stack[sp].expr
	    = default_function_array_conversion (stack[sp].expr);
	  stack[sp].expr.value = c_objc_common_truthvalue_conversion
	    (default_conversion (stack[sp].expr.value));
	  skip_evaluation += stack[sp].expr.value == truthvalue_false_node;
	  break;
	case TRUTH_ORIF_EXPR:
	  stack[sp].expr
	    = default_function_array_conversion (stack[sp].expr);
	  stack[sp].expr.value = c_objc_common_truthvalue_conversion
	    (default_conversion (stack[sp].expr.value));
	  skip_evaluation += stack[sp].expr.value == truthvalue_true_node;
	  break;
#endif
	default:
	  break;
	}
      sp++;
      stack[sp].expr = c_parser_cast_expression (parser, NULL);
      stack[sp].prec = oprec;
      stack[sp].op = ocode;
    }
 out:
  while (sp > 0)
    POP;
  return stack[0].expr;
#undef POP
}
Пример #6
0
type check_binary(int binop, expression e1, expression e2)
{
  type t1 = default_conversion(e1), t2 = default_conversion(e2);
  type rtype = NULL;
  bool common = FALSE;

  /* XXX: Misc warnings (see build_binary_op) */
  if (t1 == error_type || t2 == error_type)
    rtype = error_type;
  else switch(binop)
    {
    case kind_plus:
      if (type_pointer(t1) && type_integer(t2))
	rtype = pointer_int_sum(t1, t2);
      else if (type_pointer(t2) && type_integer(t1))
	rtype = pointer_int_sum(t2, t1);
      else
	common = TRUE;
      break;

    case kind_minus: 
      if (type_pointer(t1) && type_integer(t2))
	rtype = pointer_int_sum(t1, t2);
      else if (type_pointer(t1) && type_pointer(t2) &&
	       compatible_pointer_types(t1, t2))
	rtype = ptrdiff_t_type;
      else
	common = TRUE;
      break;

    case kind_plus_assign: case kind_minus_assign:
      if (type_pointer(t1) && type_integer(t2))
	rtype = pointer_int_sum(t1, t2);
      else
	common = TRUE;
      break;

    case kind_times: case kind_divide:
    case kind_times_assign: case kind_divide_assign:
      common = TRUE;
      break;

    case kind_modulo: case kind_bitand: case kind_bitor: case kind_bitxor:
    case kind_lshift: case kind_rshift:
    case kind_modulo_assign: case kind_bitand_assign: case kind_bitor_assign:
    case kind_bitxor_assign: case kind_lshift_assign: case kind_rshift_assign:
      if (type_integer(t1) && type_integer(t2))
	rtype = common_type(t1, t2);
      break;

    case kind_leq: case kind_geq: case kind_lt: case kind_gt:
      rtype = int_type; /* Default to assuming success */
      if (type_real(t1) && type_real(t2))
	;
      else if (type_pointer(t1) && type_pointer(t2))
	{
	  if (compatible_pointer_types(t1, t2))
	    {
	      /* XXX: how can this happen ? */
	      if (type_incomplete(t1) != type_incomplete(t2))
		pedwarn("comparison of complete and incomplete pointers");
	      else if (pedantic && type_function(type_points_to(t1)))
		pedwarn("ANSI C forbids ordered comparisons of pointers to functions");
	    }
	  else
	    pedwarn("comparison of distinct pointer types lacks a cast");
	}
      /* XXX: Use of definite_zero may lead to extra warnings when !extra_warnings */
      else if ((type_pointer(t1) && definite_zero(e2)) ||
	       (type_pointer(t2) && definite_zero(e1)))
	{
	  if (pedantic || extra_warnings)
	    pedwarn("ordered comparison of pointer with integer zero");
	}
      else if ((type_pointer(t1) && type_integer(t2)) ||
	       (type_pointer(t2) && type_integer(t1)))
	{
	  if (!flag_traditional)
	    pedwarn("comparison between pointer and integer");
	}
      else
	rtype = NULL; /* Force error */
      break;

    case kind_eq: case kind_ne:
      rtype = int_type; /* Default to assuming success */
      if (type_arithmetic(t1) && type_arithmetic(t2))
	;
      else if (type_pointer(t1) && type_pointer(t2))
	{
	  if (!compatible_pointer_types(t1, t2) &&
	      !valid_compare(t1, t2, e1) &&
	      !valid_compare(t2, t1, e2))
	    pedwarn("comparison of distinct pointer types lacks a cast");
	}
      else if ((type_pointer(t1) && definite_null(e2)) ||
	       (type_pointer(t2) && definite_null(e1)))
	;
      else if ((type_pointer(t1) && type_integer(t2)) ||
	       (type_pointer(t2) && type_integer(t1)))
	{
	  if (!flag_traditional)
	    pedwarn("comparison between pointer and integer");
	}
      else
	rtype = NULL; /* Force error */
      break;

    case kind_andand: case kind_oror:
      if (type_scalar(t1) && type_scalar(t2))
	rtype = int_type;
      break;

    default: assert(0); break;
    }

  if (common && type_arithmetic(t1) && type_arithmetic(t2))
    rtype = common_type(t1, t2);

  if (!rtype)
    {
      error("invalid operands to binary %s", binary_op_name(binop));
      rtype = error_type;
    }

  return rtype;
}
Пример #7
0
expression make_cast(location loc, asttype t, expression e)
{
  expression result = CAST(expression, new_cast(parse_region, loc, e, t));
  type castto = t->type;
  
  if (castto == error_type || type_void(castto))
    ; /* Do nothing */
  else if (type_array(castto))
    {
      error("cast specifies array type");
      castto = error_type;
    }
  else if (type_function(castto))
    {
      error("cast specifies function type");
      castto = error_type;
    }
  else if (type_equal_unqualified(castto, e->type))
    {
      if (pedantic && type_aggregate(castto))
	pedwarn("ANSI C forbids casting nonscalar to the same type");
    }
  else
    {
      type etype = e->type;

      /* Convert functions and arrays to pointers,
	 but don't convert any other types.  */
      if (type_function(etype) || type_array(etype))
	etype = default_conversion(e);

      if (type_union(castto))
	{
	  tag_declaration utag = type_tag(castto);
	  field_declaration ufield;

	  /* Look for etype as a field of the union */
	  for (ufield = utag->fieldlist; ufield; ufield = ufield->next)
	    if (ufield->name && type_equal_unqualified(ufield->type, etype))
	      {
		if (pedantic)
		  pedwarn("ANSI C forbids casts to union type");
		break;
	      }
	  if (!ufield)
	    error("cast to union type from type not present in union");
	}
      else 
	{
	  /* Optionally warn about potentially worrisome casts.  */

	  if (warn_cast_qual && type_pointer(etype) && type_pointer(castto))
	    {
	      type ep = type_points_to(etype), cp = type_points_to(castto);

	      if (type_volatile(ep) && !type_volatile(cp))
		pedwarn("cast discards `volatile' from pointer target type");
	      if (type_const(ep) && !type_const(cp))
		pedwarn("cast discards `const' from pointer target type");
	    }

	  /* This warning is weird */
	  if (warn_bad_function_cast && is_function_call(e) &&
	      !type_equal_unqualified(castto, etype))
	    warning ("cast does not match function type");

#if 0
	  /* Warn about possible alignment problems.  */
	  if (STRICT_ALIGNMENT && warn_cast_align
	      && TREE_CODE (type) == POINTER_TYPE
	      && TREE_CODE (otype) == POINTER_TYPE
	      && TREE_CODE (TREE_TYPE (otype)) != VOID_TYPE
	      && TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE
	      /* Don't warn about opaque types, where the actual alignment
		 restriction is unknown.  */
	      && !((TREE_CODE (TREE_TYPE (otype)) == UNION_TYPE
		    || TREE_CODE (TREE_TYPE (otype)) == RECORD_TYPE)
		   && TYPE_MODE (TREE_TYPE (otype)) == VOIDmode)
	      && TYPE_ALIGN (TREE_TYPE (type)) > TYPE_ALIGN (TREE_TYPE (otype)))
	    warning ("cast increases required alignment of target type");

	  if (TREE_CODE (type) == INTEGER_TYPE
	      && TREE_CODE (otype) == POINTER_TYPE
	      && TYPE_PRECISION (type) != TYPE_PRECISION (otype)
	      && !TREE_CONSTANT (value))
	    warning ("cast from pointer to integer of different size");

	  if (TREE_CODE (type) == POINTER_TYPE
	      && TREE_CODE (otype) == INTEGER_TYPE
	      && TYPE_PRECISION (type) != TYPE_PRECISION (otype)
#if 0
	      /* Don't warn about converting 0 to pointer,
		 provided the 0 was explicit--not cast or made by folding.  */
	      && !(TREE_CODE (value) == INTEGER_CST && integer_zerop (value))
#endif
	      /* Don't warn about converting any constant.  */
	      && !TREE_CONSTANT (value))
	    warning ("cast to pointer from integer of different size");
#endif

	  check_conversion(castto, etype);
	}
    }

  result->lvalue = !pedantic && e->lvalue;
  result->isregister = e->isregister;
  result->bitfield = e->bitfield;
  result->static_address = e->static_address;
  result->type = castto;
  result->cst = fold_cast(result);

  return result;
}
Пример #8
0
expression make_unary(location loc, int unop, expression e)
{
  switch (unop)
    {
    case kind_address_of:
      return make_address_of(loc, e);
    case kind_preincrement:
      return make_preincrement(loc, e);
    case kind_predecrement:
      return make_predecrement(loc, e);
    default:
      {
	expression result = CAST(expression, newkind_unary(parse_region, unop, loc, e));
	type etype = default_conversion(e);
	const char *errstring = NULL;

	if (etype == error_type)
	  result->type = error_type;
	else
	  {
	    switch (unop)
	      {
	      case kind_unary_plus:
		if (!type_arithmetic(etype))
		  errstring = "wrong type argument to unary plus";
		break;
	      case kind_unary_minus:
		if (!type_arithmetic(etype))
		  errstring = "wrong type argument to unary minus";
		break;
	      case kind_bitnot:
		if (type_complex(etype))
		  result->kind = kind_conjugate;
		else if (!type_integer(etype))
		  errstring = "wrong type argument to bit-complement";
		break;
	      case kind_not:
		if (!type_scalar(etype))
		  errstring = "wrong type argument to unary exclamation mark";
		else
		  etype = int_type;
		break;
	      case kind_realpart: case kind_imagpart:
		if (!type_arithmetic(etype))
		  if (unop == kind_realpart)
		    errstring = "wrong type argument to __real__";
		  else
		    errstring = "wrong type argument to __imag__";
		else
		  etype = type_complex(etype) ? make_base_type(etype) : etype;
	      default:
		assert(0);
	      }
	    if (errstring)
	      {
		error(errstring);
		result->type = error_type;
	      }
	    else
	      {
		result->type = etype;
		result->cst = fold_unary(result);
	      }
	  }
	return result;
      }
    }
}
Пример #9
0
      if (!definite_zero(e2))
	pedwarn("pointer/integer type mismatch in conditional expression");
      return TRUE;
    }
  return FALSE;
}

expression make_conditional(location loc, expression cond,
			    expression true, expression false)
{
  expression result =
    CAST(expression, new_conditional(parse_region, loc, cond, true, false));
  type ctype, ttype, ftype, rtype = NULL;
  bool truelvalue = true ? true->lvalue : FALSE;

  ctype = default_conversion(cond);

  if (!true)
    {
      true = cond;
      truelvalue = FALSE; /* Not an lvalue in gcc ! */
    }

  if (type_void(true->type))
    ttype = true->type;
  else
    ttype = default_conversion(true);
  
  if (type_void(false->type))
    ftype = false->type;
  else
Пример #10
0
static expression build_taskid(module m, data_declaration taskdecl)
{
  /* Build a unique identifier for a task whose declaration is taskdecl,
     in module m.
     Method: we add enum { m$taskdecl = unique("task-unique-string") };
             to all_cdecls
	     and return an identifier-expression referring to m$taskdecl
  */

  location loc = taskdecl->ast->location;
  region r = parse_region;
  cstring idname;
  enumerator idast;
  struct data_declaration tempdecl;
  enum_ref idenum;
  tag_declaration enumdecl;
  data_decl iddecl;
  expression unique_id, unique_fn, unique_args, use_id;
  cstring silly_name;
  identifier_declarator silly_id;
  declarator silly_d;
  type_element silly_modifiers;
  rid silly_typedef;
  type silly_type;
  variable_decl silly_vd;
  data_decl silly_decl;

  /* Build unique("task-unique-string") */
  unique_fn = build_identifier(r, loc, magic_unique);
  unique_args = build_string(r, loc, scheduler_unique_name);
  default_conversion(unique_args);
  unique_id = build_function_call(r, loc, unique_fn, unique_args);

  /* Build, declare enumerator taskdecl */
  idname = str2cstring(r, taskdecl->name);
  idast = new_enumerator(r, loc, idname, unique_id, NULL);
  init_data_declaration(&tempdecl, CAST(declaration, idast), idname.data,
			int_type);
  tempdecl.kind = decl_constant;
  tempdecl.definition = tempdecl.ast;
  tempdecl.value = unique_id->cst;
  idast->ddecl = declare(m->ienv, &tempdecl, FALSE);

  /* Build the enum declaration */
  idenum = new_enum_ref(r, loc, NULL, NULL, NULL, TRUE);
  idenum->fields = CAST(declaration, idast);
  idenum->tdecl = enumdecl = declare_tag(idenum);
  layout_enum_start(enumdecl);
  enumdecl->definition = idenum;
  enumdecl->defined = TRUE;
  layout_enum_end(enumdecl);

  /* Build the expression we will use in the wiring. */
  use_id = build_identifier(r, loc, idast->ddecl);

  /* Hack: the use_id expression needs to be in the module's AST so
     that we do instantiation and constant folding on it. We build
     a silly typedef for that purpose:
       typedef int __nesc_sillytask_taskdecl[use_id]
  */
  silly_name = alloc_cstring(r, strlen(taskdecl->name) + 17);
  sprintf(silly_name.data, "__nesc_sillytask_%s", taskdecl->name);
  silly_id = new_identifier_declarator(r, loc, silly_name);
  silly_type = make_array_type(int_type, use_id);
  type2ast(r, loc, silly_type, CAST(declarator, silly_id), 
	   &silly_d, &silly_modifiers);

  silly_typedef = new_rid(r, loc, RID_TYPEDEF);

  silly_vd = new_variable_decl(r, loc, silly_d, NULL, NULL, NULL,
			       NULL/*ddecl*/);
  init_data_declaration(&tempdecl, CAST(declaration, silly_vd),
			silly_name.data, silly_type);
  tempdecl.kind = decl_typedef;
  tempdecl.definition = tempdecl.ast;
  silly_vd->ddecl = declare(m->ienv, &tempdecl, FALSE);
  silly_vd->declared_type = silly_type;
  silly_decl =
    new_data_decl(r, loc, type_element_chain(CAST(type_element, silly_typedef),
					     silly_modifiers),
		  CAST(declaration, silly_vd));
  m->decls = declaration_chain(CAST(declaration, silly_decl), m->decls);

  /* Build the declaration and add it to the module's decls */
  iddecl = new_data_decl(r, loc, CAST(type_element, idenum), NULL);
  m->decls = declaration_chain(CAST(declaration, iddecl), m->decls);

  return use_id;
}