mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 07:38:48 +00:00
Allow polymorphic checking with intrinsics.type_is_subtype_of(Derived_Type, Poly_Type)
This commit is contained in:
@@ -5686,7 +5686,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
operand->value = exact_value_bool(is_type_subtype_of(op_src.type, op_dst.type));
|
operand->value = exact_value_bool(is_type_subtype_of_and_allow_polymorphic(op_src.type, op_dst.type));
|
||||||
operand->mode = Addressing_Constant;
|
operand->mode = Addressing_Constant;
|
||||||
operand->type = t_untyped_bool;
|
operand->type = t_untyped_bool;
|
||||||
} break;
|
} break;
|
||||||
|
|||||||
+12
-2
@@ -1,5 +1,6 @@
|
|||||||
gb_internal ParameterValue handle_parameter_value(CheckerContext *ctx, Type *in_type, Type **out_type_, Ast *expr, bool allow_caller_location);
|
gb_internal ParameterValue handle_parameter_value(CheckerContext *ctx, Type *in_type, Type **out_type_, Ast *expr, bool allow_caller_location);
|
||||||
gb_internal Type *determine_type_from_polymorphic(CheckerContext *ctx, Type *poly_type, Operand const &operand);
|
gb_internal Type *determine_type_from_polymorphic(CheckerContext *ctx, Type *poly_type, Operand const &operand);
|
||||||
|
gb_internal Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is_variadic_, isize *variadic_index_, bool *success_, isize *specialization_count_, Array<Operand> const *operands);
|
||||||
|
|
||||||
gb_internal void populate_using_array_index(CheckerContext *ctx, Ast *node, AstField *field, Type *t, String name, i32 idx) {
|
gb_internal void populate_using_array_index(CheckerContext *ctx, Ast *node, AstField *field, Type *t, String name, i32 idx) {
|
||||||
t = base_type(t);
|
t = base_type(t);
|
||||||
@@ -394,7 +395,6 @@ gb_internal Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *poly
|
|||||||
bool *is_polymorphic_,
|
bool *is_polymorphic_,
|
||||||
Ast *node, Array<Operand> *poly_operands) {
|
Ast *node, Array<Operand> *poly_operands) {
|
||||||
Type *polymorphic_params_type = nullptr;
|
Type *polymorphic_params_type = nullptr;
|
||||||
bool can_check_fields = true;
|
|
||||||
GB_ASSERT(is_polymorphic_ != nullptr);
|
GB_ASSERT(is_polymorphic_ != nullptr);
|
||||||
|
|
||||||
if (polymorphic_params == nullptr) {
|
if (polymorphic_params == nullptr) {
|
||||||
@@ -404,6 +404,17 @@ gb_internal Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *poly
|
|||||||
return polymorphic_params_type;
|
return polymorphic_params_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// bool is_variadic = false;
|
||||||
|
// isize variadic_index = 0;
|
||||||
|
// bool success = false;
|
||||||
|
// isize specialization_count = 0;
|
||||||
|
// polymorphic_params_type = check_get_params(ctx, ctx->scope, polymorphic_params, &is_variadic, &variadic_index, &success, &specialization_count, poly_operands);
|
||||||
|
// if (success) {
|
||||||
|
// return nullptr;
|
||||||
|
// }
|
||||||
|
|
||||||
|
bool can_check_fields = true;
|
||||||
ast_node(field_list, FieldList, polymorphic_params);
|
ast_node(field_list, FieldList, polymorphic_params);
|
||||||
Slice<Ast *> params = field_list->list;
|
Slice<Ast *> params = field_list->list;
|
||||||
if (params.count != 0) {
|
if (params.count != 0) {
|
||||||
@@ -565,7 +576,6 @@ gb_internal Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *poly
|
|||||||
if (!*is_polymorphic_) {
|
if (!*is_polymorphic_) {
|
||||||
*is_polymorphic_ = polymorphic_params != nullptr && poly_operands == nullptr;
|
*is_polymorphic_ = polymorphic_params != nullptr && poly_operands == nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return polymorphic_params_type;
|
return polymorphic_params_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+17
-2
@@ -4093,7 +4093,7 @@ gb_internal i64 type_offset_of_from_selection(Type *type, Selection sel) {
|
|||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
gb_internal isize check_is_assignable_to_using_subtype(Type *src, Type *dst, isize level = 0, bool src_is_ptr = false) {
|
gb_internal isize check_is_assignable_to_using_subtype(Type *src, Type *dst, isize level = 0, bool src_is_ptr = false, bool allow_polymorphic=false) {
|
||||||
Type *prev_src = src;
|
Type *prev_src = src;
|
||||||
src = type_deref(src);
|
src = type_deref(src);
|
||||||
if (!src_is_ptr) {
|
if (!src_is_ptr) {
|
||||||
@@ -4105,11 +4105,19 @@ gb_internal isize check_is_assignable_to_using_subtype(Type *src, Type *dst, isi
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool dst_is_polymorphic = is_type_polymorphic(dst);
|
||||||
|
|
||||||
for_array(i, src->Struct.fields) {
|
for_array(i, src->Struct.fields) {
|
||||||
Entity *f = src->Struct.fields[i];
|
Entity *f = src->Struct.fields[i];
|
||||||
if (f->kind != Entity_Variable || (f->flags&EntityFlags_IsSubtype) == 0) {
|
if (f->kind != Entity_Variable || (f->flags&EntityFlags_IsSubtype) == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (allow_polymorphic && dst_is_polymorphic) {
|
||||||
|
Type *fb = base_type(type_deref(f->type));
|
||||||
|
if (fb->kind == Type_Struct && fb->Struct.polymorphic_parent == dst) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (are_types_identical(f->type, dst)) {
|
if (are_types_identical(f->type, dst)) {
|
||||||
return level+1;
|
return level+1;
|
||||||
@@ -4119,7 +4127,7 @@ gb_internal isize check_is_assignable_to_using_subtype(Type *src, Type *dst, isi
|
|||||||
return level+1;
|
return level+1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
isize nested_level = check_is_assignable_to_using_subtype(f->type, dst, level+1, src_is_ptr);
|
isize nested_level = check_is_assignable_to_using_subtype(f->type, dst, level+1, src_is_ptr, allow_polymorphic);
|
||||||
if (nested_level > 0) {
|
if (nested_level > 0) {
|
||||||
return nested_level;
|
return nested_level;
|
||||||
}
|
}
|
||||||
@@ -4135,6 +4143,13 @@ gb_internal bool is_type_subtype_of(Type *src, Type *dst) {
|
|||||||
|
|
||||||
return 0 < check_is_assignable_to_using_subtype(src, dst, 0, is_type_pointer(src));
|
return 0 < check_is_assignable_to_using_subtype(src, dst, 0, is_type_pointer(src));
|
||||||
}
|
}
|
||||||
|
gb_internal bool is_type_subtype_of_and_allow_polymorphic(Type *src, Type *dst) {
|
||||||
|
if (are_types_identical(src, dst)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0 < check_is_assignable_to_using_subtype(src, dst, 0, is_type_pointer(src), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
gb_internal bool has_type_got_objc_class_attribute(Type *t) {
|
gb_internal bool has_type_got_objc_class_attribute(Type *t) {
|
||||||
|
|||||||
Reference in New Issue
Block a user