[qfcc] Add type_count() function

It returns the number of elements in a type (so something like `countof`
(hopefully that's what the up-coming C feature will be called) can be
implemented), but it applies to structs, vectors, etc (eg, 9 for mat3).
This commit is contained in:
Bill Currie 2024-11-17 16:12:27 +09:00
parent d082d39e17
commit 91a93d7803
4 changed files with 35 additions and 0 deletions

View file

@ -107,6 +107,7 @@ typedef struct symtab_s {
struct symtab_s *next; ///< next in global collection of symtabs
stab_type_e type; ///< type of symbol table
int size; ///< size of structure represented by symtab
int count; ///< number of real members in structure
struct hashtab_s *tab; ///< symbols defined in this table
symbol_t *symbols; ///< chain of symbols in this table
symbol_t **symtail; ///< keep chain in declaration order

View file

@ -253,6 +253,7 @@ bool type_assignable (const type_t *dst, const type_t *src);
bool type_promotes (const type_t *dst, const type_t *src) __attribute__((pure));
bool type_same (const type_t *dst, const type_t *src) __attribute__((pure));
int type_size (const type_t *type) __attribute__((pure));
int type_count (const type_t *type) __attribute__((pure));
int type_width (const type_t *type) __attribute__((pure));
int type_rows (const type_t *type) __attribute__((pure));
int type_cols (const type_t *type) __attribute__((pure));

View file

@ -224,6 +224,7 @@ build_struct (int su, symbol_t *tag, symtab_t *symtab, const type_t *type,
s->id = index++;
}
}
symtab->count = index;
if (!type)
sym->type = find_type (sym->type); // checks the tag, not the symtab
((type_t *) sym->type)->symtab = symtab;

View file

@ -1728,6 +1728,38 @@ type_size (const type_t *type)
internal_error (0, "invalid type meta: %d", type->meta);
}
int
type_count (const type_t *type)
{
switch (type->meta) {
case ty_handle:
case ty_bool:
case ty_basic:
case ty_enum:
if (type->type != ev_short && (!type->columns || !type->width)) {
internal_error (0, "%s:%d:%d", pr_type_name[type->type],
type->columns, type->width);
}
return type->width * type->columns;
case ty_struct:
case ty_union:
if (!type->symtab)
return 0;
return type->symtab->count;
case ty_array:
return type->array.count;
case ty_class:
return 1;
case ty_alias:
return type_size (type->alias.aux_type);
case ty_algebra:
internal_error (0, "count of algebra type");
case ty_meta_count:
break;
}
internal_error (0, "invalid type meta: %d", type->meta);
}
int
type_width (const type_t *type)
{