mirror of
https://github.com/odin-lang/Odin.git
synced 2026-08-22 05:00:51 +00:00
simd [?] type fix; count recovery
This commit is contained in:
@@ -10688,7 +10688,25 @@ gb_internal ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast *
|
||||
if (count != nullptr) {
|
||||
if (count->kind == Ast_UnaryExpr &&
|
||||
count->UnaryExpr.op.kind == Token_Question) {
|
||||
type = alloc_type_array(check_type(c, type_expr->ArrayType.elem), -1);
|
||||
Type *elem = check_type(c, type_expr->ArrayType.elem);
|
||||
|
||||
bool is_simd_tag = false;
|
||||
if (type_expr->ArrayType.tag != nullptr) {
|
||||
GB_ASSERT(type_expr->ArrayType.tag->kind == Ast_BasicDirective);
|
||||
is_simd_tag = type_expr->ArrayType.tag->BasicDirective.name.string == "simd";
|
||||
}
|
||||
if (is_simd_tag) {
|
||||
if (!is_type_valid_vector_elem(elem) && !is_type_polymorphic(elem)) {
|
||||
gbString str = type_to_string(elem);
|
||||
error(type_expr->ArrayType.elem, "Invalid element type for #simd, expected an integer, float, boolean, or 'rawptr' with no specific endianness, got '%s'", str);
|
||||
gb_string_free(str);
|
||||
type = alloc_type_array(elem, -1);
|
||||
} else {
|
||||
type = alloc_type_simd_vector(-1, elem);
|
||||
}
|
||||
} else {
|
||||
type = alloc_type_array(elem, -1);
|
||||
}
|
||||
is_to_be_determined_array_count = true;
|
||||
}
|
||||
} else {
|
||||
@@ -10912,7 +10930,9 @@ gb_internal ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast *
|
||||
} else if (t->kind == Type_SimdVector) {
|
||||
elem_type = t->SimdVector.elem;
|
||||
context_name = str_lit("simd vector literal");
|
||||
max_type_count = t->SimdVector.count;
|
||||
if (!is_to_be_determined_array_count) {
|
||||
max_type_count = t->SimdVector.count;
|
||||
}
|
||||
} else if (t->kind == Type_Matrix) {
|
||||
elem_type = t->Matrix.elem;
|
||||
context_name = str_lit("matrix literal");
|
||||
@@ -11088,6 +11108,16 @@ gb_internal ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast *
|
||||
error(node, "Expected %lld values for this array literal, got %lld", cast(long long)t->Array.count, cast(long long)max);
|
||||
}
|
||||
}
|
||||
} else if (t->kind == Type_SimdVector) {
|
||||
// the length laws cannot be applied until the literal has supplied the count
|
||||
if (is_to_be_determined_array_count) {
|
||||
t->SimdVector.count = max;
|
||||
if (max < 1 || !is_power_of_two(max)) {
|
||||
error(node, "Invalid length for #simd, expected a power of two length, got '%lld'", cast(long long)max);
|
||||
} else if (max > SIMD_ELEMENT_COUNT_MAX) {
|
||||
error(node, "#simd support a maximum element count of %d, got %lld", SIMD_ELEMENT_COUNT_MAX, cast(long long)max);
|
||||
}
|
||||
}
|
||||
} else if (t->kind == Type_Struct) {
|
||||
GB_ASSERT(t->Struct.soa_kind == StructSoa_Fixed);
|
||||
if (is_to_be_determined_array_count) {
|
||||
|
||||
@@ -3538,9 +3538,12 @@ gb_internal void check_array_type_internal(CheckerContext *ctx, Ast *e, Type **t
|
||||
return;
|
||||
}
|
||||
|
||||
// Track user input and recovery value seperate, since both could be '0'
|
||||
bool count_recovered = false;
|
||||
if (count < 0) {
|
||||
error(at->count, "? can only be used in conjunction with compound literals");
|
||||
count = 0;
|
||||
count_recovered = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -3562,7 +3565,12 @@ gb_internal void check_array_type_internal(CheckerContext *ctx, Ast *e, Type **t
|
||||
// Ignore
|
||||
} else if (count < 1 || !is_power_of_two(count)) {
|
||||
*type = alloc_type_array(elem, count, generic_type);
|
||||
if (ctx->disallow_polymorphic_return_types && count == 0) {
|
||||
if (count_recovered) {
|
||||
return;
|
||||
}
|
||||
// a polymorphic value used as the count is still unresolved while the
|
||||
// signature is checked and reads as 0; only a written count is constant
|
||||
if (ctx->disallow_polymorphic_return_types && o.mode != Addressing_Constant) {
|
||||
return;
|
||||
}
|
||||
error(at->count, "Invalid length for #simd, expected a power of two length, got '%lld'", cast(long long)count);
|
||||
|
||||
Reference in New Issue
Block a user