From 56a4d13975f443fc9e81f0acbb1a896122aa5857 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Thu, 12 Sep 2024 13:05:08 -0400 Subject: Automatic promotion to single-argument enum tags with a unique type --- types.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'types.c') diff --git a/types.c b/types.c index d7b517d3..d70346a2 100644 --- a/types.c +++ b/types.c @@ -276,6 +276,25 @@ PUREFUNC bool has_stack_memory(type_t *t) } } +PUREFUNC const char *enum_single_value_tag(type_t *enum_type, type_t *t) +{ + const char *found = NULL; + for (tag_t *tag = Match(enum_type, EnumType)->tags; tag; tag = tag->next) { + if (tag->type->tag != StructType) continue; + auto s = Match(tag->type, StructType); + if (!s->fields || s->fields->next || !s->fields->type) + continue; + + if (can_promote(t, s->fields->type)) { + if (found) // Ambiguous case, multiple matches + return NULL; + found = tag->name; + // Continue searching to check for ambiguous cases + } + } + return found; +} + PUREFUNC bool can_promote(type_t *actual, type_t *needed) { // No promotion necessary: @@ -296,6 +315,9 @@ PUREFUNC bool can_promote(type_t *actual, type_t *needed) return cmp == NUM_PRECISION_EQUAL || cmp == NUM_PRECISION_LESS; } + if (needed->tag == EnumType) + return (enum_single_value_tag(needed, actual) != NULL); + // Text to C String if (actual->tag == TextType && !Match(actual, TextType)->lang && needed->tag == CStringType) return true; -- cgit v1.2.3