Commit 095591f0b0
Changed files (10)
doc
test
cases
doc/langref.md
@@ -625,3 +625,7 @@ Converts a pointer of one type to a pointer of another type.
### @intToPtr(comptime DestType: type, int: usize) -> DestType
Converts an integer to a pointer. To convert the other way, use `usize(ptr)`.
+
+### @enumTagName(value: var) -> []const u8
+
+Converts an enum tag name to a slice of bytes. Example:
src/all_types.hpp
@@ -966,6 +966,8 @@ struct TypeTableEntryEnum {
struct TypeTableEntryEnumTag {
TypeTableEntry *enum_type;
TypeTableEntry *int_type;
+ bool generate_name_table;
+ LLVMValueRef name_table;
};
struct TypeTableEntryUnion {
@@ -1200,6 +1202,7 @@ enum BuiltinFnId {
BuiltinFnIdPanic,
BuiltinFnIdPtrCast,
BuiltinFnIdIntToPtr,
+ BuiltinFnIdEnumTagName,
};
struct BuiltinFnEntry {
@@ -1464,6 +1467,8 @@ struct CodeGen {
Buf global_asm;
ZigList<Buf *> link_objects;
+
+ ZigList<TypeTableEntry *> name_table_enums;
};
enum VarLinkage {
@@ -1742,6 +1747,7 @@ enum IrInstructionId {
IrInstructionIdSetGlobalLinkage,
IrInstructionIdDeclRef,
IrInstructionIdPanic,
+ IrInstructionIdEnumTagName,
};
struct IrInstruction {
@@ -2481,6 +2487,12 @@ struct IrInstructionPanic {
IrInstruction *msg;
};
+struct IrInstructionEnumTagName {
+ IrInstruction base;
+
+ IrInstruction *target;
+};
+
static const size_t slice_ptr_index = 0;
static const size_t slice_len_index = 1;
src/analyze.cpp
@@ -1181,7 +1181,7 @@ bool type_is_invalid(TypeTableEntry *type_entry) {
}
-static TypeTableEntry *create_enum_tag_type(CodeGen *g, TypeTableEntry *enum_type, TypeTableEntry *int_type) {
+TypeTableEntry *create_enum_tag_type(CodeGen *g, TypeTableEntry *enum_type, TypeTableEntry *int_type) {
TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnumTag);
buf_resize(&entry->name, 0);
src/analyze.hpp
@@ -149,5 +149,6 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val);
TypeTableEntry *make_int_type(CodeGen *g, bool is_signed, size_t size_in_bits);
ConstParent *get_const_val_parent(ConstExprValue *value);
FnTableEntry *get_extern_panic_fn(CodeGen *g);
+TypeTableEntry *create_enum_tag_type(CodeGen *g, TypeTableEntry *enum_type, TypeTableEntry *int_type);
#endif
src/codegen.cpp
@@ -2134,6 +2134,29 @@ static LLVMValueRef ir_render_err_name(CodeGen *g, IrExecutable *executable, IrI
return LLVMBuildInBoundsGEP(g->builder, g->err_name_table, indices, 2, "");
}
+static LLVMValueRef ir_render_enum_tag_name(CodeGen *g, IrExecutable *executable,
+ IrInstructionEnumTagName *instruction)
+{
+ TypeTableEntry *enum_tag_type = instruction->target->value.type;
+ assert(enum_tag_type->data.enum_tag.generate_name_table);
+
+ LLVMValueRef enum_tag_value = ir_llvm_value(g, instruction->target);
+ if (ir_want_debug_safety(g, &instruction->base)) {
+ TypeTableEntry *enum_type = enum_tag_type->data.enum_tag.enum_type;
+ size_t field_count = enum_type->data.enumeration.src_field_count;
+ LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(enum_tag_value));
+ LLVMValueRef end_val = LLVMConstInt(LLVMTypeOf(enum_tag_value), field_count, false);
+ add_bounds_check(g, enum_tag_value, LLVMIntUGE, zero, LLVMIntULT, end_val);
+ }
+
+ LLVMValueRef indices[] = {
+ LLVMConstNull(g->builtin_types.entry_usize->type_ref),
+ enum_tag_value,
+ };
+ return LLVMBuildInBoundsGEP(g->builder, enum_tag_type->data.enum_tag.name_table, indices, 2, "");
+}
+
+
static LLVMAtomicOrdering to_LLVMAtomicOrdering(AtomicOrder atomic_order) {
switch (atomic_order) {
case AtomicOrderUnordered: return LLVMAtomicOrderingUnordered;
@@ -2830,6 +2853,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
return ir_render_container_init_list(g, executable, (IrInstructionContainerInitList *)instruction);
case IrInstructionIdPanic:
return ir_render_panic(g, executable, (IrInstructionPanic *)instruction);
+ case IrInstructionIdEnumTagName:
+ return ir_render_enum_tag_name(g, executable, (IrInstructionEnumTagName *)instruction);
}
zig_unreachable();
}
@@ -3390,6 +3415,46 @@ static void generate_error_name_table(CodeGen *g) {
LLVMSetUnnamedAddr(g->err_name_table, true);
}
+static void generate_enum_name_tables(CodeGen *g) {
+ TypeTableEntry *str_type = get_slice_type(g, g->builtin_types.entry_u8, true);
+ TypeTableEntry *u8_ptr_type = str_type->data.structure.fields[0].type_entry;
+
+ for (size_t enum_i = 0; enum_i < g->name_table_enums.length; enum_i += 1) {
+ TypeTableEntry *enum_tag_type = g->name_table_enums.at(enum_i);
+ assert(enum_tag_type->id == TypeTableEntryIdEnumTag);
+ TypeTableEntry *enum_type = enum_tag_type->data.enum_tag.enum_type;
+
+ size_t field_count = enum_type->data.enumeration.src_field_count;
+ LLVMValueRef *values = allocate<LLVMValueRef>(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;
+
+ LLVMValueRef str_init = LLVMConstString(buf_ptr(name), buf_len(name), true);
+ LLVMValueRef str_global = LLVMAddGlobal(g->module, LLVMTypeOf(str_init), "");
+ LLVMSetInitializer(str_global, str_init);
+ LLVMSetLinkage(str_global, LLVMPrivateLinkage);
+ LLVMSetGlobalConstant(str_global, true);
+ LLVMSetUnnamedAddr(str_global, true);
+
+ LLVMValueRef fields[] = {
+ LLVMConstBitCast(str_global, u8_ptr_type->type_ref),
+ LLVMConstInt(g->builtin_types.entry_usize->type_ref, buf_len(name), false),
+ };
+ values[field_i] = LLVMConstNamedStruct(str_type->type_ref, fields, 2);
+ }
+
+ LLVMValueRef name_table_init = LLVMConstArray(str_type->type_ref, values, field_count);
+
+ Buf *table_name = buf_sprintf("%s_name_table", buf_ptr(&enum_type->name));
+ LLVMValueRef name_table = LLVMAddGlobal(g->module, LLVMTypeOf(name_table_init), buf_ptr(table_name));
+ LLVMSetInitializer(name_table, name_table_init);
+ LLVMSetLinkage(name_table, LLVMPrivateLinkage);
+ LLVMSetGlobalConstant(name_table, true);
+ LLVMSetUnnamedAddr(name_table, true);
+ enum_tag_type->data.enum_tag.name_table = name_table;
+ }
+}
+
static void build_all_basic_blocks(CodeGen *g, FnTableEntry *fn) {
IrExecutable *executable = &fn->analyzed_executable;
assert(executable->basic_block_list.length > 0);
@@ -3428,6 +3493,7 @@ static void do_code_gen(CodeGen *g) {
delete_unused_builtin_fns(g);
generate_error_name_table(g);
+ generate_enum_name_tables(g);
// Generate module level variables
for (size_t i = 0; i < g->global_vars.length; i += 1) {
@@ -3800,7 +3866,8 @@ static const GlobalLinkageValue global_linkage_values[] = {
static void init_enum_debug_info(CodeGen *g, TypeTableEntry *enum_type) {
uint32_t field_count = enum_type->data.enumeration.src_field_count;
- TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(g, field_count);
+ TypeTableEntry *tag_int_type = get_smallest_unsigned_int_type(g, field_count);
+ TypeTableEntry *tag_type_entry = create_enum_tag_type(g, enum_type, tag_int_type);
enum_type->data.enumeration.tag_type = tag_type_entry;
ZigLLVMDIEnumerator **di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count);
@@ -4327,6 +4394,7 @@ static void define_builtin_fns(CodeGen *g) {
create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1);
create_builtin_fn(g, BuiltinFnIdPtrCast, "ptrcast", 2);
create_builtin_fn(g, BuiltinFnIdIntToPtr, "intToPtr", 2);
+ create_builtin_fn(g, BuiltinFnIdEnumTagName, "enumTagName", 1);
}
static void add_compile_var(CodeGen *g, const char *name, ConstExprValue *value) {
src/ir.cpp
@@ -541,6 +541,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPanic *) {
return IrInstructionIdPanic;
}
+static constexpr IrInstructionId ir_instruction_id(IrInstructionEnumTagName *) {
+ return IrInstructionIdEnumTagName;
+}
+
template<typename T>
static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
T *special_instruction = allocate<T>(1);
@@ -2130,6 +2134,17 @@ static IrInstruction *ir_build_panic(IrBuilder *irb, Scope *scope, AstNode *sour
return &instruction->base;
}
+static IrInstruction *ir_build_enum_tag_name(IrBuilder *irb, Scope *scope, AstNode *source_node,
+ IrInstruction *target)
+{
+ IrInstructionEnumTagName *instruction = ir_build_instruction<IrInstructionEnumTagName>(irb, scope, source_node);
+ instruction->target = target;
+
+ ir_ref_instruction(target, irb->current_basic_block);
+
+ return &instruction->base;
+}
+
static IrInstruction *ir_instruction_br_get_dep(IrInstructionBr *instruction, size_t index) {
return nullptr;
}
@@ -2787,6 +2802,13 @@ static IrInstruction *ir_instruction_panic_get_dep(IrInstructionPanic *instructi
}
}
+static IrInstruction *ir_instruction_enumtagname_get_dep(IrInstructionEnumTagName *instruction, size_t index) {
+ switch (index) {
+ case 0: return instruction->target;
+ default: return nullptr;
+ }
+}
+
static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t index) {
switch (instruction->id) {
case IrInstructionIdInvalid:
@@ -2975,6 +2997,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
return ir_instruction_declref_get_dep((IrInstructionDeclRef *) instruction, index);
case IrInstructionIdPanic:
return ir_instruction_panic_get_dep((IrInstructionPanic *) instruction, index);
+ case IrInstructionIdEnumTagName:
+ return ir_instruction_enumtagname_get_dep((IrInstructionEnumTagName *) instruction, index);
}
zig_unreachable();
}
@@ -4239,6 +4263,16 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
return ir_build_int_to_ptr(irb, scope, node, arg0_value, arg1_value);
}
+ case BuiltinFnIdEnumTagName:
+ {
+ AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
+ IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
+ if (arg0_value == irb->codegen->invalid_instruction)
+ return arg0_value;
+
+ IrInstruction *actual_tag = ir_build_enum_tag(irb, scope, node, arg0_value);
+ return ir_build_enum_tag_name(irb, scope, node, actual_tag);
+ }
}
zig_unreachable();
}
@@ -10290,6 +10324,8 @@ static IrInstruction *ir_analyze_enum_tag(IrAnalyze *ira, IrInstruction *source_
return ira->codegen->invalid_instruction;
}
+ TypeTableEntry *tag_type = value->value.type->data.enumeration.tag_type;
+
if (instr_is_comptime(value)) {
ConstExprValue *val = ir_resolve_const(ira, value, UndefBad);
if (!val)
@@ -10297,13 +10333,15 @@ static IrInstruction *ir_analyze_enum_tag(IrAnalyze *ira, IrInstruction *source_
IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb,
source_instr->scope, source_instr->source_node);
- const_instruction->base.value.type = value->value.type->data.enumeration.tag_type;
+ const_instruction->base.value.type = tag_type;
const_instruction->base.value.special = ConstValSpecialStatic;
bignum_init_unsigned(&const_instruction->base.value.data.x_bignum, val->data.x_enum.tag);
return &const_instruction->base;
}
- zig_panic("TODO runtime enum tag instruction");
+ IrInstruction *result = ir_build_enum_tag(&ira->new_irb, source_instr->scope, source_instr->source_node, value);
+ result->value.type = tag_type;
+ return result;
}
static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira,
@@ -11097,6 +11135,35 @@ static TypeTableEntry *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruc
return str_type;
}
+static TypeTableEntry *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstructionEnumTagName *instruction) {
+ IrInstruction *target = instruction->target->other;
+ if (type_is_invalid(target->value.type))
+ return ira->codegen->builtin_types.entry_invalid;
+
+ assert(target->value.type->id == TypeTableEntryIdEnumTag);
+
+ if (instr_is_comptime(target)) {
+ TypeTableEntry *enum_type = target->value.type->data.enum_tag.enum_type;
+ uint64_t tag_value = target->value.data.x_bignum.data.x_uint;
+ TypeEnumField *field = &enum_type->data.enumeration.fields[tag_value];
+ ConstExprValue *array_val = create_const_str_lit(ira->codegen, field->name);
+ ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
+ init_const_slice(ira->codegen, out_val, array_val, 0, buf_len(field->name), true);
+ return out_val->type;
+ }
+
+ if (!target->value.type->data.enum_tag.generate_name_table) {
+ target->value.type->data.enum_tag.generate_name_table = true;
+ ira->codegen->name_table_enums.append(target->value.type);
+ }
+
+ IrInstruction *result = ir_build_enum_tag_name(&ira->new_irb, instruction->base.scope,
+ instruction->base.source_node, target);
+ ir_link_new_instruction(result, &instruction->base);
+ result->value.type = get_slice_type(ira->codegen, ira->codegen->builtin_types.entry_u8, true);
+ return result->value.type;
+}
+
static TypeTableEntry *ir_analyze_instruction_type_name(IrAnalyze *ira, IrInstructionTypeName *instruction) {
IrInstruction *type_value = instruction->type_value->other;
TypeTableEntry *type_entry = ir_resolve_type(ira, type_value);
@@ -12641,6 +12708,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
return ir_analyze_instruction_ptr_cast(ira, (IrInstructionPtrCast *)instruction);
case IrInstructionIdIntToPtr:
return ir_analyze_instruction_int_to_ptr(ira, (IrInstructionIntToPtr *)instruction);
+ case IrInstructionIdEnumTagName:
+ return ir_analyze_instruction_enum_tag_name(ira, (IrInstructionEnumTagName *)instruction);
case IrInstructionIdMaybeWrap:
case IrInstructionIdErrWrapCode:
case IrInstructionIdErrWrapPayload:
@@ -12792,7 +12861,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdRef:
case IrInstructionIdMinValue:
case IrInstructionIdMaxValue:
- case IrInstructionIdErrName:
case IrInstructionIdEmbedFile:
case IrInstructionIdDivExact:
case IrInstructionIdTruncate:
@@ -12819,9 +12887,11 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdIntToErr:
case IrInstructionIdErrToInt:
case IrInstructionIdTestType:
- case IrInstructionIdTypeName:
case IrInstructionIdCanImplicitCast:
case IrInstructionIdDeclRef:
+ case IrInstructionIdErrName:
+ case IrInstructionIdTypeName:
+ case IrInstructionIdEnumTagName:
return false;
case IrInstructionIdAsm:
{
src/ir_print.cpp
@@ -816,15 +816,18 @@ static void ir_print_check_switch_prongs(IrPrint *irp, IrInstructionCheckSwitchP
}
static void ir_print_test_type(IrPrint *irp, IrInstructionTestType *instruction) {
- fprintf(irp->f, "@testType(");
+ fprintf(irp->f, "testtype ");
ir_print_other_instruction(irp, instruction->type_value);
- fprintf(irp->f, ")");
}
static void ir_print_type_name(IrPrint *irp, IrInstructionTypeName *instruction) {
- fprintf(irp->f, "@typeName(");
+ fprintf(irp->f, "typename ");
ir_print_other_instruction(irp, instruction->type_value);
- fprintf(irp->f, ")");
+}
+
+static void ir_print_enum_tag_name(IrPrint *irp, IrInstructionEnumTagName *instruction) {
+ fprintf(irp->f, "enumtagname ");
+ ir_print_other_instruction(irp, instruction->target);
}
static void ir_print_can_implicit_cast(IrPrint *irp, IrInstructionCanImplicitCast *instruction) {
@@ -1131,6 +1134,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
case IrInstructionIdTypeName:
ir_print_type_name(irp, (IrInstructionTypeName *)instruction);
break;
+ case IrInstructionIdEnumTagName:
+ ir_print_enum_tag_name(irp, (IrInstructionEnumTagName *)instruction);
+ break;
case IrInstructionIdCanImplicitCast:
ir_print_can_implicit_cast(irp, (IrInstructionCanImplicitCast *)instruction);
break;
std/os/index.zig
@@ -272,7 +272,7 @@ pub fn posixExecve(exe_path: []const u8, argv: []const []const u8, env_map: &con
return posixExecveErrnoToErr(posix.getErrno(posix.execve(path_buf.ptr, argv_buf.ptr, envp_buf.ptr)));
}
- const PATH = getEnv("PATH") ?? ([]const u8)("/usr/local/bin:/bin/:/usr/bin"); // TODO issue #299
+ const PATH = getEnv("PATH") ?? "/usr/local/bin:/bin/:/usr/bin";
// PATH.len because it is >= the largest search_path
// +1 for the / to join the search path and exe_path
// +1 for the null terminating byte
std/build.zig
@@ -137,13 +137,13 @@ pub const Builder = struct {
Target.Native => {},
Target.Cross => |cross_target| {
%return zig_args.append("--target-arch");
- %return zig_args.append(targetArchName(cross_target.arch));
+ %return zig_args.append(@enumTagName(cross_target.arch));
%return zig_args.append("--target-os");
- %return zig_args.append(targetOsName(cross_target.os));
+ %return zig_args.append(@enumTagName(cross_target.os));
%return zig_args.append("--target-environ");
- %return zig_args.append(targetEnvironName(cross_target.environ));
+ %return zig_args.append(@enumTagName(cross_target.environ));
},
}
@@ -458,131 +458,3 @@ fn printInvocation(exe_name: []const u8, args: &const List([]const u8)) {
}
%%io.stderr.printf("\n");
}
-
-// TODO issue #299
-fn targetOsName(target_os: Os) -> []const u8 {
- return switch (target_os) {
- Os.freestanding => "freestanding",
- Os.cloudabi => "cloudabi",
- Os.darwin => "darwin",
- Os.dragonfly => "dragonfly",
- Os.freebsd => "freebsd",
- Os.ios => "ios",
- Os.kfreebsd => "kfreebsd",
- Os.linux => "linux",
- Os.lv2 => "lv2",
- Os.macosx => "macosx",
- Os.netbsd => "netbsd",
- Os.openbsd => "openbsd",
- Os.solaris => "solaris",
- Os.windows => "windows",
- Os.haiku => "haiku",
- Os.minix => "minix",
- Os.rtems => "rtems",
- Os.nacl => "nacl",
- Os.cnk => "cnk",
- Os.bitrig => "bitrig",
- Os.aix => "aix",
- Os.cuda => "cuda",
- Os.nvcl => "nvcl",
- Os.amdhsa => "amdhsa",
- Os.ps4 => "ps4",
- Os.elfiamcu => "elfiamcu",
- Os.tvos => "tvos",
- Os.watchos => "watchos",
- Os.mesa3d => "mesa3d",
- };
-}
-
-// TODO issue #299
-fn targetArchName(target_arch: Arch) -> []const u8 {
- return switch (target_arch) {
- Arch.armv8_2a => "armv8_2a",
- Arch.armv8_1a => "armv8_1a",
- Arch.armv8 => "armv8",
- Arch.armv8m_baseline => "armv8m_baseline",
- Arch.armv8m_mainline => "armv8m_mainline",
- Arch.armv7 => "armv7",
- Arch.armv7em => "armv7em",
- Arch.armv7m => "armv7m",
- Arch.armv7s => "armv7s",
- Arch.armv7k => "armv7k",
- Arch.armv6 => "armv6",
- Arch.armv6m => "armv6m",
- Arch.armv6k => "armv6k",
- Arch.armv6t2 => "armv6t2",
- Arch.armv5 => "armv5",
- Arch.armv5te => "armv5te",
- Arch.armv4t => "armv4t",
- Arch.armeb => "armeb",
- Arch.aarch64 => "aarch64",
- Arch.aarch64_be => "aarch64_be",
- Arch.avr => "avr",
- Arch.bpfel => "bpfel",
- Arch.bpfeb => "bpfeb",
- Arch.hexagon => "hexagon",
- Arch.mips => "mips",
- Arch.mipsel => "mipsel",
- Arch.mips64 => "mips64",
- Arch.mips64el => "mips64el",
- Arch.msp430 => "msp430",
- Arch.powerpc => "powerpc",
- Arch.powerpc64 => "powerpc64",
- Arch.powerpc64le => "powerpc64le",
- Arch.r600 => "r600",
- Arch.amdgcn => "amdgcn",
- Arch.sparc => "sparc",
- Arch.sparcv9 => "sparcv9",
- Arch.sparcel => "sparcel",
- Arch.s390x => "s390x",
- Arch.tce => "tce",
- Arch.thumb => "thumb",
- Arch.thumbeb => "thumbeb",
- Arch.i386 => "i386",
- Arch.x86_64 => "x86_64",
- Arch.xcore => "xcore",
- Arch.nvptx => "nvptx",
- Arch.nvptx64 => "nvptx64",
- Arch.le32 => "le32",
- Arch.le64 => "le64",
- Arch.amdil => "amdil",
- Arch.amdil64 => "amdil64",
- Arch.hsail => "hsail",
- Arch.hsail64 => "hsail64",
- Arch.spir => "spir",
- Arch.spir64 => "spir64",
- Arch.kalimbav3 => "kalimbav3",
- Arch.kalimbav4 => "kalimbav4",
- Arch.kalimbav5 => "kalimbav5",
- Arch.shave => "shave",
- Arch.lanai => "lanai",
- Arch.wasm32 => "wasm32",
- Arch.wasm64 => "wasm64",
- Arch.renderscript32 => "renderscript32",
- Arch.renderscript64 => "renderscript64",
- };
-}
-
-// TODO issue #299
-fn targetEnvironName(target_environ: Environ) -> []const u8 {
- return switch (target_environ) {
- Environ.gnu => "gnu",
- Environ.gnuabi64 => "gnuabi64",
- Environ.gnueabi => "gnueabi",
- Environ.gnueabihf => "gnueabihf",
- Environ.gnux32 => "gnux32",
- Environ.code16 => "code16",
- Environ.eabi => "eabi",
- Environ.eabihf => "eabihf",
- Environ.android => "android",
- Environ.musl => "musl",
- Environ.musleabi => "musleabi",
- Environ.musleabihf => "musleabihf",
- Environ.msvc => "msvc",
- Environ.itanium => "itanium",
- Environ.cygnus => "cygnus",
- Environ.amdopencl => "amdopencl",
- Environ.coreclr => "coreclr",
- };
-}
-
test/cases/enum.zig
@@ -1,4 +1,5 @@
const assert = @import("std").debug.assert;
+const mem = @import("std").mem;
test "enumType" {
const foo1 = Foo.One {13};
@@ -103,3 +104,19 @@ const IntToEnumNumber = enum {
Three,
Four,
};
+
+
+test "enumTagName builtin function" {
+ assert(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));
+ comptime assert(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));
+}
+
+fn testEnumTagNameBare(n: BareNumber) -> []const u8 {
+ return @enumTagName(n);
+}
+
+const BareNumber = enum {
+ One,
+ Two,
+ Three,
+};