aboutsummaryrefslogtreecommitdiff
path: root/src/types.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/types.cpp')
-rw-r--r--src/types.cpp70
1 files changed, 64 insertions, 6 deletions
diff --git a/src/types.cpp b/src/types.cpp
index 0c6702103..effa8ef64 100644
--- a/src/types.cpp
+++ b/src/types.cpp
@@ -1377,14 +1377,20 @@ gb_internal bool is_type_ordered_numeric(Type *t) {
gb_internal bool is_type_constant_type(Type *t) {
t = core_type(t);
if (t == nullptr) { return false; }
- if (t->kind == Type_Basic) {
+ switch (t->kind) {
+ case Type_Basic:
+ if (t->Basic.kind == Basic_typeid) {
+ return true;
+ }
return (t->Basic.flags & BasicFlag_ConstantType) != 0;
- }
- if (t->kind == Type_BitSet) {
+ case Type_BitSet:
return true;
- }
- if (t->kind == Type_Proc) {
+ case Type_Proc:
return true;
+ case Type_Array:
+ return is_type_constant_type(t->Array.elem);
+ case Type_EnumeratedArray:
+ return is_type_constant_type(t->EnumeratedArray.elem);
}
return false;
}
@@ -2507,18 +2513,70 @@ gb_internal bool type_has_nil(Type *t) {
return false;
}
+gb_internal bool is_type_union_constantable(Type *type) {
+ Type *bt = base_type(type);
+ GB_ASSERT(bt->kind == Type_Union);
+
+ if (bt->Union.variants.count == 0) {
+ return true;
+ } else if (bt->Union.variants.count == 1) {
+ return is_type_constant_type(bt->Union.variants[0]);
+ }
+
+ for (Type *v : bt->Union.variants) {
+ if (!is_type_constant_type(v)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+gb_internal bool is_type_raw_union_constantable(Type *type) {
+ Type *bt = base_type(type);
+ GB_ASSERT(bt->kind == Type_Struct);
+ GB_ASSERT(bt->Struct.is_raw_union);
+
+ for (Entity *f : bt->Struct.fields) {
+ if (!is_type_constant_type(f->type)) {
+ return false;
+ }
+ }
+ // return true;
+ return false; // Disable raw union constants for the time being
+}
+
gb_internal bool elem_type_can_be_constant(Type *t) {
t = base_type(t);
if (t == t_invalid) {
return false;
}
- if (is_type_any(t) || is_type_union(t) || is_type_raw_union(t)) {
+ if (is_type_any(t)) {
return false;
}
+ if (is_type_raw_union(t)) {
+ return is_type_raw_union_constantable(t);
+ }
+ if (is_type_union(t)) {
+ return is_type_union_constantable(t);
+ }
return true;
}
+gb_internal bool elem_cannot_be_constant(Type *t) {
+ if (is_type_any(t)) {
+ return true;
+ }
+ if (is_type_union(t)) {
+ return !is_type_union_constantable(t);
+ }
+ if (is_type_raw_union(t)) {
+ return !is_type_raw_union_constantable(t);
+ }
+ return false;
+}
+
+
gb_internal bool is_type_lock_free(Type *t) {
t = core_type(t);
if (t == t_invalid) {