Beispiel #1
0
tree_t type_field(type_t t, unsigned n)
{
   if (t->kind == T_SUBTYPE)
      return type_field(type_base(t), n);
   else
      return tree_array_nth(&(lookup_item(t, I_FIELDS)->tree_array), n);
}
Beispiel #2
0
ident_t type_ident(type_t t)
{
   assert(t != NULL);

   if (t->ident == NULL) {
      char *buf;
      switch (t->kind) {
      case T_SUBTYPE:
         return type_ident(type_base(t));

      case T_ACCESS:
         buf = xasprintf("access to %s",
                  istr(type_ident(type_access(t))));
         break;

      case T_NONE:
         buf = xasprintf("none");
         break;

      default:
         assert(false);
      }

      ident_t ident = ident_new(buf);
      free(buf);
      return ident;
   }
   else
      return t->ident;
}
Beispiel #3
0
unsigned type_fields(type_t t)
{
   if (t->kind == T_SUBTYPE)
      return type_fields(type_base(t));
   else
      return lookup_item(t, I_FIELDS)->tree_array.count;
}
Beispiel #4
0
type_t type_base_recur(type_t t)
{
   assert(t != NULL);
   while (t->kind == T_SUBTYPE)
      t = type_base(t);
   return t;
}
Beispiel #5
0
bool type_is_real(type_t t)
{
   assert(t != NULL);
   if (t->kind == T_SUBTYPE)
      return type_is_real(type_base(t));
   else
      return (t->kind == T_REAL);
}
Beispiel #6
0
bool type_is_integer(type_t t)
{
   assert(t != NULL);
   if (t->kind == T_SUBTYPE)
      return type_is_integer(type_base(t));
   else
      return (t->kind == T_INTEGER);
}
Beispiel #7
0
bool type_is_enum(type_t t)
{
   assert(t != NULL);
   if (t->kind == T_SUBTYPE)
      return type_is_enum(type_base(t));
   else
      return (t->kind == T_ENUM);
}
Beispiel #8
0
bool type_is_array(type_t t)
{
   assert(t != NULL);
   if (t->kind == T_SUBTYPE)
      return type_is_array(type_base(t));
   else
      return (t->kind == T_CARRAY || t->kind == T_UARRAY);
}
Beispiel #9
0
bool type_is_scalar(type_t t)
{
   assert(t != NULL);
   if (t->kind == T_SUBTYPE)
      return type_is_scalar(type_base(t));
   else
      return (t->kind == T_INTEGER)
         || (t->kind == T_REAL)
         || (t->kind == T_ENUM);
}
Beispiel #10
0
bool type_is_unconstrained(type_t t)
{
   assert(t != NULL);
   if (t->kind == T_SUBTYPE) {
      if (type_dims(t) == 0)
         return type_is_unconstrained(type_base(t));
      else
         return false;
   }
   else
      return (t->kind == T_UARRAY);
}
Beispiel #11
0
type_t type_elem(type_t t)
{
   assert(t != NULL);

   if (IS(t, T_SUBTYPE))
      return type_elem(type_base(t));
   else {
      item_t *item = lookup_item(t, I_ELEM);
      assert(item->type != NULL);
      return item->type;
   }
}
Beispiel #12
0
void type_replace(type_t t, type_t a)
{
   assert(t != NULL);
   assert(IS(t, T_INCOMPLETE));

   t->kind  = a->kind;
   t->ident = a->ident;

   const imask_t has = has_map[t->kind];

   if (has & I_DIMS) {
      const int ndims = type_dims(a);
      for (int i = 0; i < ndims; i++)
         type_add_dim(t, type_dim(a, i));
   }

   switch (a->kind) {
   case T_UARRAY:
      for (unsigned i = 0; i < type_index_constrs(a); i++)
         type_add_index_constr(t, type_index_constr(a, i));

      // Fall-through
   case T_CARRAY:
      type_set_elem(t, type_elem(a));
      break;

   case T_SUBTYPE:
      type_set_base(t, type_base(a));
      break;

   case T_FUNC:
      type_set_result(t, type_result(a));
      break;

   case T_INTEGER:
   case T_REAL:
      break;

   case T_ENUM:
      for (unsigned i = 0; i < type_enum_literals(a); i++)
         type_enum_add_literal(t, type_enum_literal(a, i));
      break;

   case T_RECORD:
      for (unsigned i = 0; i < type_fields(a); i++)
         type_add_field(t, type_field(a, i));
      break;

   default:
      assert(false);
   }
}
Beispiel #13
0
ast_t* type_builtin(pass_opt_t* opt, ast_t* from, const char* name)
{
  ast_t* ast = type_base(from, NULL, name);

  if(!names_nominal(opt, from, &ast, false))
  {
    ast_error(from, "unable to validate '%s'", name);
    ast_free(ast);
    return NULL;
  }

  return ast;
}
Beispiel #14
0
void main(int argc, string argv[])
{
  string type, name;

  initparam(argv, defv);
  type = getparam("type");
  name = getparam("name");
  printf("type_length(\"%s\") = %d\n", type, type_length(type));
  printf("type_name(\"%s\") = %s\n", type, type_name(type));
  printf("type_base(\"%s\") = %s\n", type, type_base(type));
  printf("type_fmt(\"%s\", TRUE) = %s\n", type, type_fmt(type, TRUE));
  printf("type_fmt(\"%s\", FALSE) = %s\n", type, type_fmt(type, FALSE));
  printf("name_type(\"%s\") = %s\n", name, name_type(name));
}
Beispiel #15
0
ast_t* type_sugar(ast_t* from, const char* package, const char* name)
{
  return type_base(from, package, name);
}
Beispiel #16
0
bool type_eq(type_t a, type_t b)
{
   assert(a != NULL);
   assert(b != NULL);

   type_kind_t kind_a = type_kind(a);
   type_kind_t kind_b = type_kind(b);

   if ((kind_a == T_UNRESOLVED) || (kind_b == T_UNRESOLVED))
      return false;

   if (a == b)
      return true;

   // Subtypes are convertible to the base type
   while ((kind_a = type_kind(a)) == T_SUBTYPE)
      a = type_base(a);
   while ((kind_b = type_kind(b)) == T_SUBTYPE)
      b = type_base(b);

   const bool compare_c_u_arrays =
      (kind_a == T_CARRAY && kind_b == T_UARRAY)
      || (kind_a == T_UARRAY && kind_b == T_CARRAY);

   if ((kind_a != kind_b) && !compare_c_u_arrays)
      return false;

   // Universal integer type is equal to any other integer type
   type_t universal_int = type_universal_int();
   ident_t uint_i = type_ident(universal_int);
   if (kind_a == T_INTEGER
       && (type_ident(a) == uint_i || type_ident(b) == uint_i))
      return true;

   // Universal real type is equal to any other real type
   type_t universal_real = type_universal_real();
   ident_t ureal_i = type_ident(universal_real);
   if (kind_a == T_REAL
       && (type_ident(a) == ureal_i || type_ident(b) == ureal_i))
      return true;

   // XXX: this is not quite right as structurally equivalent types
   // may be declared in different scopes with the same name but
   // shouldn't compare equal

   if (type_ident(a) != type_ident(b))
      return false;

   // Access types are equal if the pointed to type is the same
   if (kind_a == T_ACCESS)
      return type_eq(type_access(a), type_access(b));

   if (compare_c_u_arrays)
      return type_eq(type_elem(a), type_elem(b));

   const imask_t has = has_map[a->kind];

   if ((has & I_DIMS) && (type_dims(a) != type_dims(b)))
      return false;

   if (type_kind(a) == T_FUNC) {
      if (!type_eq(type_result(a), type_result(b)))
         return false;
   }

   if (has & I_PARAMS) {
      if (type_params(a) != type_params(b))
         return false;

      const int nparams = type_params(a);
      for (int i = 0; i < nparams; i++) {
         if (!type_eq(type_param(a, i), type_param(b, i)))
             return false;
      }
   }

   return true;
}