mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-03 05:08:14 +00:00
Add #subtype struct field prefix, required to have a COM interface hierarchy
This commit is contained in:
@@ -9774,6 +9774,9 @@ gbString write_expr_to_string(gbString str, Ast *node, bool shorthand) {
|
|||||||
if (f->flags&FieldFlag_const) {
|
if (f->flags&FieldFlag_const) {
|
||||||
str = gb_string_appendc(str, "#const ");
|
str = gb_string_appendc(str, "#const ");
|
||||||
}
|
}
|
||||||
|
if (f->flags&FieldFlag_subtype) {
|
||||||
|
str = gb_string_appendc(str, "#subtype ");
|
||||||
|
}
|
||||||
|
|
||||||
for_array(i, f->names) {
|
for_array(i, f->names) {
|
||||||
Ast *name = f->names[i];
|
Ast *name = f->names[i];
|
||||||
|
|||||||
@@ -144,6 +144,7 @@ void check_struct_fields(CheckerContext *ctx, Ast *node, Slice<Entity *> *fields
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool is_using = (p->flags&FieldFlag_using) != 0;
|
bool is_using = (p->flags&FieldFlag_using) != 0;
|
||||||
|
bool is_subtype = (p->flags&FieldFlag_subtype) != 0;
|
||||||
|
|
||||||
for_array(j, p->names) {
|
for_array(j, p->names) {
|
||||||
Ast *name = p->names[j];
|
Ast *name = p->names[j];
|
||||||
@@ -158,6 +159,9 @@ void check_struct_fields(CheckerContext *ctx, Ast *node, Slice<Entity *> *fields
|
|||||||
Entity *field = alloc_entity_field(ctx->scope, name_token, type, is_using, field_src_index);
|
Entity *field = alloc_entity_field(ctx->scope, name_token, type, is_using, field_src_index);
|
||||||
add_entity(ctx, ctx->scope, name, field);
|
add_entity(ctx, ctx->scope, name, field);
|
||||||
field->Variable.field_group_index = field_group_index;
|
field->Variable.field_group_index = field_group_index;
|
||||||
|
if (is_subtype) {
|
||||||
|
field->flags |= EntityFlag_Subtype;
|
||||||
|
}
|
||||||
|
|
||||||
if (j == 0) {
|
if (j == 0) {
|
||||||
field->Variable.docs = docs;
|
field->Variable.docs = docs;
|
||||||
@@ -194,6 +198,20 @@ void check_struct_fields(CheckerContext *ctx, Ast *node, Slice<Entity *> *fields
|
|||||||
|
|
||||||
populate_using_entity_scope(ctx, node, p, type);
|
populate_using_entity_scope(ctx, node, p, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_subtype && p->names.count > 0) {
|
||||||
|
Type *first_type = fields_array[fields_array.count-1]->type;
|
||||||
|
Type *t = base_type(type_deref(first_type));
|
||||||
|
|
||||||
|
if (!does_field_type_allow_using(t) &&
|
||||||
|
p->names.count >= 1 &&
|
||||||
|
p->names[0]->kind == Ast_Ident) {
|
||||||
|
Token name_token = p->names[0]->Ident.token;
|
||||||
|
gbString type_str = type_to_string(first_type);
|
||||||
|
error(name_token, "'subtype' cannot be applied to the field '%.*s' of type '%s'", LIT(name_token.string), type_str);
|
||||||
|
gb_string_free(type_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*fields = slice_from_array(fields_array);
|
*fields = slice_from_array(fields_array);
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ enum EntityFlag : u64 {
|
|||||||
|
|
||||||
EntityFlag_Test = 1ull<<30,
|
EntityFlag_Test = 1ull<<30,
|
||||||
EntityFlag_Init = 1ull<<31,
|
EntityFlag_Init = 1ull<<31,
|
||||||
|
EntityFlag_Subtype = 1ull<<32,
|
||||||
|
|
||||||
EntityFlag_CustomLinkName = 1ull<<40,
|
EntityFlag_CustomLinkName = 1ull<<40,
|
||||||
EntityFlag_CustomLinkage_Internal = 1ull<<41,
|
EntityFlag_CustomLinkage_Internal = 1ull<<41,
|
||||||
@@ -86,6 +87,10 @@ enum EntityFlag : u64 {
|
|||||||
EntityFlag_Overridden = 1ull<<63,
|
EntityFlag_Overridden = 1ull<<63,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum : u64 {
|
||||||
|
EntityFlags_IsSubtype = EntityFlag_Using|EntityFlag_Subtype,
|
||||||
|
};
|
||||||
|
|
||||||
enum EntityState : u32 {
|
enum EntityState : u32 {
|
||||||
EntityState_Unresolved = 0,
|
EntityState_Unresolved = 0,
|
||||||
EntityState_InProgress = 1,
|
EntityState_InProgress = 1,
|
||||||
|
|||||||
+3
-1
@@ -3504,12 +3504,13 @@ enum FieldPrefixKind : i32 {
|
|||||||
FieldPrefix_Unknown = -1,
|
FieldPrefix_Unknown = -1,
|
||||||
FieldPrefix_Invalid = 0,
|
FieldPrefix_Invalid = 0,
|
||||||
|
|
||||||
FieldPrefix_using,
|
FieldPrefix_using, // implies #subtype
|
||||||
FieldPrefix_const,
|
FieldPrefix_const,
|
||||||
FieldPrefix_no_alias,
|
FieldPrefix_no_alias,
|
||||||
FieldPrefix_c_vararg,
|
FieldPrefix_c_vararg,
|
||||||
FieldPrefix_auto_cast,
|
FieldPrefix_auto_cast,
|
||||||
FieldPrefix_any_int,
|
FieldPrefix_any_int,
|
||||||
|
FieldPrefix_subtype, // does not imply `using` semantics
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ParseFieldPrefixMapping {
|
struct ParseFieldPrefixMapping {
|
||||||
@@ -3526,6 +3527,7 @@ gb_global ParseFieldPrefixMapping parse_field_prefix_mappings[] = {
|
|||||||
{str_lit("c_vararg"), Token_Hash, FieldPrefix_c_vararg, FieldFlag_c_vararg},
|
{str_lit("c_vararg"), Token_Hash, FieldPrefix_c_vararg, FieldFlag_c_vararg},
|
||||||
{str_lit("const"), Token_Hash, FieldPrefix_const, FieldFlag_const},
|
{str_lit("const"), Token_Hash, FieldPrefix_const, FieldFlag_const},
|
||||||
{str_lit("any_int"), Token_Hash, FieldPrefix_any_int, FieldFlag_any_int},
|
{str_lit("any_int"), Token_Hash, FieldPrefix_any_int, FieldFlag_any_int},
|
||||||
|
{str_lit("subtype"), Token_Hash, FieldPrefix_subtype, FieldFlag_subtype},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -282,6 +282,7 @@ enum FieldFlag : u32 {
|
|||||||
FieldFlag_auto_cast = 1<<4,
|
FieldFlag_auto_cast = 1<<4,
|
||||||
FieldFlag_const = 1<<5,
|
FieldFlag_const = 1<<5,
|
||||||
FieldFlag_any_int = 1<<6,
|
FieldFlag_any_int = 1<<6,
|
||||||
|
FieldFlag_subtype = 1<<7,
|
||||||
|
|
||||||
// Internal use by the parser only
|
// Internal use by the parser only
|
||||||
FieldFlag_Tags = 1<<10,
|
FieldFlag_Tags = 1<<10,
|
||||||
@@ -289,7 +290,7 @@ enum FieldFlag : u32 {
|
|||||||
|
|
||||||
// Parameter List Restrictions
|
// Parameter List Restrictions
|
||||||
FieldFlag_Signature = FieldFlag_ellipsis|FieldFlag_using|FieldFlag_no_alias|FieldFlag_c_vararg|FieldFlag_auto_cast|FieldFlag_const|FieldFlag_any_int,
|
FieldFlag_Signature = FieldFlag_ellipsis|FieldFlag_using|FieldFlag_no_alias|FieldFlag_c_vararg|FieldFlag_auto_cast|FieldFlag_const|FieldFlag_any_int,
|
||||||
FieldFlag_Struct = FieldFlag_using|FieldFlag_Tags,
|
FieldFlag_Struct = FieldFlag_using|FieldFlag_subtype|FieldFlag_Tags,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum StmtAllowFlag {
|
enum StmtAllowFlag {
|
||||||
|
|||||||
+6
-6
@@ -2334,7 +2334,7 @@ String lookup_subtype_polymorphic_field(Type *dst, Type *src) {
|
|||||||
GB_ASSERT(is_type_struct(src) || is_type_union(src));
|
GB_ASSERT(is_type_struct(src) || is_type_union(src));
|
||||||
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 & EntityFlag_Using) {
|
if (f->kind == Entity_Variable && f->flags & EntityFlags_IsSubtype) {
|
||||||
if (are_types_identical(dst, f->type)) {
|
if (are_types_identical(dst, f->type)) {
|
||||||
return f->token.string;
|
return f->token.string;
|
||||||
}
|
}
|
||||||
@@ -2343,7 +2343,7 @@ String lookup_subtype_polymorphic_field(Type *dst, Type *src) {
|
|||||||
return f->token.string;
|
return f->token.string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (is_type_struct(f->type)) {
|
if ((f->flags & EntityFlag_Using) != 0 && is_type_struct(f->type)) {
|
||||||
String name = lookup_subtype_polymorphic_field(dst, f->type);
|
String name = lookup_subtype_polymorphic_field(dst, f->type);
|
||||||
if (name.len > 0) {
|
if (name.len > 0) {
|
||||||
return name;
|
return name;
|
||||||
@@ -2489,9 +2489,9 @@ bool are_types_identical_internal(Type *x, Type *y, bool check_tuple_names) {
|
|||||||
if (xf->token.string != yf->token.string) {
|
if (xf->token.string != yf->token.string) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool xf_is_using = (xf->flags&EntityFlag_Using) != 0;
|
u64 xf_flags = (xf->flags&EntityFlags_IsSubtype);
|
||||||
bool yf_is_using = (yf->flags&EntityFlag_Using) != 0;
|
u64 yf_flags = (yf->flags&EntityFlags_IsSubtype);
|
||||||
if (xf_is_using ^ yf_is_using) {
|
if (xf_flags != yf_flags) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3813,7 +3813,7 @@ isize check_is_assignable_to_using_subtype(Type *src, Type *dst, isize level = 0
|
|||||||
|
|
||||||
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&EntityFlag_Using) == 0) {
|
if (f->kind != Entity_Variable || (f->flags&EntityFlags_IsSubtype) == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user