From b24a164634fd0ebaaea98ec1ba40324ee0cc96df Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Thu, 29 Dec 2016 16:36:43 +0000 Subject: [PATCH] Stop using type indexes to generate unique record names --- src/cgen.c | 2 +- src/lower.c | 45 +++++++++++++++---------- src/vcode.c | 85 +++++++++++++++++++---------------------------- src/vcode.h | 9 +++-- test/test_lower.c | 16 ++++----- 5 files changed, 76 insertions(+), 81 deletions(-) diff --git a/src/cgen.c b/src/cgen.c index b3d76118..15c795f3 100644 --- a/src/cgen.c +++ b/src/cgen.c @@ -230,7 +230,7 @@ static LLVMTypeRef cgen_type(vcode_type_t type) case VCODE_TYPE_RECORD: { - char *name LOCAL = vtype_record_name(type); + const char *name = istr(vtype_record_name(type)); LLVMTypeRef lltype = LLVMGetTypeByName(module, name); if (lltype != NULL) return lltype; diff --git a/src/lower.c b/src/lower.c index 73caa061..ef18a538 100644 --- a/src/lower.c +++ b/src/lower.c @@ -332,15 +332,18 @@ static vcode_type_t lower_array_type(type_t type) return vtype_uarray(array_dimension(type), elem_type, elem_bounds); } -static vcode_bookmark_t lower_record_bookmark(type_t type) +static ident_t lower_record_unique_name(type_t type) { // If a record type is not qualified with a package name then add a unique - // index to its type name to avoid collisions - vcode_bookmark_t uniq = { .type = NULL }; + // suffix to its type name to avoid collisions ident_t name = type_ident(type); - if (ident_until(name, '.') == name && type_has_index(type)) - uniq.type = type; - return uniq; + if (ident_until(name, '.') == name) { + char buf[32]; + checked_sprintf(buf, sizeof(buf), "%"PRIxPTR, (uintptr_t)type); + return ident_prefix(name, ident_new(buf), '@'); + } + else + return name; } static vcode_type_t lower_type(type_t type) @@ -373,18 +376,17 @@ static vcode_type_t lower_type(type_t type) case T_RECORD: { - ident_t name = type_ident(type); - vcode_bookmark_t uniq = lower_record_bookmark(type); - vcode_type_t record = vtype_named_record(name, uniq, false); + ident_t name = lower_record_unique_name(type); + vcode_type_t record = vtype_find_named_record(name); if (record == VCODE_INVALID_TYPE) { - record = vtype_named_record(name, uniq, true); + vtype_named_record(name, NULL, 0); // Forward-declare the name const int nfields = type_fields(type); vcode_type_t fields[nfields]; for (int i = 0; i < nfields; i++) fields[i] = lower_type(tree_type(type_field(type, i))); - vtype_set_record_fields(record, fields, nfields); + record = vtype_named_record(name, fields, nfields); } return record; @@ -392,12 +394,9 @@ static vcode_type_t lower_type(type_t type) case T_PROTECTED: { - ident_t name = type_ident(type); - vcode_bookmark_t uniq = lower_record_bookmark(type); - vcode_type_t record = vtype_named_record(name, uniq, false); + ident_t name = lower_record_unique_name(type); + vcode_type_t record = vtype_find_named_record(name); if (record == VCODE_INVALID_TYPE) { - record = vtype_named_record(name, uniq, true); - tree_t body = type_body(type); const int ndecls = tree_decls(body); @@ -411,7 +410,7 @@ static vcode_type_t lower_type(type_t type) fields[nfields++] = lower_type(tree_type(decl)); } - vtype_set_record_fields(record, fields, nfields); + record = vtype_named_record(name, fields, nfields); } return record; @@ -4286,6 +4285,15 @@ static void lower_file_decl(tree_t decl) } } +static void lower_type_decl(tree_t decl) +{ + return; + type_t type = tree_type(decl); + if (type_is_record(type)) { + assert(false); + } +} + static void lower_decl(tree_t decl) { switch (tree_kind(decl)) { @@ -4307,6 +4315,9 @@ static void lower_decl(tree_t decl) break; case T_TYPE_DECL: + lower_type_decl(decl); + break; + case T_HIER: case T_ALIAS: case T_FUNC_DECL: diff --git a/src/vcode.c b/src/vcode.c index 9a11b715..0ec698dd 100644 --- a/src/vcode.c +++ b/src/vcode.c @@ -149,7 +149,6 @@ typedef struct { vcode_type_t base; struct { ident_t name; - vcode_bookmark_t uniq; vcode_type_array_t fields; }; }; @@ -239,7 +238,7 @@ struct vcode_unit { VCODE_FOR_EACH_OP(name) if (name->kind == k) #define VCODE_MAGIC 0x76636f64 -#define VCODE_VERSION 4 +#define VCODE_VERSION 5 #define VCODE_CHECK_UNIONS 0 static vcode_unit_t active_unit = NULL; @@ -1137,10 +1136,7 @@ static void vcode_dump_one_type(vcode_type_t type) break; case VCODE_TYPE_RECORD: - { - char *name LOCAL = vtype_record_name(type); - printf("%s{}", name); - } + printf("%s{}", istr(vt->name)); break; case VCODE_TYPE_FILE: @@ -1226,11 +1222,7 @@ void vcode_dump(void) const vtype_t *t = &(vu->types.items[i]); if (t->kind == VCODE_TYPE_RECORD) { int col = 0; - if (t->uniq.type != NULL && type_has_index(t->uniq.type)) - col += color_printf(" $magenta$%s.%u$$", istr(t->name), - type_index(t->uniq.type)); - else - col += color_printf(" $magenta$%s$$", istr(t->name)); + col += color_printf(" $magenta$%s$$", istr(t->name)); vcode_dump_tab(col, 40); color_printf("$cyan${"); for (unsigned i = 0; i < t->fields.count; i++) { @@ -2188,7 +2180,7 @@ bool vtype_eq(vcode_type_t a, vcode_type_t b) case VCODE_TYPE_FILE: return vtype_eq(at->base, bt->base); case VCODE_TYPE_RECORD: - return at->name == bt->name && at->uniq.type == bt->uniq.type; + return at->name == bt->name; case VCODE_TYPE_IMAGE_MAP: return false; } @@ -2284,28 +2276,45 @@ vcode_type_t vtype_carray(int size, vcode_type_t elem, vcode_type_t bounds) return vtype_new(n); } -vcode_type_t vtype_named_record(ident_t name, vcode_bookmark_t uniq, bool create) +vcode_type_t vtype_find_named_record(ident_t name) { assert(active_unit != NULL); for (int i = 0; i < active_unit->types.count; i++) { vtype_t *other = &(active_unit->types.items[i]); - if (other->kind == VCODE_TYPE_RECORD && other->name == name - && other->uniq.type == uniq.type) + if (other->kind == VCODE_TYPE_RECORD && other->name == name) return MAKE_HANDLE(active_unit->depth, i); } - if (create) { - vtype_t *n = vtype_array_alloc(&(active_unit->types)); - memset(n, '\0', sizeof(vtype_t)); - n->kind = VCODE_TYPE_RECORD; - n->name = name; - n->uniq = uniq; + return VCODE_INVALID_TYPE; +} - return vtype_new(n); +vcode_type_t vtype_named_record(ident_t name, const vcode_type_t *field_types, + int nfields) +{ + assert(active_unit != NULL); + + vtype_t *data = NULL; + vcode_type_t handle = vtype_find_named_record(name); + if (handle == VCODE_INVALID_TYPE) { + data = vtype_array_alloc(&(active_unit->types)); + memset(data, '\0', sizeof(vtype_t)); + data->kind = VCODE_TYPE_RECORD; + data->name = name; + + handle = vtype_new(data); } - else - return VCODE_INVALID_TYPE; + else { + data = vcode_type_data(handle); + VCODE_ASSERT(data->fields.count == 0, + "record type %s already defined", istr(name)); + } + + vcode_type_array_resize(&(data->fields), 0, VCODE_INVALID_TYPE); + for (int i = 0; i < nfields; i++) + vcode_type_array_add(&(data->fields), field_types[i]); + + return handle; } vcode_type_t vtype_uarray(int ndim, vcode_type_t elem, vcode_type_t bounds) @@ -2470,26 +2479,11 @@ vcode_type_t vtype_field(vcode_type_t type, int field) return vcode_type_array_nth(&(vt->fields), field); } -void vtype_set_record_fields(vcode_type_t type, const vcode_type_t *field_types, - int nfields) -{ - vtype_t *n = vcode_type_data(type); - - if (n->fields.count > 0) - vcode_type_array_resize(&(n->fields), 0, VCODE_INVALID_TYPE); - - for (int i = 0; i < nfields; i++) - vcode_type_array_add(&(n->fields), field_types[i]); -} - -char *vtype_record_name(vcode_type_t type) +ident_t vtype_record_name(vcode_type_t type) { vtype_t *vt = vcode_type_data(type); assert(vt->kind == VCODE_TYPE_RECORD); - if (vt->uniq.type != NULL && type_has_index(vt->uniq.type)) - return xasprintf("%s.%u", istr(vt->name), type_index(vt->uniq.type)); - else - return xasprintf("%s", istr(vt->name)); + return vt->name; } vcode_type_t vtype_pointed(vcode_type_t type) @@ -4870,10 +4864,6 @@ static void vcode_write_unit(vcode_unit_t unit, fbuf_t *f, case VCODE_TYPE_RECORD: ident_write(t->name, ident_wr_ctx); - if (t->uniq.type) - write_u32(type_index(t->uniq.type), f); - else - write_u32(0, f); write_u32(t->fields.count, f); for (unsigned j = 0; j < t->fields.count; j++) write_u32(t->fields.items[j], f); @@ -5067,11 +5057,6 @@ static bool vcode_read_unit(fbuf_t *f, tree_rd_ctx_t tree_ctx, case VCODE_TYPE_RECORD: { t->name = ident_read(ident_rd_ctx); - const uint32_t index = read_u32(f); - if (index != 0) - t->uniq.type = type_read_recall(tree_ctx, index); - else - t->uniq.type = NULL; vcode_type_array_resize(&(t->fields), read_u32(f), 0); for (unsigned j = 0; j < t->fields.count; j++) t->fields.items[j] = read_u32(f); diff --git a/src/vcode.h b/src/vcode.h index 9918e657..3e2b309a 100644 --- a/src/vcode.h +++ b/src/vcode.h @@ -203,10 +203,9 @@ vcode_type_t vtype_offset(void); vcode_type_t vtype_time(void); vcode_type_t vtype_char(void); vcode_type_t vtype_image_map(void); -vcode_type_t vtype_named_record(ident_t name, vcode_bookmark_t uniq, - bool create); -void vtype_set_record_fields(vcode_type_t type, - const vcode_type_t *field_types, int nfields); +vcode_type_t vtype_find_named_record(ident_t name); +vcode_type_t vtype_named_record(ident_t name, const vcode_type_t *field_types, + int nfields); vcode_type_t vtype_file(vcode_type_t base); bool vtype_eq(vcode_type_t a, vcode_type_t b); bool vtype_includes(vcode_type_t type, vcode_type_t bounds); @@ -221,7 +220,7 @@ unsigned vtype_size(vcode_type_t type); int vtype_fields(vcode_type_t type); vcode_type_t vtype_field(vcode_type_t type, int field); vcode_type_t vtype_base(vcode_type_t type); -char *vtype_record_name(vcode_type_t type); +ident_t vtype_record_name(vcode_type_t type); vcode_type_t vtype_real(void); vcode_unit_t vcode_find_unit(ident_t name); vcode_unit_t vcode_unit_next(vcode_unit_t unit); diff --git a/test/test_lower.c b/test/test_lower.c index c59462b7..25259bce 100644 --- a/test/test_lower.c +++ b/test/test_lower.c @@ -2184,11 +2184,11 @@ START_TEST(test_rectype) fail_unless(vtype_kind(0) == VCODE_TYPE_RECORD); fail_unless(vtype_kind(1) == VCODE_TYPE_RECORD); - char *r2_name LOCAL = vtype_record_name(0); - fail_unless(strncmp(r2_name, "R2.", 3) == 0); + ident_t r2_name = vtype_record_name(0); + fail_unless(strncmp(istr(r2_name), "R2@", 3) == 0); - char *r1_name LOCAL = vtype_record_name(1); - fail_unless(strcmp(r1_name, "WORK.RECTYPE.R1") == 0); + ident_t r1_name = vtype_record_name(1); + fail_unless(icmp(r1_name, "WORK.RECTYPE.R1")); } END_TEST @@ -2244,11 +2244,11 @@ START_TEST(test_issue167) fail_unless(vtype_kind(0) == VCODE_TYPE_RECORD); fail_unless(vtype_kind(2) == VCODE_TYPE_RECORD); - char *p1_name LOCAL = vtype_record_name(0); - fail_unless(strcmp(p1_name, "WORK.PKG.P1") == 0); + ident_t p1_name = vtype_record_name(0); + fail_unless(icmp(p1_name, "WORK.PKG.P1")); - char *p2_name LOCAL = vtype_record_name(2); - fail_unless(strncmp(p2_name, "P2.", 3) == 0); + ident_t p2_name = vtype_record_name(2); + fail_unless(strncmp(istr(p2_name), "P2@", 3) == 0); } END_TEST -- 2.39.2