diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2024-09-12 13:05:08 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2024-09-12 13:05:08 -0400 |
| commit | 56a4d13975f443fc9e81f0acbb1a896122aa5857 (patch) | |
| tree | 09ea8a4d14ff7e3d849f9ed3cb3b76b81094fff9 /types.c | |
| parent | 43f4f3610e5258afbfb9e313c989e1e52f477c38 (diff) | |
Automatic promotion to single-argument enum tags with a unique type
Diffstat (limited to 'types.c')
| -rw-r--r-- | types.c | 22 |
1 files changed, 22 insertions, 0 deletions
@@ -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; |
