mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-03 14:18:47 +00:00
Do using Foo :: enum at the type_decl stage
This commit is contained in:
@@ -88,7 +88,6 @@ Type_Info_Enum :: struct {
|
|||||||
base: ^Type_Info,
|
base: ^Type_Info,
|
||||||
names: []string,
|
names: []string,
|
||||||
values: []Type_Info_Enum_Value,
|
values: []Type_Info_Enum_Value,
|
||||||
is_using: bool, // TODO(bill): Should this be in the `Type_Info`?
|
|
||||||
};
|
};
|
||||||
Type_Info_Map :: struct {
|
Type_Info_Map :: struct {
|
||||||
key: ^Type_Info,
|
key: ^Type_Info,
|
||||||
|
|||||||
@@ -248,6 +248,33 @@ void check_type_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Type *def)
|
|||||||
named->Named.base = bt;
|
named->Named.base = bt;
|
||||||
e->TypeName.is_type_alias = true;
|
e->TypeName.is_type_alias = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// using decl
|
||||||
|
if (decl->is_using) {
|
||||||
|
// NOTE(bill): Must be an enum declaration
|
||||||
|
if (te->kind == Ast_EnumType) {
|
||||||
|
Scope *parent = ctx->scope->parent;
|
||||||
|
if (parent->flags&ScopeFlag_File) {
|
||||||
|
// NOTE(bill): Use package scope
|
||||||
|
parent = parent->parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type *t = base_type(e->type);
|
||||||
|
GB_ASSERT(t->kind == Type_Enum);
|
||||||
|
|
||||||
|
for_array(i, t->Enum.fields) {
|
||||||
|
Entity *f = t->Enum.fields[i];
|
||||||
|
if (f->kind != Entity_Constant) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String name = f->token.string;
|
||||||
|
if (is_blank_ident(name)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
add_entity(ctx->checker, parent, nullptr, f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+1
-23
@@ -600,29 +600,7 @@ void check_enum_type(CheckerContext *ctx, Type *enum_type, Type *named_type, Ast
|
|||||||
GB_ASSERT(fields.count <= et->fields.count);
|
GB_ASSERT(fields.count <= et->fields.count);
|
||||||
|
|
||||||
|
|
||||||
enum_type->Enum.fields = fields;
|
enum_type->Enum.fields = fields;
|
||||||
enum_type->Enum.is_using = et->is_using;
|
|
||||||
// TODO(bill): Should this be done elsewhere? e.g. delayed
|
|
||||||
if (et->is_using) {
|
|
||||||
Scope *parent = ctx->scope->parent;
|
|
||||||
if (parent->flags&ScopeFlag_File) {
|
|
||||||
// NOTE(bill): Use package scope
|
|
||||||
parent = parent->parent;
|
|
||||||
}
|
|
||||||
for_array(i, fields) {
|
|
||||||
Entity *f = fields[i];
|
|
||||||
if (f->kind != Entity_Constant) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
String name = f->token.string;
|
|
||||||
if (is_blank_ident(name)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
add_entity(ctx->checker, parent, nullptr, f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Scope *s = ctx->scope;
|
|
||||||
enum_type->Enum.names = make_names_field_for_struct(ctx, ctx->scope);
|
enum_type->Enum.names = make_names_field_for_struct(ctx, ctx->scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -2123,7 +2123,7 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) {
|
|||||||
|
|
||||||
if (vd->is_using) {
|
if (vd->is_using) {
|
||||||
if (e->kind == Entity_TypeName && init->kind == Ast_EnumType) {
|
if (e->kind == Entity_TypeName && init->kind == Ast_EnumType) {
|
||||||
init->EnumType.is_using = true;
|
d->is_using = true;
|
||||||
} else {
|
} else {
|
||||||
error(name, "'using' is not allowed on this constant value declaration");
|
error(name, "'using' is not allowed on this constant value declaration");
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -187,10 +187,10 @@ struct DeclInfo {
|
|||||||
|
|
||||||
Ast * type_expr;
|
Ast * type_expr;
|
||||||
Ast * init_expr;
|
Ast * init_expr;
|
||||||
// Array<Ast *> init_expr_list;
|
|
||||||
Array<Ast *> attributes;
|
Array<Ast *> attributes;
|
||||||
Ast * proc_lit; // Ast_ProcLit
|
Ast * proc_lit; // Ast_ProcLit
|
||||||
Type * gen_proc_type; // Precalculated
|
Type * gen_proc_type; // Precalculated
|
||||||
|
bool is_using;
|
||||||
|
|
||||||
PtrSet<Entity *> deps;
|
PtrSet<Entity *> deps;
|
||||||
PtrSet<Type *> type_info_deps;
|
PtrSet<Type *> type_info_deps;
|
||||||
|
|||||||
@@ -8163,9 +8163,6 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info
|
|||||||
irValue *base = ir_type_info(proc, t->Enum.base_type);
|
irValue *base = ir_type_info(proc, t->Enum.base_type);
|
||||||
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), base);
|
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), base);
|
||||||
|
|
||||||
// is_using
|
|
||||||
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 3), ir_const_bool(t->Enum.is_using));
|
|
||||||
|
|
||||||
if (t->Enum.fields.count > 0) {
|
if (t->Enum.fields.count > 0) {
|
||||||
auto fields = t->Enum.fields;
|
auto fields = t->Enum.fields;
|
||||||
irValue *name_array = ir_generate_array(m, t_string, fields.count,
|
irValue *name_array = ir_generate_array(m, t_string, fields.count,
|
||||||
|
|||||||
+3
-3
@@ -435,9 +435,9 @@ AST_KIND(_TypeBegin, "", bool) \
|
|||||||
Ast *type; \
|
Ast *type; \
|
||||||
}) \
|
}) \
|
||||||
AST_KIND(PolyType, "polymorphic type", struct { \
|
AST_KIND(PolyType, "polymorphic type", struct { \
|
||||||
Token token; \
|
Token token; \
|
||||||
Ast *type; \
|
Ast * type; \
|
||||||
Ast *specialization; \
|
Ast * specialization; \
|
||||||
}) \
|
}) \
|
||||||
AST_KIND(ProcType, "procedure type", struct { \
|
AST_KIND(ProcType, "procedure type", struct { \
|
||||||
Token token; \
|
Token token; \
|
||||||
|
|||||||
@@ -135,7 +135,6 @@ struct TypeStruct {
|
|||||||
Scope * scope; \
|
Scope * scope; \
|
||||||
Entity * names; \
|
Entity * names; \
|
||||||
Type * base_type; \
|
Type * base_type; \
|
||||||
bool is_using; \
|
|
||||||
}) \
|
}) \
|
||||||
TYPE_KIND(Union, struct { \
|
TYPE_KIND(Union, struct { \
|
||||||
Array<Type *> variants; \
|
Array<Type *> variants; \
|
||||||
|
|||||||
Reference in New Issue
Block a user