Race down the alias chain before checking types

This takes care of some of the type aliasing issues.
This commit is contained in:
Bill Currie 2020-02-19 18:28:11 +09:00
parent a5aba6c8ac
commit d50a27a045
2 changed files with 182 additions and 156 deletions

View File

@ -160,6 +160,7 @@ void print_type (const type_t *type);
const char *encode_params (const type_t *type); const char *encode_params (const type_t *type);
void encode_type (struct dstring_s *encoding, const type_t *type); void encode_type (struct dstring_s *encoding, const type_t *type);
const char *type_get_encoding (const type_t *type); const char *type_get_encoding (const type_t *type);
const type_t *unalias_type (const type_t *type) __attribute__((pure));
int is_void (const type_t *type) __attribute__((pure)); int is_void (const type_t *type) __attribute__((pure));
int is_enum (const type_t *type) __attribute__((pure)); int is_enum (const type_t *type) __attribute__((pure));
int is_integral (const type_t *type) __attribute__((pure)); int is_integral (const type_t *type) __attribute__((pure));

View File

@ -471,84 +471,95 @@ print_type_str (dstring_t *str, const type_t *type)
dasprintf (str, " (null)"); dasprintf (str, " (null)");
return; return;
} }
switch (type->type) { switch (type->meta) {
case ev_field: case ty_class:
dasprintf (str, ".("); dasprintf (str, " %s", type->t.class->name);
print_type_str (str, type->t.fldptr.type); if (type->protos)
dasprintf (str, ")"); print_protocollist (str, type->protos);
break; return;
case ev_func: case ty_enum:
print_type_str (str, type->t.func.type); dasprintf (str, " enum %s", type->name);
if (type->t.func.num_params == -1) { return;
dasprintf (str, "(...)"); case ty_struct:
dasprintf (str, " struct %s", type->name);
return;
case ty_union:
dasprintf (str, " union %s", type->name);
return;
case ty_array:
print_type_str (str, type->t.array.type);
if (type->t.array.base) {
dasprintf (str, "[%d..%d]", type->t.array.base,
type->t.array.base + type->t.array.size - 1);
} else { } else {
int c, i; dasprintf (str, "[%d]", type->t.array.size);
dasprintf (str, "(");
if ((c = type->t.func.num_params) < 0)
c = ~c; // num_params is one's compliment
for (i = 0; i < c; i++) {
if (i)
dasprintf (str, ", ");
print_type_str (str, type->t.func.param_types[i]);
}
if (type->t.func.num_params < 0)
dasprintf (str, ", ...");
dasprintf (str, ")");
} }
break; return;
case ev_pointer: case ty_alias:
if (obj_is_id (type)) { dasprintf (str, "({%s=", type->name);
dasprintf (str, "id"); print_type_str (str, type->t.alias.type);
if (type->t.fldptr.type->protos) dstring_appendstr (str, "})");
print_protocollist (str, type->t.fldptr.type->protos); return;
break; case ty_none:
} switch (type->type) {
if (type == &type_SEL) { case ev_field:
dasprintf (str, "SEL"); dasprintf (str, ".(");
break; print_type_str (str, type->t.fldptr.type);
} dasprintf (str, ")");
dasprintf (str, "(*"); return;
print_type_str (str, type->t.fldptr.type); case ev_func:
dasprintf (str, ")"); print_type_str (str, type->t.func.type);
break; if (type->t.func.num_params == -1) {
case ev_invalid: dasprintf (str, "(...)");
switch (type->meta) {
case ty_class:
dasprintf (str, " %s", type->t.class->name);
if (type->protos)
print_protocollist (str, type->protos);
break;
case ty_enum:
dasprintf (str, " enum %s", type->name);
break;
case ty_struct:
dasprintf (str, " struct %s", type->name);
break;
case ty_union:
dasprintf (str, " union %s", type->name);
break;
case ty_array:
print_type_str (str, type->t.array.type);
if (type->t.array.base) {
dasprintf (str, "[%d..%d]", type->t.array.base,
type->t.array.base + type->t.array.size - 1);
} else { } else {
dasprintf (str, "[%d]", type->t.array.size); int c, i;
dasprintf (str, "(");
if ((c = type->t.func.num_params) < 0)
c = ~c; // num_params is one's compliment
for (i = 0; i < c; i++) {
if (i)
dasprintf (str, ", ");
print_type_str (str, type->t.func.param_types[i]);
}
if (type->t.func.num_params < 0)
dasprintf (str, ", ...");
dasprintf (str, ")");
} }
break; return;
case ty_alias: case ev_pointer:
dasprintf (str, "({%s=", type->name); if (obj_is_id (type)) {
print_type_str (str, type->t.alias.type); dasprintf (str, "id");
dstring_appendstr (str, "})"); if (type->t.fldptr.type->protos)
break; print_protocollist (str, type->t.fldptr.type->protos);
case ty_none: return;
}
if (type == &type_SEL) {
dasprintf (str, "SEL");
return;
}
dasprintf (str, "(*");
print_type_str (str, type->t.fldptr.type);
dasprintf (str, ")");
return;
case ev_void:
case ev_string:
case ev_float:
case ev_vector:
case ev_entity:
case ev_quat:
case ev_integer:
case ev_uinteger:
case ev_short:
case ev_double:
dasprintf (str, " %s", pr_type_name[type->type]);
return;
case ev_invalid:
case ev_type_count:
break; break;
} }
break; break;
default:
dasprintf (str, " %s", pr_type_name[type->type]);
break;
} }
internal_error (0, "bad type meta:type %d:%d", type->meta, type->type);
} }
void void
@ -622,96 +633,103 @@ encode_type (dstring_t *encoding, const type_t *type)
{ {
if (!type) if (!type)
return; return;
switch (type->type) { switch (type->meta) {
case ev_void: case ty_class:
dasprintf (encoding, "v"); encode_class (encoding, type);
break; return;
case ev_string: case ty_enum:
dasprintf (encoding, "*"); encode_enum (encoding, type);
break; return;
case ev_double: case ty_struct:
dasprintf (encoding, "d"); case ty_union:
break; encode_struct (encoding, type);
case ev_float: return;
dasprintf (encoding, "f"); case ty_array:
break; dasprintf (encoding, "[");
case ev_vector: dasprintf (encoding, "%d", type->t.array.size);
dasprintf (encoding, "V"); if (type->t.array.base)
break; dasprintf (encoding, ":%d", type->t.array.base);
case ev_entity: dasprintf (encoding, "=");
dasprintf (encoding, "E"); encode_type (encoding, type->t.array.type);
break; dasprintf (encoding, "]");
case ev_field: return;
dasprintf (encoding, "F"); case ty_alias:
encode_type (encoding, type->t.fldptr.type); encode_type (encoding, type->t.alias.type);
break; return;
case ev_func: case ty_none:
dasprintf (encoding, "("); switch (type->type) {
encode_type (encoding, type->t.func.type); case ev_void:
dasprintf (encoding, "%s)", encode_params (type)); dasprintf (encoding, "v");
break; return;
case ev_pointer: case ev_string:
if (type == &type_id) { dasprintf (encoding, "*");
dasprintf (encoding, "@"); return;
case ev_double:
dasprintf (encoding, "d");
return;
case ev_float:
dasprintf (encoding, "f");
return;
case ev_vector:
dasprintf (encoding, "V");
return;
case ev_entity:
dasprintf (encoding, "E");
return;
case ev_field:
dasprintf (encoding, "F");
encode_type (encoding, type->t.fldptr.type);
return;
case ev_func:
dasprintf (encoding, "(");
encode_type (encoding, type->t.func.type);
dasprintf (encoding, "%s)", encode_params (type));
return;
case ev_pointer:
if (type == &type_id) {
dasprintf (encoding, "@");
return;
}
if (type == &type_SEL) {
dasprintf (encoding, ":");
return;
}
if (type == &type_Class) {
dasprintf (encoding, "#");
return;
}
type = type->t.fldptr.type;
dasprintf (encoding, "^");
encode_type (encoding, type);
return;
case ev_quat:
dasprintf (encoding, "Q");
return;
case ev_integer:
dasprintf (encoding, "i");
return;
case ev_uinteger:
dasprintf (encoding, "I");
return;
case ev_short:
dasprintf (encoding, "s");
return;
case ev_invalid:
case ev_type_count:
break; break;
} }
if (type == &type_SEL) {
dasprintf (encoding, ":");
break;
}
if (type == &type_Class) {
dasprintf (encoding, "#");
break;
}
type = type->t.fldptr.type;
dasprintf (encoding, "^");
encode_type (encoding, type);
break;
case ev_quat:
dasprintf (encoding, "Q");
break;
case ev_integer:
dasprintf (encoding, "i");
break;
case ev_uinteger:
dasprintf (encoding, "I");
break;
case ev_short:
dasprintf (encoding, "s");
break;
case ev_invalid:
switch (type->meta) {
case ty_class:
encode_class (encoding, type);
break;
case ty_enum:
encode_enum (encoding, type);
break;
case ty_struct:
case ty_union:
encode_struct (encoding, type);
break;
case ty_array:
dasprintf (encoding, "[");
dasprintf (encoding, "%d", type->t.array.size);
if (type->t.array.base)
dasprintf (encoding, ":%d", type->t.array.base);
dasprintf (encoding, "=");
encode_type (encoding, type->t.array.type);
dasprintf (encoding, "]");
break;
case ty_alias:
encode_type (encoding, type->t.alias.type);
break;
case ty_none:
dasprintf (encoding, "?");
break;
}
break;
case ev_type_count:
dasprintf (encoding, "?");
break; break;
} }
internal_error (0, "bad type meta:type %d:%d", type->meta, type->type);
}
const type_t *
unalias_type (const type_t *type)
{
while (type->meta == ty_alias) {
type = type->t.alias.type;
}
return type;
} }
int int
@ -723,6 +741,7 @@ is_void (const type_t *type)
int int
is_enum (const type_t *type) is_enum (const type_t *type)
{ {
type = unalias_type (type);
if (type->type == ev_invalid && type->meta == ty_enum) if (type->type == ev_invalid && type->meta == ty_enum)
return 1; return 1;
return 0; return 0;
@ -779,6 +798,7 @@ is_math (const type_t *type)
int int
is_struct (const type_t *type) is_struct (const type_t *type)
{ {
type = unalias_type (type);
if (type->type == ev_invalid if (type->type == ev_invalid
&& (type->meta == ty_struct || type->meta == ty_union)) && (type->meta == ty_struct || type->meta == ty_union))
return 1; return 1;
@ -804,6 +824,7 @@ is_field (const type_t *type)
int int
is_array (const type_t *type) is_array (const type_t *type)
{ {
type = unalias_type (type);
if (type->type == ev_invalid && type->meta == ty_array) if (type->type == ev_invalid && type->meta == ty_array)
return 1; return 1;
return 0; return 0;
@ -828,6 +849,8 @@ is_string (const type_t *type)
int int
type_compatible (const type_t *dst, const type_t *src) type_compatible (const type_t *dst, const type_t *src)
{ {
dst = unalias_type (dst);
src = unalias_type (src);
// same type // same type
if (dst == src) { if (dst == src) {
return 1; return 1;
@ -847,6 +870,8 @@ type_compatible (const type_t *dst, const type_t *src)
int int
type_assignable (const type_t *dst, const type_t *src) type_assignable (const type_t *dst, const type_t *src)
{ {
dst = unalias_type (dst);
src = unalias_type (src);
int ret; int ret;
// same type // same type