aboutsummaryrefslogtreecommitdiff
path: root/src/types.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/types.cpp')
-rw-r--r--src/types.cpp48
1 files changed, 46 insertions, 2 deletions
diff --git a/src/types.cpp b/src/types.cpp
index f5d1bb4a9..74cc264da 100644
--- a/src/types.cpp
+++ b/src/types.cpp
@@ -127,6 +127,7 @@ struct TypeUnion {
Scope *scope; \
}) \
TYPE_KIND(Pointer, struct { Type *elem; }) \
+ TYPE_KIND(Opaque, struct { Type *elem; }) \
TYPE_KIND(Array, struct { \
Type *elem; \
i64 count; \
@@ -400,6 +401,7 @@ gb_global Type *t_type_info_enum = nullptr;
gb_global Type *t_type_info_map = nullptr;
gb_global Type *t_type_info_bit_field = nullptr;
gb_global Type *t_type_info_bit_set = nullptr;
+gb_global Type *t_type_info_opaque = nullptr;
gb_global Type *t_type_info_named_ptr = nullptr;
gb_global Type *t_type_info_integer_ptr = nullptr;
@@ -423,6 +425,7 @@ gb_global Type *t_type_info_enum_ptr = nullptr;
gb_global Type *t_type_info_map_ptr = nullptr;
gb_global Type *t_type_info_bit_field_ptr = nullptr;
gb_global Type *t_type_info_bit_set_ptr = nullptr;
+gb_global Type *t_type_info_opaque_ptr = nullptr;
gb_global Type *t_allocator = nullptr;
gb_global Type *t_allocator_ptr = nullptr;
@@ -461,6 +464,19 @@ Type *base_type(Type *t) {
return t;
}
+Type *strip_opaque_type(Type *t) {
+ for (;;) {
+ if (t == nullptr) {
+ break;
+ }
+ if (t->kind != Type_Opaque) {
+ break;
+ }
+ t = t->Opaque.elem;
+ }
+ return t;
+}
+
Type *base_enum_type(Type *t) {
Type *bt = base_type(t);
if (bt != nullptr &&
@@ -486,6 +502,9 @@ Type *core_type(Type *t) {
case Type_Enum:
t = t->Enum.base_type;
continue;
+ case Type_Opaque:
+ t = t->Opaque.elem;
+ continue;
}
break;
}
@@ -519,6 +538,12 @@ Type *alloc_type_generic(Scope *scope, i64 id, String name, Type *specialized) {
return t;
}
+Type *alloc_type_opaque(Type *elem) {
+ Type *t = alloc_type(Type_Opaque);
+ t->Opaque.elem = elem;
+ return t;
+}
+
Type *alloc_type_pointer(Type *elem) {
Type *t = alloc_type(Type_Pointer);
t->Pointer.elem = elem;
@@ -819,8 +844,10 @@ bool is_type_tuple(Type *t) {
t = base_type(t);
return t->kind == Type_Tuple;
}
-
-
+bool is_type_opaque(Type *t) {
+ t = base_type(t);
+ return t->kind == Type_Opaque;
+}
bool is_type_uintptr(Type *t) {
if (t->kind == Type_Basic) {
return (t->Basic.kind == Basic_uintptr);
@@ -1212,6 +1239,8 @@ bool type_has_nil(Type *t) {
return true;
case Type_Struct:
return false;
+ case Type_Opaque:
+ return true;
}
return false;
}
@@ -1257,6 +1286,9 @@ bool is_type_comparable(Type *t) {
case Type_BitSet:
return true;
+
+ case Type_Opaque:
+ return is_type_comparable(t->Opaque.elem);
}
return false;
}
@@ -1294,6 +1326,12 @@ bool are_types_identical(Type *x, Type *y) {
}
break;
+ case Type_Opaque:
+ if (y->kind == Type_Opaque) {
+ return are_types_identical(x->Opaque.elem, y->Opaque.elem);
+ }
+ break;
+
case Type_Basic:
if (y->kind == Type_Basic) {
return x->Basic.kind == y->Basic.kind;
@@ -2061,6 +2099,9 @@ i64 type_align_of_internal(Type *t, TypePath *path) {
return align;
}
+ case Type_Opaque:
+ return type_align_of_internal(t->Opaque.elem, path);
+
case Type_DynamicArray:
// data, count, capacity, allocator
return build_context.word_size;
@@ -2265,6 +2306,9 @@ i64 type_size_of_internal(Type *t, TypePath *path) {
case Type_Pointer:
return build_context.word_size;
+ case Type_Opaque:
+ return type_size_of_internal(t->Opaque.elem, path);
+
case Type_Array: {
i64 count, align, size, alignment;
count = t->Array.count;