authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-12-03 22:36:01-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-12-03 22:36:01-05:00
log5a8367e8924e809b1390796eb656633ea5e34a86
tree1eb50935a4dfb147349975875d5b00d391b75fcb
parent0ad1239522c70418990dc7b9da4e128da7cdd1d5

rename @EnumTagType to @TagType. add tests for union-enums

See #618

6 files changed, 109 insertions(+), 55 deletions(-)

src/all_types.hpp+5-5
......@@ -1266,7 +1266,7 @@ enum BuiltinFnId {
12661266 BuiltinFnIdIntToPtr,
12671267 BuiltinFnIdPtrToInt,
12681268 BuiltinFnIdTagName,
1269 BuiltinFnIdEnumTagType,
1269 BuiltinFnIdTagType,
12701270 BuiltinFnIdFieldParentPtr,
12711271 BuiltinFnIdOffsetOf,
12721272 BuiltinFnIdInlineCall,
......@@ -1889,8 +1889,8 @@ enum IrInstructionId {
18891889 IrInstructionIdSetGlobalLinkage,
18901890 IrInstructionIdDeclRef,
18911891 IrInstructionIdPanic,
1892 IrInstructionIdEnumTagName,
1893 IrInstructionIdEnumTagType,
1892 IrInstructionIdTagName,
1893 IrInstructionIdTagType,
18941894 IrInstructionIdFieldParentPtr,
18951895 IrInstructionIdOffsetOf,
18961896 IrInstructionIdTypeId,
......@@ -2652,13 +2652,13 @@ struct IrInstructionPanic {
26522652 IrInstruction *msg;
26532653};
26542654
2655struct IrInstructionEnumTagName {
2655struct IrInstructionTagName {
26562656 IrInstruction base;
26572657
26582658 IrInstruction *target;
26592659};
26602660
2661struct IrInstructionEnumTagType {
2661struct IrInstructionTagType {
26622662 IrInstruction base;
26632663
26642664 IrInstruction *target;
src/codegen.cpp+5-5
......@@ -2717,7 +2717,7 @@ static LLVMValueRef ir_render_err_name(CodeGen *g, IrExecutable *executable, IrI
27172717}
27182718
27192719static LLVMValueRef ir_render_enum_tag_name(CodeGen *g, IrExecutable *executable,
2720 IrInstructionEnumTagName *instruction)
2720 IrInstructionTagName *instruction)
27212721{
27222722 TypeTableEntry *enum_type = instruction->target->value.type;
27232723 assert(enum_type->id == TypeTableEntryIdEnum);
......@@ -3484,7 +3484,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
34843484 case IrInstructionIdOpaqueType:
34853485 case IrInstructionIdSetAlignStack:
34863486 case IrInstructionIdArgType:
3487 case IrInstructionIdEnumTagType:
3487 case IrInstructionIdTagType:
34883488 zig_unreachable();
34893489 case IrInstructionIdReturn:
34903490 return ir_render_return(g, executable, (IrInstructionReturn *)instruction);
......@@ -3594,8 +3594,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
35943594 return ir_render_container_init_list(g, executable, (IrInstructionContainerInitList *)instruction);
35953595 case IrInstructionIdPanic:
35963596 return ir_render_panic(g, executable, (IrInstructionPanic *)instruction);
3597 case IrInstructionIdEnumTagName:
3598 return ir_render_enum_tag_name(g, executable, (IrInstructionEnumTagName *)instruction);
3597 case IrInstructionIdTagName:
3598 return ir_render_enum_tag_name(g, executable, (IrInstructionTagName *)instruction);
35993599 case IrInstructionIdFieldParentPtr:
36003600 return ir_render_field_parent_ptr(g, executable, (IrInstructionFieldParentPtr *)instruction);
36013601 case IrInstructionIdAlignCast:
......@@ -4963,7 +4963,7 @@ static void define_builtin_fns(CodeGen *g) {
49634963 create_builtin_fn(g, BuiltinFnIdIntToPtr, "intToPtr", 2);
49644964 create_builtin_fn(g, BuiltinFnIdPtrToInt, "ptrToInt", 1);
49654965 create_builtin_fn(g, BuiltinFnIdTagName, "tagName", 1);
4966 create_builtin_fn(g, BuiltinFnIdEnumTagType, "EnumTagType", 1);
4966 create_builtin_fn(g, BuiltinFnIdTagType, "TagType", 1);
49674967 create_builtin_fn(g, BuiltinFnIdFieldParentPtr, "fieldParentPtr", 3);
49684968 create_builtin_fn(g, BuiltinFnIdOffsetOf, "offsetOf", 2);
49694969 create_builtin_fn(g, BuiltinFnIdDivExact, "divExact", 2);
src/ir.cpp+56-35
......@@ -539,12 +539,12 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPanic *) {
539539 return IrInstructionIdPanic;
540540}
541541
542static constexpr IrInstructionId ir_instruction_id(IrInstructionEnumTagName *) {
543 return IrInstructionIdEnumTagName;
542static constexpr IrInstructionId ir_instruction_id(IrInstructionTagName *) {
543 return IrInstructionIdTagName;
544544}
545545
546static constexpr IrInstructionId ir_instruction_id(IrInstructionEnumTagType *) {
547 return IrInstructionIdEnumTagType;
546static constexpr IrInstructionId ir_instruction_id(IrInstructionTagType *) {
547 return IrInstructionIdTagType;
548548}
549549
550550static constexpr IrInstructionId ir_instruction_id(IrInstructionFieldParentPtr *) {
......@@ -2205,10 +2205,10 @@ static IrInstruction *ir_build_panic(IrBuilder *irb, Scope *scope, AstNode *sour
22052205 return &instruction->base;
22062206}
22072207
2208static IrInstruction *ir_build_enum_tag_name(IrBuilder *irb, Scope *scope, AstNode *source_node,
2208static IrInstruction *ir_build_tag_name(IrBuilder *irb, Scope *scope, AstNode *source_node,
22092209 IrInstruction *target)
22102210{
2211 IrInstructionEnumTagName *instruction = ir_build_instruction<IrInstructionEnumTagName>(irb, scope, source_node);
2211 IrInstructionTagName *instruction = ir_build_instruction<IrInstructionTagName>(irb, scope, source_node);
22122212 instruction->target = target;
22132213
22142214 ir_ref_instruction(target, irb->current_basic_block);
......@@ -2216,10 +2216,10 @@ static IrInstruction *ir_build_enum_tag_name(IrBuilder *irb, Scope *scope, AstNo
22162216 return &instruction->base;
22172217}
22182218
2219static IrInstruction *ir_build_enum_tag_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
2219static IrInstruction *ir_build_tag_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
22202220 IrInstruction *target)
22212221{
2222 IrInstructionEnumTagType *instruction = ir_build_instruction<IrInstructionEnumTagType>(irb, scope, source_node);
2222 IrInstructionTagType *instruction = ir_build_instruction<IrInstructionTagType>(irb, scope, source_node);
22232223 instruction->target = target;
22242224
22252225 ir_ref_instruction(target, irb->current_basic_block);
......@@ -3002,14 +3002,14 @@ static IrInstruction *ir_instruction_panic_get_dep(IrInstructionPanic *instructi
30023002 }
30033003}
30043004
3005static IrInstruction *ir_instruction_enumtagname_get_dep(IrInstructionEnumTagName *instruction, size_t index) {
3005static IrInstruction *ir_instruction_enumtagname_get_dep(IrInstructionTagName *instruction, size_t index) {
30063006 switch (index) {
30073007 case 0: return instruction->target;
30083008 default: return nullptr;
30093009 }
30103010}
30113011
3012static IrInstruction *ir_instruction_enumtagtype_get_dep(IrInstructionEnumTagType *instruction, size_t index) {
3012static IrInstruction *ir_instruction_enumtagtype_get_dep(IrInstructionTagType *instruction, size_t index) {
30133013 switch (index) {
30143014 case 0: return instruction->target;
30153015 default: return nullptr;
......@@ -3270,10 +3270,10 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
32703270 return ir_instruction_declref_get_dep((IrInstructionDeclRef *) instruction, index);
32713271 case IrInstructionIdPanic:
32723272 return ir_instruction_panic_get_dep((IrInstructionPanic *) instruction, index);
3273 case IrInstructionIdEnumTagName:
3274 return ir_instruction_enumtagname_get_dep((IrInstructionEnumTagName *) instruction, index);
3275 case IrInstructionIdEnumTagType:
3276 return ir_instruction_enumtagtype_get_dep((IrInstructionEnumTagType *) instruction, index);
3273 case IrInstructionIdTagName:
3274 return ir_instruction_enumtagname_get_dep((IrInstructionTagName *) instruction, index);
3275 case IrInstructionIdTagType:
3276 return ir_instruction_enumtagtype_get_dep((IrInstructionTagType *) instruction, index);
32773277 case IrInstructionIdFieldParentPtr:
32783278 return ir_instruction_fieldparentptr_get_dep((IrInstructionFieldParentPtr *) instruction, index);
32793279 case IrInstructionIdOffsetOf:
......@@ -4627,16 +4627,16 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
46274627 return arg0_value;
46284628
46294629 IrInstruction *actual_tag = ir_build_union_tag(irb, scope, node, arg0_value);
4630 return ir_build_enum_tag_name(irb, scope, node, actual_tag);
4630 return ir_build_tag_name(irb, scope, node, actual_tag);
46314631 }
4632 case BuiltinFnIdEnumTagType:
4632 case BuiltinFnIdTagType:
46334633 {
46344634 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
46354635 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
46364636 if (arg0_value == irb->codegen->invalid_instruction)
46374637 return arg0_value;
46384638
4639 return ir_build_enum_tag_type(irb, scope, node, arg0_value);
4639 return ir_build_tag_type(irb, scope, node, arg0_value);
46404640 }
46414641 case BuiltinFnIdFieldParentPtr:
46424642 {
......@@ -13638,7 +13638,7 @@ static TypeTableEntry *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruc
1363813638 return str_type;
1363913639}
1364013640
13641static TypeTableEntry *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstructionEnumTagName *instruction) {
13641static TypeTableEntry *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstructionTagName *instruction) {
1364213642 IrInstruction *target = instruction->target->other;
1364313643 if (type_is_invalid(target->value.type))
1364413644 return ira->codegen->builtin_types.entry_invalid;
......@@ -13658,7 +13658,7 @@ static TypeTableEntry *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrIn
1365813658 ira->codegen->name_table_enums.append(target->value.type);
1365913659 }
1366013660
13661 IrInstruction *result = ir_build_enum_tag_name(&ira->new_irb, instruction->base.scope,
13661 IrInstruction *result = ir_build_tag_name(&ira->new_irb, instruction->base.scope,
1366213662 instruction->base.source_node, target);
1366313663 ir_link_new_instruction(result, &instruction->base);
1366413664 TypeTableEntry *u8_ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, true);
......@@ -15838,22 +15838,43 @@ static TypeTableEntry *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstruc
1583815838 return ira->codegen->builtin_types.entry_type;
1583915839}
1584015840
15841static TypeTableEntry *ir_analyze_instruction_enum_tag_type(IrAnalyze *ira, IrInstructionEnumTagType *instruction) {
15841static TypeTableEntry *ir_analyze_instruction_tag_type(IrAnalyze *ira, IrInstructionTagType *instruction) {
1584215842 IrInstruction *target_inst = instruction->target->other;
1584315843 TypeTableEntry *enum_type = ir_resolve_type(ira, target_inst);
1584415844 if (type_is_invalid(enum_type))
1584515845 return ira->codegen->builtin_types.entry_invalid;
15846 if (enum_type->id != TypeTableEntryIdEnum) {
15847 ir_add_error(ira, target_inst, buf_sprintf("expected enum, found '%s'", buf_ptr(&enum_type->name)));
15846
15847 if (enum_type->id == TypeTableEntryIdEnum) {
15848 ensure_complete_type(ira->codegen, enum_type);
15849 if (type_is_invalid(enum_type))
15850 return ira->codegen->builtin_types.entry_invalid;
15851
15852 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
15853 out_val->data.x_type = enum_type->data.enumeration.tag_int_type;
15854 return ira->codegen->builtin_types.entry_type;
15855 } else if (enum_type->id == TypeTableEntryIdUnion) {
15856 ensure_complete_type(ira->codegen, enum_type);
15857 if (type_is_invalid(enum_type))
15858 return ira->codegen->builtin_types.entry_invalid;
15859
15860 AstNode *decl_node = enum_type->data.unionation.decl_node;
15861 if (decl_node->data.container_decl.auto_enum || decl_node->data.container_decl.init_arg_expr != nullptr) {
15862 assert(enum_type->data.unionation.tag_type != nullptr);
15863
15864 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
15865 out_val->data.x_type = enum_type->data.unionation.tag_type;
15866 return ira->codegen->builtin_types.entry_type;
15867 } else {
15868 ErrorMsg *msg = ir_add_error(ira, target_inst, buf_sprintf("union '%s' has no tag",
15869 buf_ptr(&enum_type->name)));
15870 add_error_note(ira->codegen, msg, decl_node, buf_sprintf("consider 'union(enum)' here"));
15871 return ira->codegen->builtin_types.entry_invalid;
15872 }
15873 } else {
15874 ir_add_error(ira, target_inst, buf_sprintf("expected enum or union, found '%s'",
15875 buf_ptr(&enum_type->name)));
1584815876 return ira->codegen->builtin_types.entry_invalid;
1584915877 }
15850 ensure_complete_type(ira->codegen, enum_type);
15851 if (type_is_invalid(enum_type))
15852 return ira->codegen->builtin_types.entry_invalid;
15853
15854 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
15855 out_val->data.x_type = enum_type->data.enumeration.tag_int_type;
15856 return ira->codegen->builtin_types.entry_type;
1585715878}
1585815879
1585915880static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {
......@@ -16032,8 +16053,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
1603216053 return ir_analyze_instruction_int_to_ptr(ira, (IrInstructionIntToPtr *)instruction);
1603316054 case IrInstructionIdPtrToInt:
1603416055 return ir_analyze_instruction_ptr_to_int(ira, (IrInstructionPtrToInt *)instruction);
16035 case IrInstructionIdEnumTagName:
16036 return ir_analyze_instruction_enum_tag_name(ira, (IrInstructionEnumTagName *)instruction);
16056 case IrInstructionIdTagName:
16057 return ir_analyze_instruction_enum_tag_name(ira, (IrInstructionTagName *)instruction);
1603716058 case IrInstructionIdFieldParentPtr:
1603816059 return ir_analyze_instruction_field_parent_ptr(ira, (IrInstructionFieldParentPtr *)instruction);
1603916060 case IrInstructionIdOffsetOf:
......@@ -16052,8 +16073,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
1605216073 return ir_analyze_instruction_set_align_stack(ira, (IrInstructionSetAlignStack *)instruction);
1605316074 case IrInstructionIdArgType:
1605416075 return ir_analyze_instruction_arg_type(ira, (IrInstructionArgType *)instruction);
16055 case IrInstructionIdEnumTagType:
16056 return ir_analyze_instruction_enum_tag_type(ira, (IrInstructionEnumTagType *)instruction);
16076 case IrInstructionIdTagType:
16077 return ir_analyze_instruction_tag_type(ira, (IrInstructionTagType *)instruction);
1605716078 }
1605816079 zig_unreachable();
1605916080}
......@@ -16230,14 +16251,14 @@ bool ir_has_side_effects(IrInstruction *instruction) {
1623016251 case IrInstructionIdDeclRef:
1623116252 case IrInstructionIdErrName:
1623216253 case IrInstructionIdTypeName:
16233 case IrInstructionIdEnumTagName:
16254 case IrInstructionIdTagName:
1623416255 case IrInstructionIdFieldParentPtr:
1623516256 case IrInstructionIdOffsetOf:
1623616257 case IrInstructionIdTypeId:
1623716258 case IrInstructionIdAlignCast:
1623816259 case IrInstructionIdOpaqueType:
1623916260 case IrInstructionIdArgType:
16240 case IrInstructionIdEnumTagType:
16261 case IrInstructionIdTagType:
1624116262 return false;
1624216263 case IrInstructionIdAsm:
1624316264 {
src/ir_print.cpp+8-8
......@@ -872,8 +872,8 @@ static void ir_print_type_name(IrPrint *irp, IrInstructionTypeName *instruction)
872872 ir_print_other_instruction(irp, instruction->type_value);
873873}
874874
875static void ir_print_enum_tag_name(IrPrint *irp, IrInstructionEnumTagName *instruction) {
876 fprintf(irp->f, "enumtagname ");
875static void ir_print_tag_name(IrPrint *irp, IrInstructionTagName *instruction) {
876 fprintf(irp->f, "tagname ");
877877 ir_print_other_instruction(irp, instruction->target);
878878}
879879
......@@ -981,8 +981,8 @@ static void ir_print_arg_type(IrPrint *irp, IrInstructionArgType *instruction) {
981981 fprintf(irp->f, ")");
982982}
983983
984static void ir_print_enum_tag_type(IrPrint *irp, IrInstructionEnumTagType *instruction) {
985 fprintf(irp->f, "@EnumTagType(");
984static void ir_print_enum_tag_type(IrPrint *irp, IrInstructionTagType *instruction) {
985 fprintf(irp->f, "@TagType(");
986986 ir_print_other_instruction(irp, instruction->target);
987987 fprintf(irp->f, ")");
988988}
......@@ -1254,8 +1254,8 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
12541254 case IrInstructionIdTypeName:
12551255 ir_print_type_name(irp, (IrInstructionTypeName *)instruction);
12561256 break;
1257 case IrInstructionIdEnumTagName:
1258 ir_print_enum_tag_name(irp, (IrInstructionEnumTagName *)instruction);
1257 case IrInstructionIdTagName:
1258 ir_print_tag_name(irp, (IrInstructionTagName *)instruction);
12591259 break;
12601260 case IrInstructionIdCanImplicitCast:
12611261 ir_print_can_implicit_cast(irp, (IrInstructionCanImplicitCast *)instruction);
......@@ -1299,8 +1299,8 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
12991299 case IrInstructionIdArgType:
13001300 ir_print_arg_type(irp, (IrInstructionArgType *)instruction);
13011301 break;
1302 case IrInstructionIdEnumTagType:
1303 ir_print_enum_tag_type(irp, (IrInstructionEnumTagType *)instruction);
1302 case IrInstructionIdTagType:
1303 ir_print_enum_tag_type(irp, (IrInstructionTagType *)instruction);
13041304 break;
13051305 }
13061306 fprintf(irp->f, "\n");
test/cases/enum.zig+2-2
......@@ -204,12 +204,12 @@ test "set enum tag type" {
204204 {
205205 var x = Small.One;
206206 x = Small.Two;
207 comptime assert(@EnumTagType(Small) == u2);
207 comptime assert(@TagType(Small) == u2);
208208 }
209209 {
210210 var x = Small2.One;
211211 x = Small2.Two;
212 comptime assert(@EnumTagType(Small2) == u2);
212 comptime assert(@TagType(Small2) == u2);
213213 }
214214}
215215
test/cases/union.zig+33
......@@ -104,3 +104,36 @@ fn bar(value: &const Payload) -> i32 {
104104 Payload.C => |x| if (x) i32(30) else 31,
105105 };
106106}
107
108const MultipleChoice2 = union(enum(u32)) {
109 Unspecified1: i32,
110 A: f32 = 20,
111 Unspecified2: void,
112 B: bool = 40,
113 Unspecified3: i32,
114 C: i8 = 60,
115 Unspecified4: void,
116 D: void = 1000,
117 Unspecified5: i32,
118};
119
120test "union(enum(u32)) with specified and unspecified tag values" {
121 comptime assert(@TagType(@TagType(MultipleChoice2)) == u32);
122 testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2 {.C = 123});
123 comptime testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2 { .C = 123} );
124}
125
126fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: &const MultipleChoice2) {
127 assert(u32(@TagType(MultipleChoice2)(*x)) == 60);
128 assert(1123 == switch (*x) {
129 MultipleChoice2.A => 1,
130 MultipleChoice2.B => 2,
131 MultipleChoice2.C => |v| i32(1000) + v,
132 MultipleChoice2.D => 4,
133 MultipleChoice2.Unspecified1 => 5,
134 MultipleChoice2.Unspecified2 => 6,
135 MultipleChoice2.Unspecified3 => 7,
136 MultipleChoice2.Unspecified4 => 8,
137 MultipleChoice2.Unspecified5 => 9,
138 });
139}