@@ -551,6 +551,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionEnumTagName *) {
551551 return IrInstructionIdEnumTagName;
552552}
553553
554+ static constexpr IrInstructionId ir_instruction_id(IrInstructionEnumTagType *) {
555+ return IrInstructionIdEnumTagType;
556+ }
557+
554558static constexpr IrInstructionId ir_instruction_id(IrInstructionFieldParentPtr *) {
555559 return IrInstructionIdFieldParentPtr;
556560}
@@ -2270,6 +2274,17 @@ static IrInstruction *ir_build_enum_tag_name(IrBuilder *irb, Scope *scope, AstNo
22702274 return &instruction->base;
22712275}
22722276
2277+ static IrInstruction *ir_build_enum_tag_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
2278+ IrInstruction *target)
2279+ {
2280+ IrInstructionEnumTagType *instruction = ir_build_instruction<IrInstructionEnumTagType>(irb, scope, source_node);
2281+ instruction->target = target;
2282+
2283+ ir_ref_instruction(target, irb->current_basic_block);
2284+
2285+ return &instruction->base;
2286+ }
2287+
22732288static IrInstruction *ir_build_field_parent_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
22742289 IrInstruction *type_value, IrInstruction *field_name, IrInstruction *field_ptr, TypeStructField *field)
22752290{
@@ -3066,6 +3081,13 @@ static IrInstruction *ir_instruction_enumtagname_get_dep(IrInstructionEnumTagNam
30663081 }
30673082}
30683083
3084+ static IrInstruction *ir_instruction_enumtagtype_get_dep(IrInstructionEnumTagType *instruction, size_t index) {
3085+ switch (index) {
3086+ case 0: return instruction->target;
3087+ default: return nullptr;
3088+ }
3089+ }
3090+
30693091static IrInstruction *ir_instruction_fieldparentptr_get_dep(IrInstructionFieldParentPtr *instruction, size_t index) {
30703092 switch (index) {
30713093 case 0: return instruction->type_value;
@@ -3326,6 +3348,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
33263348 return ir_instruction_panic_get_dep((IrInstructionPanic *) instruction, index);
33273349 case IrInstructionIdEnumTagName:
33283350 return ir_instruction_enumtagname_get_dep((IrInstructionEnumTagName *) instruction, index);
3351+ case IrInstructionIdEnumTagType:
3352+ return ir_instruction_enumtagtype_get_dep((IrInstructionEnumTagType *) instruction, index);
33293353 case IrInstructionIdFieldParentPtr:
33303354 return ir_instruction_fieldparentptr_get_dep((IrInstructionFieldParentPtr *) instruction, index);
33313355 case IrInstructionIdOffsetOf:
@@ -4681,6 +4705,15 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
46814705 IrInstruction *actual_tag = ir_build_enum_tag(irb, scope, node, arg0_value);
46824706 return ir_build_enum_tag_name(irb, scope, node, actual_tag);
46834707 }
4708+ case BuiltinFnIdEnumTagType:
4709+ {
4710+ AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4711+ IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
4712+ if (arg0_value == irb->codegen->invalid_instruction)
4713+ return arg0_value;
4714+
4715+ return ir_build_enum_tag_type(irb, scope, node, arg0_value);
4716+ }
46844717 case BuiltinFnIdFieldParentPtr:
46854718 {
46864719 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
@@ -15831,6 +15864,27 @@ static TypeTableEntry *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstruc
1583115864 return ira->codegen->builtin_types.entry_type;
1583215865}
1583315866
15867+ static TypeTableEntry *ir_analyze_instruction_enum_tag_type(IrAnalyze *ira, IrInstructionEnumTagType *instruction) {
15868+ IrInstruction *target_inst = instruction->target->other;
15869+ TypeTableEntry *enum_type = ir_resolve_type(ira, target_inst);
15870+ if (type_is_invalid(enum_type))
15871+ return ira->codegen->builtin_types.entry_invalid;
15872+ if (enum_type->id != TypeTableEntryIdEnum) {
15873+ ir_add_error(ira, target_inst, buf_sprintf("expected enum, found '%s'", buf_ptr(&enum_type->name)));
15874+ return ira->codegen->builtin_types.entry_invalid;
15875+ }
15876+ ensure_complete_type(ira->codegen, enum_type);
15877+ if (type_is_invalid(enum_type))
15878+ return ira->codegen->builtin_types.entry_invalid;
15879+
15880+ TypeTableEntry *non_int_tag_type = enum_type->data.enumeration.tag_type;
15881+ assert(non_int_tag_type->id == TypeTableEntryIdEnumTag);
15882+
15883+ ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
15884+ out_val->data.x_type = non_int_tag_type->data.enum_tag.int_type;
15885+ return ira->codegen->builtin_types.entry_type;
15886+ }
15887+
1583415888static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {
1583515889 switch (instruction->id) {
1583615890 case IrInstructionIdInvalid:
@@ -16029,6 +16083,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
1602916083 return ir_analyze_instruction_set_align_stack(ira, (IrInstructionSetAlignStack *)instruction);
1603016084 case IrInstructionIdArgType:
1603116085 return ir_analyze_instruction_arg_type(ira, (IrInstructionArgType *)instruction);
16086+ case IrInstructionIdEnumTagType:
16087+ return ir_analyze_instruction_enum_tag_type(ira, (IrInstructionEnumTagType *)instruction);
1603216088 }
1603316089 zig_unreachable();
1603416090}
@@ -16214,6 +16270,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
1621416270 case IrInstructionIdAlignCast:
1621516271 case IrInstructionIdOpaqueType:
1621616272 case IrInstructionIdArgType:
16273+ case IrInstructionIdEnumTagType:
1621716274 return false;
1621816275 case IrInstructionIdAsm:
1621916276 {
0 commit comments