mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-28 08:11:49 -07:00
union #shared_nil
This adds a feature to `union` which requires all the variants to have a `nil` value and on assign to the union, checks whether that value is `nil` or not. If the value is `nil`, the union will be `nil` (thus sharing the `nil` value)
This commit is contained in:
@@ -1176,10 +1176,35 @@ void lb_emit_store_union_variant_tag(lbProcedure *p, lbValue parent, Type *varia
|
||||
}
|
||||
|
||||
void lb_emit_store_union_variant(lbProcedure *p, lbValue parent, lbValue variant, Type *variant_type) {
|
||||
lbValue underlying = lb_emit_conv(p, parent, alloc_type_pointer(variant_type));
|
||||
Type *pt = base_type(type_deref(parent.type));
|
||||
GB_ASSERT(pt->kind == Type_Union);
|
||||
if (pt->Union.kind == UnionType_shared_nil) {
|
||||
lbBlock *if_nil = lb_create_block(p, "shared_nil.if_nil");
|
||||
lbBlock *if_not_nil = lb_create_block(p, "shared_nil.if_not_nil");
|
||||
lbBlock *done = lb_create_block(p, "shared_nil.done");
|
||||
|
||||
lb_emit_store(p, underlying, variant);
|
||||
lb_emit_store_union_variant_tag(p, parent, variant_type);
|
||||
lbValue cond_is_nil = lb_emit_comp_against_nil(p, Token_CmpEq, variant);
|
||||
lb_emit_if(p, cond_is_nil, if_nil, if_not_nil);
|
||||
|
||||
lb_start_block(p, if_nil);
|
||||
lb_emit_store(p, parent, lb_const_nil(p->module, type_deref(parent.type)));
|
||||
lb_emit_jump(p, done);
|
||||
|
||||
lb_start_block(p, if_not_nil);
|
||||
lbValue underlying = lb_emit_conv(p, parent, alloc_type_pointer(variant_type));
|
||||
lb_emit_store(p, underlying, variant);
|
||||
lb_emit_store_union_variant_tag(p, parent, variant_type);
|
||||
lb_emit_jump(p, done);
|
||||
|
||||
lb_start_block(p, done);
|
||||
|
||||
|
||||
} else {
|
||||
lbValue underlying = lb_emit_conv(p, parent, alloc_type_pointer(variant_type));
|
||||
|
||||
lb_emit_store(p, underlying, variant);
|
||||
lb_emit_store_union_variant_tag(p, parent, variant_type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user