[qfcc] Make is_struct struct-only

And add is_union to handle unions. Sometimes it's necessary to check
between the two.
This commit is contained in:
Bill Currie 2023-05-25 21:22:50 +09:00
parent 6d5e8922a5
commit d001473536
8 changed files with 26 additions and 19 deletions

View file

@ -218,6 +218,7 @@ int is_scalar (const type_t *type) __attribute__((pure));
int is_nonscalar (const type_t *type) __attribute__((pure)); int is_nonscalar (const type_t *type) __attribute__((pure));
int is_math (const type_t *type) __attribute__((pure)); int is_math (const type_t *type) __attribute__((pure));
int is_struct (const type_t *type) __attribute__((pure)); int is_struct (const type_t *type) __attribute__((pure));
int is_union (const type_t *type) __attribute__((pure));
int is_array (const type_t *type) __attribute__((pure)); int is_array (const type_t *type) __attribute__((pure));
int is_structural (const type_t *type) __attribute__((pure)); int is_structural (const type_t *type) __attribute__((pure));
int type_compatible (const type_t *dst, const type_t *src) __attribute__((pure)); int type_compatible (const type_t *dst, const type_t *src) __attribute__((pure));

View file

@ -1013,6 +1013,8 @@ do_op_compound (int op, expr_t *e, expr_t *e1, expr_t *e2)
type_t *t2 = get_type (e2); type_t *t2 = get_type (e2);
if (is_struct (t1) && is_struct (t2)) if (is_struct (t1) && is_struct (t2))
return do_op_struct (op, e, e1, e2); return do_op_struct (op, e, e1, e2);
if (is_union (t1) && is_union (t2))
return do_op_struct (op, e, e1, e2);
if (is_scalar (t1) && is_scalar (t2)) { if (is_scalar (t1) && is_scalar (t2)) {
if (is_enum (t1)) { if (is_enum (t1)) {
if (t2->type == ev_double) if (t2->type == ev_double)

View file

@ -605,10 +605,8 @@ initialize_def (symbol_t *sym, expr_t *init, defspace_t *space,
convert_name (init); convert_name (init);
if (init->type == ex_error) if (init->type == ex_error)
return; return;
if ((is_array (sym->type) || is_struct (sym->type) if ((is_structural (sym->type) || is_nonscalar (sym->type))
|| is_nonscalar (sym->type)) && (init->type == ex_compound || init->type == ex_nil)) {
&& ((init->type == ex_compound)
|| init->type == ex_nil)) {
init_elements (sym->s.def, init); init_elements (sym->s.def, init);
sym->s.def->initialized = 1; sym->s.def->initialized = 1;
} else { } else {

View file

@ -1467,7 +1467,7 @@ field_expr (expr_t *e1, expr_t *e2)
} }
} }
} else if (is_ptr (t1)) { } else if (is_ptr (t1)) {
if (is_struct (t1->t.fldptr.type)) { if (is_struct (t1->t.fldptr.type) || is_union (t1->t.fldptr.type)) {
symbol_t *field; symbol_t *field;
field = get_struct_field (t1->t.fldptr.type, e1, e2); field = get_struct_field (t1->t.fldptr.type, e1, e2);
@ -1492,7 +1492,7 @@ field_expr (expr_t *e1, expr_t *e2)
e1 = cast_expr (pointer_type (ivar->type), e1); e1 = cast_expr (pointer_type (ivar->type), e1);
return unary_expr ('.', e1); return unary_expr ('.', e1);
} }
} else if (is_nonscalar (t1) || is_struct (t1)) { } else if (is_nonscalar (t1) || is_struct (t1) || is_union (t1)) {
symbol_t *field; symbol_t *field;
field = get_struct_field (t1, e1, e2); field = get_struct_field (t1, e1, e2);

View file

@ -436,7 +436,7 @@ is_anonymous_struct (specifier_t spec)
if (spec.sym) { if (spec.sym) {
return 0; return 0;
} }
if (!is_struct (spec.type)) { if (!is_struct (spec.type) && !is_union (spec.type)) {
return 0; return 0;
} }
if (!spec.type->t.symtab || spec.type->t.symtab->parent) { if (!spec.type->t.symtab || spec.type->t.symtab->parent) {
@ -484,7 +484,8 @@ check_specifiers (specifier_t spec)
if (is_anonymous_struct (spec)){ if (is_anonymous_struct (spec)){
warning (0, "unnamed struct/union that defines " warning (0, "unnamed struct/union that defines "
"no instances"); "no instances");
} else if (!is_enum (spec.type) && !is_struct (spec.type)) { } else if (!is_enum (spec.type)
&& !is_struct (spec.type) && !is_union (spec.type)) {
warning (0, "useless type name in empty declaration"); warning (0, "useless type name in empty declaration");
} }
} else if (!spec.type && spec.sym) { } else if (!spec.type && spec.sym) {

View file

@ -1044,7 +1044,7 @@ expr_call_v6p (sblock_t *sblock, expr_t *call, operand_t **op)
use = p; use = p;
continue; continue;
} }
if (is_struct (get_type (param))) { if (is_struct (get_type (param)) || is_union (get_type (param))) {
expr_t *mov = assign_expr (param, a); expr_t *mov = assign_expr (param, a);
mov->line = a->line; mov->line = a->line;
mov->file = a->file; mov->file = a->file;
@ -1946,7 +1946,7 @@ expr_nil (sblock_t *sblock, expr_t *e, operand_t **op)
operand_t *size; operand_t *size;
statement_t *s; statement_t *s;
if (!is_struct (nil) && !is_array (nil)) { if (!is_structural (nil)) {
*op = value_operand (new_nil_val (nil), e); *op = value_operand (new_nil_val (nil), e);
return sblock; return sblock;
} }

View file

@ -186,7 +186,7 @@ build_struct (int su, symbol_t *tag, symtab_t *symtab, type_t *type, int base)
symbol_t *t = s->next; symbol_t *t = s->next;
int offset = s->s.offset; int offset = s->s.offset;
if (!is_struct (s->type)) { if (!is_struct (s->type) && !is_union (s->type)) {
internal_error (0, "non-struct/union anonymous field"); internal_error (0, "non-struct/union anonymous field");
} }
anonymous = s->type->t.symtab; anonymous = s->type->t.symtab;
@ -362,8 +362,7 @@ emit_structure (const char *name, int su, struct_def_t *defs, type_t *type,
name = save_string (name); name = save_string (name);
if (!type) if (!type)
type = make_structure (0, su, defs, 0)->type; type = make_structure (0, su, defs, 0)->type;
if (!is_struct (type) || (su == 's' && type->meta != ty_struct) if ((su == 's' && !is_struct (type)) || (su == 'u' && !is_union (type)))
|| (su == 'u' && type->meta != ty_union))
internal_error (0, "structure %s type mismatch", name); internal_error (0, "structure %s type mismatch", name);
for (i = 0, field_sym = type->t.symtab->symbols; field_sym; for (i = 0, field_sym = type->t.symtab->symbols; field_sym;
i++, field_sym = field_sym->next) { i++, field_sym = field_sym->next) {

View file

@ -174,9 +174,7 @@ low_level_type (type_t *type)
return type->type; return type->type;
if (is_enum (type)) if (is_enum (type))
return type_default->type; return type_default->type;
if (is_struct (type)) if (is_structural (type))
return ev_void;
if (is_array (type))
return ev_void; return ev_void;
internal_error (0, "invalid complex type"); internal_error (0, "invalid complex type");
} }
@ -1210,8 +1208,16 @@ int
is_struct (const type_t *type) is_struct (const type_t *type)
{ {
type = unalias_type (type); type = unalias_type (type);
if (type->type == ev_invalid if (type->type == ev_invalid && type->meta == ty_struct)
&& (type->meta == ty_struct || type->meta == ty_union)) return 1;
return 0;
}
int
is_union (const type_t *type)
{
type = unalias_type (type);
if (type->type == ev_invalid && type->meta == ty_union)
return 1; return 1;
return 0; return 0;
} }
@ -1229,7 +1235,7 @@ int
is_structural (const type_t *type) is_structural (const type_t *type)
{ {
type = unalias_type (type); type = unalias_type (type);
return is_struct (type) || is_array (type); return is_struct (type) || is_union (type) || is_array (type);
} }
int int