Пример #1
0
ast_t* control_type_add_branch(ast_t* control_type, ast_t* branch)
{
  assert(branch != NULL);

  ast_t* branch_type = ast_type(branch);

  if(is_typecheck_error(branch_type))
    return branch_type;

  if(is_type_literal(branch_type))
  {
    // The new branch is a literal
    if(control_type == NULL)
      control_type = ast_from(branch, TK_LITERAL);

    if(ast_id(control_type) != TK_LITERAL)
    {
      // The current control type is not a literal, fix that
      ast_t* old_control = control_type;
      control_type = ast_from(branch, TK_LITERAL);
      ast_settype(control_type, old_control);
    }

    assert(ast_id(control_type) == TK_LITERAL);

    // Add a literal branch reference to the new branch
    ast_t* member = ast_from(branch, TK_LITERALBRANCH);
    ast_setdata(member, (void*)branch);
    ast_append(control_type, member);

    ast_t* branch_non_lit = ast_type(branch_type);

    if(branch_non_lit != NULL)
    {
      // The branch's literal type has a non-literal component
      ast_t* non_literal_type = ast_type(control_type);
      ast_settype(control_type, type_union(non_literal_type, branch_non_lit));
    }

    return control_type;
  }

  if(control_type != NULL && ast_id(control_type) == TK_LITERAL)
  {
    // New branch is not literal, but the control structure is
    // Add new branch type to the control structure's non-literal aspect
    ast_t* non_literal_type = ast_type(control_type);
    non_literal_type = type_union(non_literal_type, branch_type);
    ast_settype(control_type, non_literal_type);
    return control_type;
  }

  // No literals here, just union the types
  return type_union(control_type, branch_type);
}
Пример #2
0
static void incomplete_type_error(expression e, type t)
{
  /* Avoid duplicate error message.  */
  if (t == error_type)
    return;

  if (e && is_identifier(e))
    error("`%s' has an incomplete type", CAST(identifier, e)->cstring.data);
  else
    {
      while (type_array(t) && type_array_size(t))
	t = type_array_of(t);

      if (type_struct(t))
	error("invalid use of undefined type `struct %s'", type_tag(t)->name);
      else if (type_union(t))
	error("invalid use of undefined type `union %s'", type_tag(t)->name);
      else if (type_enum(t))
	error("invalid use of undefined type `enum %s'", type_tag(t)->name);
      else if (type_void(t))
	error("invalid use of void expression");
      else if (type_array(t))
	error("invalid use of array with unspecified bounds");
      else
	assert(0);
      /* XXX: Missing special message for typedef's */
    }
}
Пример #3
0
PRIVATE void or_fun(def d1, def d2, env v, tree cxt)
{
     if (d1 == NULL) {
	  d2->d_type = super_expand(d2->d_type, arid);
	  push_def(d2, v);
     }
     else if (d2 == NULL) {
	  d1->d_type = super_expand(d1->d_type, arid);
	  push_def(d1, v);
     }
     else {
	  if (check_types(d1->d_type, d2->d_type, d1->d_name, 
			  cxt, cxt->x_loc))
	       d1->d_type = type_union(d1->d_type, arid, d2->d_type, arid);
	  push_def(d1, v);
     }
}
Пример #4
0
// Coerce a literal control block to be the specified target type
static bool coerce_control_block(ast_t** astp, ast_t* target_type,
  lit_chain_t* chain, pass_opt_t* options, bool report_errors)
{
  assert(astp != NULL);
  ast_t* literal_expr = *astp;
  assert(literal_expr != NULL);

  ast_t* lit_type = ast_type(literal_expr);
  assert(lit_type != NULL);
  assert(ast_id(lit_type) == TK_LITERAL);
  ast_t* block_type = ast_type(lit_type);

  for(ast_t* p = ast_child(lit_type); p != NULL; p = ast_sibling(p))
  {
    assert(ast_id(p) == TK_LITERALBRANCH);
    ast_t* branch = (ast_t*)ast_data(p);
    assert(branch != NULL);

    if(!coerce_literal_to_type(&branch, target_type, chain, options,
      report_errors))
    {
      ast_free_unattached(block_type);
      return false;
    }

    block_type = type_union(block_type, ast_type(branch));
  }

  if(is_typecheck_error(block_type))
    return false;

  // block_type may be a sub-tree of the current type of literal_expr.
  // This means we must copy it before setting it as the type since ast_settype
  // will first free the existing type of literal_expr, which may include
  // block_type.
  if(ast_parent(block_type) != NULL)
    block_type = ast_dup(block_type);

  ast_settype(literal_expr, block_type);
  return true;
}
Пример #5
0
static void dump_type(type t)
{
  if (type_complex(t))
    {
      printf("C");
      t = make_base_type(t);
    }

  if (type_network_base_type(t))
    printf("N%s", type_networkdef(t)->name);
  /* Enums treated as ints for now */
  else if (type_integer(t))
    if (type_unsigned(t))
      printf("U");
    else
      printf("I");
  else if (type_float(t))
    printf("F");
  else if (type_double(t))
    printf("D");
  else if (type_long_double(t))
    printf("LD");
  else if (type_union(t))
    if (type_network(t))
      printf("ANU");
    else
      printf("AU");
  else if (type_struct(t))
    if (type_network(t))
      printf("ANS");
    else
      printf("AS");
  else if (type_pointer(t))
    printf("U");
  else
    assert(0);
}
Пример #6
0
static ast_t* find_infer_type(ast_t* type, infer_path_t* path)
{
  assert(type != NULL);

  switch(ast_id(type))
  {
    case TK_TUPLETYPE:
      if(path == NULL)  // End of path, infer the whole tuple
        return type;

      if(path->index >= ast_childcount(type)) // Cardinality mismatch
        return NULL;

      return find_infer_type(ast_childidx(type, path->index), path->next);

    case TK_UNIONTYPE:
    {
      // Infer all children
      ast_t* u_type = NULL;

      for(ast_t* p = ast_child(type); p != NULL; p = ast_sibling(p))
      {
        ast_t* t = find_infer_type(p, path);

        if(t == NULL)
        {
          // Propogate error
          ast_free_unattached(u_type);
          return NULL;
        }

        u_type = type_union(u_type, t);
      }

      return u_type;
    }

    case TK_ISECTTYPE:
    {
      // Infer all children
      ast_t* i_type = NULL;

      for(ast_t* p = ast_child(type); p != NULL; p = ast_sibling(p))
      {
        ast_t* t = find_infer_type(p, path);

        if(t == NULL)
        {
          // Propogate error
          ast_free_unattached(i_type);
          return NULL;
        }

        i_type = type_isect(i_type, t);
      }

      return i_type;
    }

    default:
      if(path != NULL)  // Type doesn't match path
        return NULL;

      // Just return whatever this type is
      return type;
  }
}
Пример #7
0
PUBLIC type tc_expr(tree t, env e)
#endif
{
     switch (t->x_kind) {
     case REF:
	  return ref_type((sym) t->x_tag, t->x_params, e, t);
	  
     case INGEN:
	  return ref_type((sym) t->x_tag,
			  list2(t->x_param1, t->x_param2), e, t);

     case PREGEN:
	  return ref_type((sym) t->x_tag, list1(t->x_param), e, t);

     case NUMBER:
	  return nat_type;
	  
     case SEXPR: {
	  def d;
	  frame params;

	  if (! open_sref(t->x_ref, e, &d, &params))
	       return err_type;

	  if ((tok) t->x_ref->x_sref_decor != empty) {
	       tc_error(t->x_loc, "Decoration ignored in schema reference");
	       tc_e_etc("Expression: %z", t);
	       tc_e_end();
	  }

	  if (t->x_ref->x_sref_renames != nil) {
	       tc_error(t->x_loc, "Renaming ignored in schema reference");
	       tc_e_etc("Expression: %z", t);
	       tc_e_end();
	  }

	  if (! aflag && d->d_abbrev)
	       return mk_power(mk_abbrev(d, params));
	  else
	       return mk_power(seal(mk_sproduct(d->d_schema), params));
     }

     case POWER: {
	  type tt1, tt2;	  
	  if (! anal_power(tt1 = tc_expr(t->x_arg, e), &tt2, t->x_arg)) {
	       tc_error(t->x_loc, "Argument of \\power must be a set");
	       tc_e_etc("Expression: %z", t);
	       tc_e_etc("Arg type:   %t", tt1);
	       tc_e_end();
	  }
	  return mk_power(mk_power(tt2));
     }
	   
     case TUPLE : {
	  type a[MAX_ARGS];
	  int n = 0;
	  tree u;
	       
	  for (u = t->x_elements; u != nil; u = cdr(u)) {
	       if (n >= MAX_ARGS)
		    panic("tc_expr - tuple too big");
	       a[n++] = tc_expr(car(u), e);
	  }
	  return mk_cproduct(n, a);
     }

     case CROSS: {
	  type a[MAX_ARGS];
	  type tt1, tt2;
	  int n = 0;
	  tree u;

	  for (u = t->x_factors; u != nil; u = cdr(u)) {
	       if (n >= MAX_ARGS)
		    panic("tc_expr - product too big");
	       tt1 = tc_expr(car(u), e);
	       if (! anal_power(tt1, &tt2, car(u))) {
		    tc_error(t->x_loc,
			     "Argument %d of \\cross must be a set", n+1);
		    tc_e_etc("Expression: %z", t);
		    tc_e_etc("Arg %d type: %t", n+1, tt1);
		    tc_e_end();
	       }
	       a[n++] = tt2;
	  }
	  return mk_power(mk_cproduct(n, a));
     }

     case EXT:
     case SEQ:
     case BAG: {
	  type elem_type;
	  type tt;
	  tree u;

	  if (t->x_elements == nil)
	       elem_type = new_typevar(t);
	  else {
	       elem_type = tc_expr(car(t->x_elements), e);
	       for (u = cdr(t->x_elements); u != nil; u = cdr(u)) {
		    if (unify(elem_type, tt = tc_expr(car(u), e)))
			 elem_type = type_union(elem_type, arid, tt, arid);
		    else {
			 tc_error(t->x_loc, "Type mismatch in %s display",
				  (t->x_kind == EXT ? "set" :
				   t->x_kind == SEQ ? "sequence" : "bag"));
			 tc_e_etc("Expression: %z", car(u));
			 tc_e_etc("Has type:   %t", tt);
			 tc_e_etc("Expected:   %t", elem_type);
			 tc_e_end();
		    }
	       }
	  }
	  switch (t->x_kind) {
	  case EXT:
	       return mk_power(elem_type);
	  case SEQ:
	       return (aflag ? rel_type(num_type, elem_type) 
			     : mk_seq(elem_type));
	  case BAG:
	       return (aflag ? rel_type(elem_type, num_type) 
			     : mk_bag(elem_type));
	  }
     }

     case THETA: 
	  return theta_type(t, e, (type) NULL, t);

     case BINDING: {
	  tree u;
	  env e1 = new_env(e);
	  for (u = t->x_elements; u != nil; u = cdr(u))
	       add_def(VAR, (sym) car(u)->x_lhs, 
		       tc_expr(car(u)->x_rhs, e), e1);
	  return mk_sproduct(mk_schema(e1));
     }

     case SELECT: {
	  type a = tc_expr(t->x_arg, e);

	  if (type_kind(a) != SPRODUCT) {
	       tc_error(t->x_loc,
			"Argument of selection must have schema type");
	       tc_e_etc("Expression: %z", t);
	       tc_e_etc("Arg type:   %t", a);
	       tc_e_end();
	       mark_error();
	       return err_type;
	  }

	  switch (t->x_field->x_kind) {
	  case IDENT:
	       return (comp_type(a, (sym) t->x_field, t, t->x_loc));

	  case THETA:
	       return (theta_type(t->x_field, e, a, t));

	  default:
	       bad_tag("tc_expr.SELECT", t->x_field->x_kind);
	       return (type) NULL;
	  }
     }

     case APPLY:
	  return tc_apply(APPLY, t, t->x_arg1, t->x_arg2, e);

     case INOP:
	  return tc_apply(INOP, t, simply(t->x_op, t->x_loc), 
			  pair(t->x_rand1, t->x_rand2), e);

     case POSTOP:
	  return tc_apply(POSTOP, t, simply(t->x_op, t->x_loc), 
			  t->x_rand, e);

     case LAMBDA: {
	  env e1 = tc_schema(t->x_bvar, e);
	  type dom = tc_expr(char_tuple(t->x_bvar), e1);
	  type ran = tc_expr(t->x_body, e1);
	  return (aflag ? rel_type(dom, ran) : mk_pfun(dom, ran));
     }
    
     case COMP:
     case MU: {
	  env e1 = tc_schema(t->x_bvar, e);
	  type a = tc_expr(exists(t->x_body) ? the(t->x_body) :
			   char_tuple(t->x_bvar), e1);
	  return (t->x_kind == COMP ? mk_power(a) : a);
     }

     case LETEXPR:
	  return tc_expr(t->x_body, tc_letdefs(t->x_defs, e));

     case IF: {
	  type a, b;
	  tc_pred(t->x_if, e);
	  a = tc_expr(t->x_then, e);
	  b = tc_expr(t->x_else, e);
	  if (unify(a, b))
	       return type_union(a, arid, b, arid);
	  else {
	       tc_error(t->x_loc,
			"Type mismatch in conditional expression");
	       tc_e_etc("Expression: %z", t);
	       tc_e_etc("Then type:  %t", a);
	       tc_e_etc("Else type:  %t", b);
	       tc_e_end();
	       return err_type;
	  }
     }

     default:
	  bad_tag("tc_expr", t->x_kind);
	  /* dummy */ return (type) NULL;
     }
}
Пример #8
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;
}