commit 559a0514c47526b89ecbdc4fe413741899f16ff3
parent e976c86b2efc493c69053ff13cb68d124503d76c
Author: Drew DeVault <sir@cmpwn.com>
Date: Sun, 26 Sep 2021 10:46:43 +0200
gen: implement tuple reflection
Diffstat:
2 files changed, 61 insertions(+), 3 deletions(-)
diff --git a/src/gen.c b/src/gen.c
@@ -3745,9 +3745,52 @@ gen_type_info(struct gen_context *ctx,
item->value = constl(len);
break;
case STORAGE_TUPLE:
- // XXX: Temporary code to make sure code in the wild builds
- // while we flesh out these types
- item->value = constw(0);
+ *repr_name = "tuple";
+ item->value = constw(type_hash(&repr));
+ item->next = xcalloc(1, sizeof(struct qbe_data_item));
+ item = item->next;
+
+ item->type = QD_ZEROED;
+ item->zeroed = 4;
+ item->next = xcalloc(1, sizeof(struct qbe_data_item));
+ item = item->next;
+
+ def = xcalloc(1, sizeof(struct qbe_def));
+ def->name = gen_name(ctx, "sldata.%d");
+ def->kind = Q_DATA;
+ subitem = &def->data.items;
+ for (const struct type_tuple *field = &type->tuple;
+ field; field = field->next) {
+ subitem->type = QD_VALUE;
+ subitem->value = constl(field->offset);
+ subitem->next = xcalloc(1, sizeof(struct qbe_data_item));
+ subitem = subitem->next;
+
+ ref = mktyperef(ctx, field->type);
+ subitem->type = QD_VALUE;
+ subitem->value.kind = QV_GLOBAL;
+ subitem->value.type = &qbe_long;
+ subitem->value.name = ref.name;
+ if (field->next) {
+ subitem->next = xcalloc(1, sizeof(struct qbe_data_item));
+ subitem = subitem->next;
+ }
+ ++len;
+ }
+ qbe_append_def(ctx->out, def);
+
+ item->type = QD_VALUE;
+ item->value.kind = QV_GLOBAL;
+ item->value.type = &qbe_long;
+ item->value.name = strdup(def->name);
+ item->next = xcalloc(1, sizeof(struct qbe_data_item));
+ item = item->next;
+ item->type = QD_VALUE;
+ item->value = constl(len);
+ item->next = xcalloc(1, sizeof(struct qbe_data_item));
+ item = item->next;
+ item->type = QD_VALUE;
+ item->value = constl(len);
break;
}
return item;
diff --git a/tests/34-reflect.ha b/tests/34-reflect.ha
@@ -192,6 +192,20 @@ fn tagged() void = {
assert(_i && _u && _v);
};
+fn tuples() void = {
+ let ty = types::reflect(type((int, int, int)));
+ assert(ty.sz == size(int) * 3);
+ assert(ty.al == size(int));
+ let tu = ty.repr as types::tuple;
+ assert(len(tu) == 3);
+ assert(tu[0].offs == 0);
+ assert(tu[0].type_ == type(int));
+ assert(tu[1].offs == 4);
+ assert(tu[1].type_ == type(int));
+ assert(tu[2].offs == 8);
+ assert(tu[2].type_ == type(int));
+};
+
export fn main() void = {
builtins();
aliases();
@@ -202,4 +216,5 @@ export fn main() void = {
functions();
struct_union();
tagged();
+ tuples();
};