From d505ea6cafe8bf6549eb2c56396b0a94d8109859 Mon Sep 17 00:00:00 2001 From: Vexu Date: Wed, 26 Feb 2020 01:03:58 +0200 Subject: fix `@tagName` on extern and non-exhaustive enums --- src/codegen.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'src/codegen.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index f9d2566da7..0bf8510843 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -5031,8 +5031,18 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) { LLVMConstNull(usize->llvm_type), }; + HashMap occupied_tag_values = {}; + occupied_tag_values.init(field_count); + for (size_t field_i = 0; field_i < field_count; field_i += 1) { - Buf *name = enum_type->data.enumeration.fields[field_i].name; + TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[field_i]; + + Buf *name = type_enum_field->name; + auto entry = occupied_tag_values.put_unique(type_enum_field->value, name); + if (entry != nullptr) { + continue; + } + LLVMValueRef str_init = LLVMConstString(buf_ptr(name), (unsigned)buf_len(name), true); LLVMValueRef str_global = LLVMAddGlobal(g->module, LLVMTypeOf(str_init), ""); LLVMSetInitializer(str_global, str_init); @@ -5086,11 +5096,6 @@ static LLVMValueRef ir_render_enum_tag_name(CodeGen *g, IrExecutableGen *executa { ZigType *enum_type = instruction->target->value->type; assert(enum_type->id == ZigTypeIdEnum); - if (enum_type->data.enumeration.non_exhaustive) { - add_node_error(g, instruction->base.base.source_node, - buf_sprintf("TODO @tagName on non-exhaustive enum https://github.com/ziglang/zig/issues/3991")); - codegen_report_errors_and_exit(g); - } LLVMValueRef enum_name_function = get_enum_tag_name_function(g, enum_type); -- cgit v1.2.3 From 215797749d0e0d911feaaf45dc70836c3d12f18e Mon Sep 17 00:00:00 2001 From: Vexu Date: Wed, 26 Feb 2020 01:19:22 +0200 Subject: fix `@intToEnum` on extern enums --- src/codegen.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'src/codegen.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index 0bf8510843..4d992d25d0 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -3329,9 +3329,21 @@ static LLVMValueRef ir_render_int_to_enum(CodeGen *g, IrExecutableGen *executabl LLVMBasicBlockRef ok_value_block = LLVMAppendBasicBlock(g->cur_fn_val, "OkValue"); size_t field_count = wanted_type->data.enumeration.src_field_count; LLVMValueRef switch_instr = LLVMBuildSwitch(g->builder, tag_int_value, bad_value_block, field_count); + + HashMap occupied_tag_values = {}; + occupied_tag_values.init(field_count); + for (size_t field_i = 0; field_i < field_count; field_i += 1) { + TypeEnumField *type_enum_field = &wanted_type->data.enumeration.fields[field_i]; + + Buf *name = type_enum_field->name; + auto entry = occupied_tag_values.put_unique(type_enum_field->value, name); + if (entry != nullptr) { + continue; + } + LLVMValueRef this_tag_int_value = bigint_to_llvm_const(get_llvm_type(g, tag_int_type), - &wanted_type->data.enumeration.fields[field_i].value); + &type_enum_field->value); LLVMAddCase(switch_instr, this_tag_int_value, ok_value_block); } LLVMPositionBuilderAtEnd(g->builder, bad_value_block); -- cgit v1.2.3 From 62de32a18c1eecedc29055e4199fa364f9e9b7c6 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 26 Feb 2020 11:21:10 -0500 Subject: call deinit on the hashmaps introduced in the prev commit --- src/codegen.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/codegen.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index 4d992d25d0..ee3e05a801 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -3346,6 +3346,7 @@ static LLVMValueRef ir_render_int_to_enum(CodeGen *g, IrExecutableGen *executabl &type_enum_field->value); LLVMAddCase(switch_instr, this_tag_int_value, ok_value_block); } + occupied_tag_values.deinit(); LLVMPositionBuilderAtEnd(g->builder, bad_value_block); gen_safety_crash(g, PanicMsgIdBadEnumValue); @@ -5084,6 +5085,7 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) { LLVMPositionBuilderAtEnd(g->builder, return_block); LLVMBuildRet(g->builder, slice_global); } + occupied_tag_values.deinit(); LLVMPositionBuilderAtEnd(g->builder, bad_value_block); if (g->build_mode == BuildModeDebug || g->build_mode == BuildModeSafeRelease) { -- cgit v1.2.3