commit d5b907c1637d152050fb7e7e8e4664b342957a74
parent 154a61d7fb282ad610cbf72c865c1275535b2699
Author: Bor Grošelj Simić <bgs@turminal.net>
Date: Sat, 4 Jun 2022 16:47:56 +0200
handle enum values without names when generating .td files
Previous version of the code relied on all values of the enum type
having a declared name. That's not always the case, so we need to treat
enum values more like regular integers in this regard.
Signed-off-by: Bor Grošelj Simić <bgs@turminal.net>
Diffstat:
3 files changed, 26 insertions(+), 22 deletions(-)
diff --git a/src/typedef.c b/src/typedef.c
@@ -123,29 +123,18 @@ emit_const(const struct expression *expr, FILE *out)
break;
case STORAGE_ENUM:
assert(expr->result->storage == STORAGE_ENUM);
- struct scope_object *ev =
- type_dealias(expr->result)->_enum.values->objects;
- for(; ev; ev = ev->lnext) {
- if (ev->otype == O_SCAN) {
- continue;
- }
- if (ev->type->alias.type->storage == STORAGE_UINTPTR) {
- if (ev->value->constant.uval == val->uval) {
- fprintf(out, "(%" PRIuMAX "): uintptr", val->uval);
- break;
- }
- } else if (ev->type->alias.type->storage == STORAGE_CHAR
- || !type_is_signed(ev->type->alias.type)) {
- if (ev->value->constant.uval == val->uval) {
- fprintf(out, "%" PRIuMAX, val->uval);
- break;
- }
- } else if (ev->value->constant.ival == val->ival) {
- fprintf(out, "%" PRIiMAX, val->ival);
- break;
- }
+ const struct type *t = type_dealias(expr->result);
+ char *ident = identifier_unparse(&t->alias.ident);
+ if (t->alias.type->storage == STORAGE_CHAR) {
+ fprintf(out, "%" PRIuMAX, val->uval);
+ } else if (type_is_signed(t->alias.type)) {
+ fprintf(out, "%" PRIiMAX "%s: %s", val->ival,
+ storage_to_suffix(t->alias.type->storage), ident);
+ } else {
+ fprintf(out, "%" PRIuMAX "%s: %s", val->uval,
+ storage_to_suffix(t->alias.type->storage), ident);
}
- assert(ev);
+ free(ident);
break;
case STORAGE_ALIAS:
case STORAGE_ARRAY:
diff --git a/testmod/testmod.ha b/testmod/testmod.ha
@@ -4,6 +4,15 @@ export type _enum = enum {
THREE = 3,
};
+export type other = enum {
+ // purposefully something that doesn't exist in _enum
+ EIGHT = 8: _enum,
+};
+
+export type char_enum = enum char {
+ ONE = 1,
+};
+
export type enum_alias = _enum;
export def val: int = 42;
diff --git a/tests/24-imports.ha b/tests/24-imports.ha
@@ -1,6 +1,11 @@
use rt;
use testmod;
+fn _enum() void = {
+ assert(testmod::other::EIGHT == 8);
+ assert(testmod::char_enum::ONE == 1);
+};
+
fn accept() void = {
assert(rt::compile("
use testmod;
@@ -80,6 +85,7 @@ fn reject() void = {
export fn main() void = {
+ _enum();
accept();
reject();
};