From 1d943da0cf9154e7ce78ce867cdbb91531c5d78e Mon Sep 17 00:00:00 2001 From: Matthew Sotoudeh Date: Tue, 25 Jul 2023 14:58:33 -0700 Subject: initial dietc commit --- type_helpers.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 type_helpers.c (limited to 'type_helpers.c') diff --git a/type_helpers.c b/type_helpers.c new file mode 100644 index 0000000..0f6b022 --- /dev/null +++ b/type_helpers.c @@ -0,0 +1,78 @@ +#include +#include "chibicc.h" + +unsigned long hash_type(Type *type) { + unsigned long hash = 6997; + if (!type) return hash; + if (type->hashing) return hash; + type->hashing = 1; +#define EXTEND_HASH(v) hash = (hash * 33) ^ (size_t)(v) + EXTEND_HASH(type->kind); + EXTEND_HASH(type->size); + EXTEND_HASH(type->align); + EXTEND_HASH(type->is_unsigned); + EXTEND_HASH(type->is_atomic); + // EXTEND_HASH(hash_type(type->origin)); + + EXTEND_HASH(hash_type(type->base)); + EXTEND_HASH(type->array_len); + EXTEND_HASH(type->vla_len); + EXTEND_HASH(type->vla_size); + EXTEND_HASH(type->members); + + // TODO: assume the members pointers are actually same? + // for (Member *m = type->members; m; m = m->next) { + // EXTEND_HASH(hash_type(m->ty)); + // EXTEND_HASH(m->name); // token + // EXTEND_HASH(m->idx); + // EXTEND_HASH(m->align); + // EXTEND_HASH(m->offset); + // EXTEND_HASH(m->is_bitfield); + // EXTEND_HASH(m->bit_offset); + // EXTEND_HASH(m->bit_width); + // } + EXTEND_HASH(type->is_flexible); + EXTEND_HASH(type->is_packed); + + EXTEND_HASH(hash_type(type->return_ty)); + EXTEND_HASH(hash_type(type->params)); + EXTEND_HASH(type->is_variadic); + // EXTEND_HASH(type->next); + + type->hashing = 0; + return hash; +} + +int definitely_same_type(Type *type1, Type *type2) { + if (!type1 || !type2) return type1 == type2; + if (type1->hashing != type2->hashing) return 0; + if (type1->hashing) return type1 == type2; + type1->hashing = 1; + type2->hashing = 1; +#define FIELD_CHECK(field) if (type1->field != type2->field) goto disequal +#define RECURSE_CHECK(field) if (!definitely_same_type(type1->field, type2->field)) goto disequal + FIELD_CHECK(kind); + FIELD_CHECK(size); + FIELD_CHECK(align); + FIELD_CHECK(is_unsigned); + FIELD_CHECK(is_atomic); + // RECURSE_CHECK(origin); + RECURSE_CHECK(base); + FIELD_CHECK(array_len); + FIELD_CHECK(vla_len); + FIELD_CHECK(vla_size); + FIELD_CHECK(members); + FIELD_CHECK(is_flexible); + FIELD_CHECK(is_packed); + RECURSE_CHECK(return_ty); + FIELD_CHECK(params); + FIELD_CHECK(is_variadic); + // RECURSE_CHECK(next); + type1->hashing = 0; + type2->hashing = 0; + return 1; +disequal: + type1->hashing = 0; + type2->hashing = 0; + return 0; +} -- cgit v1.2.3