mirror of
https://github.com/odin-lang/Odin.git
synced 2026-09-02 10:13:35 +00:00
Merge pull request #7087 from korvahkh/const-union-fixes
Implement fixes for constant unions
This commit is contained in:
@@ -3207,7 +3207,7 @@ gb_internal lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
|
||||
Type *elem = base_array_type(dst);
|
||||
lbValue e = lb_emit_conv(p, value, elem);
|
||||
lbAddr v = lb_add_local_generated(p, t, false);
|
||||
lbValue zero = lb_const_value(p->module, elem, exact_value_i64(0), elem, LB_CONST_CONTEXT_DEFAULT_ALLOW_LOCAL);
|
||||
lbValue zero = lb_const_value(p->module, elem, exact_value_i64(0), LB_CONST_CONTEXT_DEFAULT_ALLOW_LOCAL);
|
||||
for (i64 j = 0; j < dst->Matrix.column_count; j++) {
|
||||
for (i64 i = 0; i < dst->Matrix.row_count; i++) {
|
||||
lbValue ptr = lb_emit_matrix_epi(p, v.addr, i, j);
|
||||
@@ -3244,7 +3244,7 @@ gb_internal lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
|
||||
lb_emit_store(p, d, s);
|
||||
} else if (i == j) {
|
||||
lbValue d = lb_emit_matrix_epi(p, v.addr, i, j);
|
||||
lbValue s = lb_const_value(p->module, dst->Matrix.elem, exact_value_i64(1), dst->Matrix.elem, LB_CONST_CONTEXT_DEFAULT_ALLOW_LOCAL);
|
||||
lbValue s = lb_const_value(p->module, dst->Matrix.elem, exact_value_i64(1), LB_CONST_CONTEXT_DEFAULT_ALLOW_LOCAL);
|
||||
lb_emit_store(p, d, s);
|
||||
}
|
||||
}
|
||||
@@ -3439,11 +3439,12 @@ gb_internal lbValue lb_emit_comp(lbProcedure *p, TokenKind op_kind, lbValue left
|
||||
|
||||
if (are_types_identical(a, b)) {
|
||||
// NOTE(bill): No need for a conversion
|
||||
} else if ((lb_is_const(left) && !is_type_array(left.type)) || lb_is_const_nil(left)) {
|
||||
} else if ((lb_is_const(left) && !is_type_array(left.type) && !is_type_union(left.type)) || lb_is_const_nil(left)) {
|
||||
// NOTE(karl): !is_type_array(left.type) is there to avoid lb_emit_conv
|
||||
// trying to convert a constant array into a non-array. In that case we
|
||||
// want the `else` branch to happen, so it can try to convert the
|
||||
// non-array into an array instead.
|
||||
// NOTE(korvahkh): We also need !is_type_union(left.type).
|
||||
|
||||
if (lb_is_const_nil(left)) {
|
||||
if (internal_check_is_assignable_to(right.type, left.type)) {
|
||||
@@ -3454,7 +3455,7 @@ gb_internal lbValue lb_emit_comp(lbProcedure *p, TokenKind op_kind, lbValue left
|
||||
}
|
||||
}
|
||||
left = lb_emit_conv(p, left, right.type);
|
||||
} else if ((lb_is_const(right) && !is_type_array(right.type)) || lb_is_const_nil(right)) {
|
||||
} else if ((lb_is_const(right) && !is_type_array(right.type) && !is_type_union(right.type)) || lb_is_const_nil(right)) {
|
||||
|
||||
if (lb_is_const_nil(right)) {
|
||||
if (internal_check_is_assignable_to(left.type, right.type)) {
|
||||
@@ -4462,28 +4463,6 @@ gb_internal lbValue lb_build_expr(lbProcedure *p, Ast *expr) {
|
||||
return res;
|
||||
}
|
||||
|
||||
gb_internal Type *lb_build_expr_original_const_type(Ast *expr) {
|
||||
expr = unparen_expr(expr);
|
||||
Type *type = type_of_expr(expr);
|
||||
if (is_type_union(type)) {
|
||||
if (expr->kind == Ast_CallExpr) {
|
||||
if (expr->CallExpr.proc->tav.mode == Addressing_Type) {
|
||||
Type *res = lb_build_expr_original_const_type(expr->CallExpr.args[0]);
|
||||
return res;
|
||||
}
|
||||
} else if (expr->kind == Ast_Ident || expr->kind == Ast_SelectorExpr) {
|
||||
// a named constant carries the union as its type, so follow it to the declaration the
|
||||
// checker resolved: `C :: U(3)` is the variant `int`, not `U`
|
||||
Entity *e = entity_of_node(expr);
|
||||
if (e != nullptr && e->kind == Entity_Constant &&
|
||||
e->decl_info != nullptr && e->decl_info->init_expr != nullptr) {
|
||||
return lb_build_expr_original_const_type(e->decl_info->init_expr);
|
||||
}
|
||||
}
|
||||
}
|
||||
return type_of_expr(expr);
|
||||
}
|
||||
|
||||
gb_internal lbValue lb_build_expr_internal(lbProcedure *p, Ast *expr) {
|
||||
lbModule *m = p->module;
|
||||
|
||||
@@ -4496,9 +4475,8 @@ gb_internal lbValue lb_build_expr_internal(lbProcedure *p, Ast *expr) {
|
||||
|
||||
|
||||
if (tv.value.kind != ExactValue_Invalid) {
|
||||
Type *original_type = lb_build_expr_original_const_type(expr);
|
||||
// NOTE(bill): Short on constant values
|
||||
return lb_const_value(p->module, type, tv.value, original_type, LB_CONST_CONTEXT_DEFAULT_ALLOW_LOCAL);
|
||||
return lb_const_value(p->module, type, tv.value, LB_CONST_CONTEXT_DEFAULT_ALLOW_LOCAL);
|
||||
} else if (tv.mode == Addressing_Type) {
|
||||
// NOTE(bill, 2023-01-16): is this correct? I hope so at least
|
||||
return lb_typeid(m, tv.type);
|
||||
@@ -4579,7 +4557,7 @@ gb_internal lbValue lb_build_expr_internal(lbProcedure *p, Ast *expr) {
|
||||
TypeAndValue tav = type_and_value_of_expr(expr);
|
||||
GB_ASSERT(tav.mode == Addressing_Constant);
|
||||
|
||||
return lb_const_value(p->module, type, tv.value, tv.type, LB_CONST_CONTEXT_DEFAULT_ALLOW_LOCAL);
|
||||
return lb_const_value(p->module, type, tv.value, LB_CONST_CONTEXT_DEFAULT_ALLOW_LOCAL);
|
||||
case_end;
|
||||
|
||||
case_ast_node(se, SelectorCallExpr, expr);
|
||||
@@ -4862,7 +4840,7 @@ gb_internal lbAddr lb_build_addr_from_entity(lbProcedure *p, Entity *e, Ast *exp
|
||||
GB_ASSERT(e != nullptr);
|
||||
if (e->kind == Entity_Constant) {
|
||||
Type *t = default_type(type_of_expr(expr));
|
||||
lbValue v = lb_const_value(p->module, t, e->Constant.value, lb_build_expr_original_const_type(expr), LB_CONST_CONTEXT_DEFAULT_NO_LOCAL);
|
||||
lbValue v = lb_const_value(p->module, t, e->Constant.value, LB_CONST_CONTEXT_DEFAULT_NO_LOCAL);
|
||||
if (LLVMIsConstant(v.value)) {
|
||||
lbAddr g = lb_add_global_generated_from_procedure(p, t, v);
|
||||
return g;
|
||||
|
||||
Reference in New Issue
Block a user