Implement type aliasing

The separate types are in the file, but there are multiple issues
This commit is contained in:
Bill Currie 2020-02-19 18:11:43 +09:00
parent 2f18364364
commit a5aba6c8ac
5 changed files with 43 additions and 3 deletions

View file

@ -138,8 +138,9 @@ void chain_type (type_t *type);
/** Append a type to the end of a type chain.
The type chain must be made up of only field, pointer, function and array
types, as other types do not have auxiliary type fields.
The type chain must be made up of only field, pointer, function, array
and alias (typedef) types, as other types do not have auxiliary type
fields.
\param type The type chain to which the type will be appended.
\param new The type to be appended. May be any type.
@ -153,6 +154,7 @@ type_t *field_type (type_t *aux);
type_t *pointer_type (type_t *aux);
type_t *array_type (type_t *aux, int size);
type_t *based_array_type (type_t *aux, int base, int top);
type_t *alias_type (type_t *aux, const char *name);
void print_type_str (struct dstring_s *str, const type_t *type);
void print_type (const type_t *type);
const char *encode_params (const type_t *type);

View file

@ -423,6 +423,7 @@ static const char *ty_meta_names[] = {
"ty_enum",
"ty_array",
"ty_class",
"ty_alias",
};
#define NUM_META ((int)(sizeof (ty_meta_names) / sizeof (ty_meta_names[0])))

View file

@ -253,6 +253,22 @@ qfo_encode_class (type_t *type)
return def;
}
static def_t *
qfo_encode_alias (type_t *type)
{
qfot_type_t *enc;
def_t *def;
def_t *alias_type_def;
alias_type_def = qfo_encode_type (type->t.alias.type);
def = qfo_new_encoding (type, sizeof (enc->t.alias));
enc = D_POINTER (qfot_type_t, def);
ENC_DEF (enc->t.alias.type, alias_type_def);
ENC_STR (enc->t.alias.name, type->name);
return def;
}
def_t *
qfo_encode_type (type_t *type)
{
@ -265,6 +281,7 @@ qfo_encode_type (type_t *type)
qfo_encode_struct, // ty_enum
qfo_encode_array, // ty_array
qfo_encode_class, // ty_class
qfo_encode_alias, // ty_alias
};
if (type->type_def && type->type_def->external) {
@ -274,7 +291,7 @@ qfo_encode_type (type_t *type)
}
if (type->type_def)
return type->type_def;
if (type->meta > ty_class)
if (type->meta > sizeof (funcs) / (sizeof (funcs[0])))
internal_error (0, "bad type meta type");
if (!type->encoding)
type->encoding = type_get_encoding (type);

View file

@ -406,6 +406,7 @@ external_decl
$1->type = find_type (append_type ($1->type, spec.type));
if (spec.is_typedef) {
$1->sy_type = sy_type;
$1->type = alias_type ($1->type, $1->name);
symtab_addsymbol (current_symtab, $1);
} else {
initialize_def ($1, 0, current_symtab->space, spec.storage);

View file

@ -445,6 +445,25 @@ based_array_type (type_t *aux, int base, int top)
return new;
}
type_t *
alias_type (type_t *aux, const char *name)
{
type_t _new;
type_t *new = &_new;
if (!aux || !name) {
internal_error (0, "alias to null type or with no name");
}
memset (&_new, 0, sizeof (_new));
new->name = save_string (name);
new->meta = ty_alias;
new->type = aux->type;
new->alignment = aux->alignment;
new->t.alias.type = aux;
new = find_type (new);
return new;
}
void
print_type_str (dstring_t *str, const type_t *type)
{