commit a00faaebe0152adec05b27f87738ed6f5f0ea133
parent c3cb347529f031b0e3fc441e76aab1e91e75dc1a
Author: Drew DeVault <sir@cmpwn.com>
Date: Thu, 14 Jan 2021 11:00:45 -0500
Move type_hash into types.c
Diffstat:
4 files changed, 87 insertions(+), 86 deletions(-)
diff --git a/include/type_store.h b/include/type_store.h
@@ -17,8 +17,6 @@ struct type_store {
struct context *check_context;
};
-const struct type *type_dealias(const struct type *type);
-
bool type_is_assignable(struct type_store *store,
const struct type *to, const struct type *from);
bool type_is_castable(const struct type *to, const struct type *from);
diff --git a/include/types.h b/include/types.h
@@ -120,6 +120,7 @@ struct type {
};
const struct type *type_dereference(const struct type *type);
+const struct type *type_dealias(const struct type *type);
const struct struct_field *type_get_field(
const struct type *type, const char *name);
@@ -129,6 +130,8 @@ bool type_is_integer(const struct type *type);
bool type_is_numeric(const struct type *type);
bool type_is_float(const struct type *type);
+uint64_t type_hash(const struct type *type);
+
// Built-in type singletons
extern const struct type
// Primitive
diff --git a/src/type_store.c b/src/type_store.c
@@ -26,15 +26,6 @@ ast_array_len(struct type_store *store, const struct ast_type *atype)
return (size_t)out.constant.uval;
}
-const struct type *
-type_dealias(const struct type *type)
-{
- while (type->storage == TYPE_STORAGE_ALIAS) {
- type = type->alias.type;
- }
- return type;
-}
-
bool
type_is_assignable(struct type_store *store,
const struct type *to,
@@ -288,79 +279,6 @@ builtin_type_for_storage(enum type_storage storage, bool is_const)
assert(0); // Unreachable
}
-static uint64_t
-type_hash(struct type_store *store, const struct type *type)
-{
- // XXX: ARCH
- uint64_t hash = FNV1A_INIT;
- hash = fnv1a(hash, type->storage);
- hash = fnv1a(hash, type->flags);
- switch (type->storage) {
- case TYPE_STORAGE_BOOL:
- case TYPE_STORAGE_CHAR:
- case TYPE_STORAGE_F32:
- case TYPE_STORAGE_F64:
- case TYPE_STORAGE_I8:
- case TYPE_STORAGE_I16:
- case TYPE_STORAGE_I32:
- case TYPE_STORAGE_I64:
- case TYPE_STORAGE_INT:
- case TYPE_STORAGE_NULL:
- case TYPE_STORAGE_RUNE:
- case TYPE_STORAGE_SIZE:
- case TYPE_STORAGE_U8:
- case TYPE_STORAGE_U16:
- case TYPE_STORAGE_U32:
- case TYPE_STORAGE_U64:
- case TYPE_STORAGE_UINT:
- case TYPE_STORAGE_UINTPTR:
- case TYPE_STORAGE_VOID:
- case TYPE_STORAGE_STRING:
- break; // built-ins
- case TYPE_STORAGE_ALIAS:
- for (const struct identifier *ident = &type->alias.ident; ident;
- ident = ident->ns) {
- hash = fnv1a_s(hash, ident->name);
- }
- hash = fnv1a_u64(hash, type_hash(store, type->alias.type));
- break;
- case TYPE_STORAGE_ARRAY:
- hash = fnv1a_u64(hash, type_hash(store, type->array.members));
- hash = fnv1a_u64(hash, type->array.length);
- break;
- case TYPE_STORAGE_FUNCTION:
- hash = fnv1a_u64(hash, type_hash(store, type->func.result));
- hash = fnv1a(hash, type->func.variadism);
- hash = fnv1a(hash, type->func.flags);
- for (struct type_func_param *param = type->func.params;
- param; param = param->next) {
- hash = fnv1a_u64(hash, type_hash(store, param->type));
- }
- break;
- case TYPE_STORAGE_ENUM:
- assert(0); // TODO
- case TYPE_STORAGE_POINTER:
- hash = fnv1a(hash, type->pointer.flags);
- hash = fnv1a_u64(hash, type_hash(store, type->pointer.referent));
- break;
- case TYPE_STORAGE_SLICE:
- hash = fnv1a_u64(hash, type_hash(store, type->array.members));
- break;
- case TYPE_STORAGE_STRUCT:
- case TYPE_STORAGE_UNION:
- for (const struct struct_field *field = type->struct_union.fields;
- field; field = field->next) {
- hash = fnv1a_s(hash, field->name);
- hash = fnv1a_u64(hash, type_hash(store, field->type));
- hash = fnv1a_u64(hash, field->offset);
- }
- break;
- case TYPE_STORAGE_TAGGED_UNION:
- assert(0); // TODO
- }
- return hash;
-}
-
static const struct type *
builtin_for_atype(const struct ast_type *atype)
{
@@ -751,7 +669,7 @@ type_store_lookup_type(struct type_store *store, const struct type *type)
return builtin;
}
- uint64_t hash = type_hash(store, type);
+ uint64_t hash = type_hash(type);
struct type_bucket **next = &store->buckets[hash % TYPE_STORE_BUCKETS],
*bucket = NULL;
diff --git a/src/types.c b/src/types.c
@@ -2,7 +2,7 @@
#include <stdbool.h>
#include <string.h>
#include "types.h"
-#include "type_store.h"
+#include "util.h"
const struct type *
type_dereference(const struct type *type)
@@ -20,6 +20,15 @@ type_dereference(const struct type *type)
}
}
+const struct type *
+type_dealias(const struct type *type)
+{
+ while (type->storage == TYPE_STORAGE_ALIAS) {
+ type = type->alias.type;
+ }
+ return type;
+}
+
const struct struct_field *
type_get_field(const struct type *type, const char *name)
{
@@ -228,6 +237,79 @@ type_is_signed(const struct type *type)
assert(0); // Unreachable
}
+uint64_t
+type_hash(const struct type *type)
+{
+ // XXX: ARCH
+ uint64_t hash = FNV1A_INIT;
+ hash = fnv1a(hash, type->storage);
+ hash = fnv1a(hash, type->flags);
+ switch (type->storage) {
+ case TYPE_STORAGE_BOOL:
+ case TYPE_STORAGE_CHAR:
+ case TYPE_STORAGE_F32:
+ case TYPE_STORAGE_F64:
+ case TYPE_STORAGE_I8:
+ case TYPE_STORAGE_I16:
+ case TYPE_STORAGE_I32:
+ case TYPE_STORAGE_I64:
+ case TYPE_STORAGE_INT:
+ case TYPE_STORAGE_NULL:
+ case TYPE_STORAGE_RUNE:
+ case TYPE_STORAGE_SIZE:
+ case TYPE_STORAGE_U8:
+ case TYPE_STORAGE_U16:
+ case TYPE_STORAGE_U32:
+ case TYPE_STORAGE_U64:
+ case TYPE_STORAGE_UINT:
+ case TYPE_STORAGE_UINTPTR:
+ case TYPE_STORAGE_VOID:
+ case TYPE_STORAGE_STRING:
+ break; // built-ins
+ case TYPE_STORAGE_ALIAS:
+ for (const struct identifier *ident = &type->alias.ident; ident;
+ ident = ident->ns) {
+ hash = fnv1a_s(hash, ident->name);
+ }
+ hash = fnv1a_u64(hash, type_hash(type->alias.type));
+ break;
+ case TYPE_STORAGE_ARRAY:
+ hash = fnv1a_u64(hash, type_hash(type->array.members));
+ hash = fnv1a_u64(hash, type->array.length);
+ break;
+ case TYPE_STORAGE_FUNCTION:
+ hash = fnv1a_u64(hash, type_hash(type->func.result));
+ hash = fnv1a(hash, type->func.variadism);
+ hash = fnv1a(hash, type->func.flags);
+ for (struct type_func_param *param = type->func.params;
+ param; param = param->next) {
+ hash = fnv1a_u64(hash, type_hash(param->type));
+ }
+ break;
+ case TYPE_STORAGE_ENUM:
+ assert(0); // TODO
+ case TYPE_STORAGE_POINTER:
+ hash = fnv1a(hash, type->pointer.flags);
+ hash = fnv1a_u64(hash, type_hash(type->pointer.referent));
+ break;
+ case TYPE_STORAGE_SLICE:
+ hash = fnv1a_u64(hash, type_hash(type->array.members));
+ break;
+ case TYPE_STORAGE_STRUCT:
+ case TYPE_STORAGE_UNION:
+ for (const struct struct_field *field = type->struct_union.fields;
+ field; field = field->next) {
+ hash = fnv1a_s(hash, field->name);
+ hash = fnv1a_u64(hash, type_hash(field->type));
+ hash = fnv1a_u64(hash, field->offset);
+ }
+ break;
+ case TYPE_STORAGE_TAGGED_UNION:
+ assert(0); // TODO
+ }
+ return hash;
+}
+
// Built-in type singletons
const struct type builtin_type_bool = {
.storage = TYPE_STORAGE_BOOL,