aboutsummaryrefslogtreecommitdiff
path: root/src/types.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/types.cpp')
-rw-r--r--src/types.cpp51
1 files changed, 51 insertions, 0 deletions
diff --git a/src/types.cpp b/src/types.cpp
index 56b310867..0ca239bde 100644
--- a/src/types.cpp
+++ b/src/types.cpp
@@ -2403,6 +2403,57 @@ bool is_type_simple_compare(Type *t) {
return false;
}
+bool is_type_load_safe(Type *type) {
+ GB_ASSERT(type != nullptr);
+ type = core_type(core_array_type(type));
+ switch (type->kind) {
+ case Type_Basic:
+ return (type->Basic.flags & (BasicFlag_Boolean|BasicFlag_Numeric|BasicFlag_Rune)) != 0;
+
+ case Type_BitSet:
+ if (type->BitSet.underlying) {
+ return is_type_load_safe(type->BitSet.underlying);
+ }
+ return true;
+
+ case Type_RelativePointer:
+ case Type_RelativeSlice:
+ return true;
+
+ case Type_Pointer:
+ case Type_MultiPointer:
+ case Type_Slice:
+ case Type_DynamicArray:
+ case Type_Proc:
+ case Type_SoaPointer:
+ return false;
+
+ case Type_Enum:
+ case Type_EnumeratedArray:
+ case Type_Array:
+ case Type_SimdVector:
+ case Type_Matrix:
+ GB_PANIC("should never be hit");
+ return false;
+
+ case Type_Struct:
+ for_array(i, type->Struct.fields) {
+ if (!is_type_load_safe(type->Struct.fields[i]->type)) {
+ return false;
+ }
+ }
+ return type_size_of(type) > 0;
+ case Type_Union:
+ for_array(i, type->Union.variants) {
+ if (!is_type_load_safe(type->Union.variants[i])) {
+ return false;
+ }
+ }
+ return type_size_of(type) > 0;
+ }
+ return false;
+}
+
String lookup_subtype_polymorphic_field(Type *dst, Type *src) {
Type *prev_src = src;
// Type *prev_dst = dst;