authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-04-08 17:45:22-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-04-08 17:45:22-04:00
log095591f0b0f0d09bb1589fc404c2e7fdeac4bee4
treed98a149b0a2472bdaef45b15bdcd42e4d6a42566
parent7611ed3484ad810fe10d3c303a04d66bfa0bd6fd

add enumTagName builtin function

closes #299

10 files changed, 192 insertions(+), 142 deletions(-)

doc/langref.md+4
...@@ -625,3 +625,7 @@ Converts a pointer of one type to a pointer of another type....@@ -625,3 +625,7 @@ Converts a pointer of one type to a pointer of another type.
625### @intToPtr(comptime DestType: type, int: usize) -> DestType625### @intToPtr(comptime DestType: type, int: usize) -> DestType
626626
627Converts an integer to a pointer. To convert the other way, use `usize(ptr)`.627Converts an integer to a pointer. To convert the other way, use `usize(ptr)`.
628
629### @enumTagName(value: var) -> []const u8
630
631Converts an enum tag name to a slice of bytes. Example:
src/all_types.hpp+12
...@@ -966,6 +966,8 @@ struct TypeTableEntryEnum {...@@ -966,6 +966,8 @@ struct TypeTableEntryEnum {
966struct TypeTableEntryEnumTag {966struct TypeTableEntryEnumTag {
967 TypeTableEntry *enum_type;967 TypeTableEntry *enum_type;
968 TypeTableEntry *int_type;968 TypeTableEntry *int_type;
969 bool generate_name_table;
970 LLVMValueRef name_table;
969};971};
970972
971struct TypeTableEntryUnion {973struct TypeTableEntryUnion {
...@@ -1200,6 +1202,7 @@ enum BuiltinFnId {...@@ -1200,6 +1202,7 @@ enum BuiltinFnId {
1200 BuiltinFnIdPanic,1202 BuiltinFnIdPanic,
1201 BuiltinFnIdPtrCast,1203 BuiltinFnIdPtrCast,
1202 BuiltinFnIdIntToPtr,1204 BuiltinFnIdIntToPtr,
1205 BuiltinFnIdEnumTagName,
1203};1206};
12041207
1205struct BuiltinFnEntry {1208struct BuiltinFnEntry {
...@@ -1464,6 +1467,8 @@ struct CodeGen {...@@ -1464,6 +1467,8 @@ struct CodeGen {
14641467
1465 Buf global_asm;1468 Buf global_asm;
1466 ZigList<Buf *> link_objects;1469 ZigList<Buf *> link_objects;
1470
1471 ZigList<TypeTableEntry *> name_table_enums;
1467};1472};
14681473
1469enum VarLinkage {1474enum VarLinkage {
...@@ -1742,6 +1747,7 @@ enum IrInstructionId {...@@ -1742,6 +1747,7 @@ enum IrInstructionId {
1742 IrInstructionIdSetGlobalLinkage,1747 IrInstructionIdSetGlobalLinkage,
1743 IrInstructionIdDeclRef,1748 IrInstructionIdDeclRef,
1744 IrInstructionIdPanic,1749 IrInstructionIdPanic,
1750 IrInstructionIdEnumTagName,
1745};1751};
17461752
1747struct IrInstruction {1753struct IrInstruction {
...@@ -2481,6 +2487,12 @@ struct IrInstructionPanic {...@@ -2481,6 +2487,12 @@ struct IrInstructionPanic {
2481 IrInstruction *msg;2487 IrInstruction *msg;
2482};2488};
24832489
2490struct IrInstructionEnumTagName {
2491 IrInstruction base;
2492
2493 IrInstruction *target;
2494};
2495
2484static const size_t slice_ptr_index = 0;2496static const size_t slice_ptr_index = 0;
2485static const size_t slice_len_index = 1;2497static const size_t slice_len_index = 1;
24862498
src/analyze.cpp+1-1
...@@ -1181,7 +1181,7 @@ bool type_is_invalid(TypeTableEntry *type_entry) {...@@ -1181,7 +1181,7 @@ bool type_is_invalid(TypeTableEntry *type_entry) {
1181}1181}
11821182
11831183
1184static TypeTableEntry *create_enum_tag_type(CodeGen *g, TypeTableEntry *enum_type, TypeTableEntry *int_type) {1184TypeTableEntry *create_enum_tag_type(CodeGen *g, TypeTableEntry *enum_type, TypeTableEntry *int_type) {
1185 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnumTag);1185 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnumTag);
11861186
1187 buf_resize(&entry->name, 0);1187 buf_resize(&entry->name, 0);
src/analyze.hpp+1
...@@ -149,5 +149,6 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val);...@@ -149,5 +149,6 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val);
149TypeTableEntry *make_int_type(CodeGen *g, bool is_signed, size_t size_in_bits);149TypeTableEntry *make_int_type(CodeGen *g, bool is_signed, size_t size_in_bits);
150ConstParent *get_const_val_parent(ConstExprValue *value);150ConstParent *get_const_val_parent(ConstExprValue *value);
151FnTableEntry *get_extern_panic_fn(CodeGen *g);151FnTableEntry *get_extern_panic_fn(CodeGen *g);
152TypeTableEntry *create_enum_tag_type(CodeGen *g, TypeTableEntry *enum_type, TypeTableEntry *int_type);
152153
153#endif154#endif
src/codegen.cpp+69-1
...@@ -2134,6 +2134,29 @@ static LLVMValueRef ir_render_err_name(CodeGen *g, IrExecutable *executable, IrI...@@ -2134,6 +2134,29 @@ static LLVMValueRef ir_render_err_name(CodeGen *g, IrExecutable *executable, IrI
2134 return LLVMBuildInBoundsGEP(g->builder, g->err_name_table, indices, 2, "");2134 return LLVMBuildInBoundsGEP(g->builder, g->err_name_table, indices, 2, "");
2135}2135}
21362136
2137static LLVMValueRef ir_render_enum_tag_name(CodeGen *g, IrExecutable *executable,
2138 IrInstructionEnumTagName *instruction)
2139{
2140 TypeTableEntry *enum_tag_type = instruction->target->value.type;
2141 assert(enum_tag_type->data.enum_tag.generate_name_table);
2142
2143 LLVMValueRef enum_tag_value = ir_llvm_value(g, instruction->target);
2144 if (ir_want_debug_safety(g, &instruction->base)) {
2145 TypeTableEntry *enum_type = enum_tag_type->data.enum_tag.enum_type;
2146 size_t field_count = enum_type->data.enumeration.src_field_count;
2147 LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(enum_tag_value));
2148 LLVMValueRef end_val = LLVMConstInt(LLVMTypeOf(enum_tag_value), field_count, false);
2149 add_bounds_check(g, enum_tag_value, LLVMIntUGE, zero, LLVMIntULT, end_val);
2150 }
2151
2152 LLVMValueRef indices[] = {
2153 LLVMConstNull(g->builtin_types.entry_usize->type_ref),
2154 enum_tag_value,
2155 };
2156 return LLVMBuildInBoundsGEP(g->builder, enum_tag_type->data.enum_tag.name_table, indices, 2, "");
2157}
2158
2159
2137static LLVMAtomicOrdering to_LLVMAtomicOrdering(AtomicOrder atomic_order) {2160static LLVMAtomicOrdering to_LLVMAtomicOrdering(AtomicOrder atomic_order) {
2138 switch (atomic_order) {2161 switch (atomic_order) {
2139 case AtomicOrderUnordered: return LLVMAtomicOrderingUnordered;2162 case AtomicOrderUnordered: return LLVMAtomicOrderingUnordered;
...@@ -2830,6 +2853,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -2830,6 +2853,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
2830 return ir_render_container_init_list(g, executable, (IrInstructionContainerInitList *)instruction);2853 return ir_render_container_init_list(g, executable, (IrInstructionContainerInitList *)instruction);
2831 case IrInstructionIdPanic:2854 case IrInstructionIdPanic:
2832 return ir_render_panic(g, executable, (IrInstructionPanic *)instruction);2855 return ir_render_panic(g, executable, (IrInstructionPanic *)instruction);
2856 case IrInstructionIdEnumTagName:
2857 return ir_render_enum_tag_name(g, executable, (IrInstructionEnumTagName *)instruction);
2833 }2858 }
2834 zig_unreachable();2859 zig_unreachable();
2835}2860}
...@@ -3390,6 +3415,46 @@ static void generate_error_name_table(CodeGen *g) {...@@ -3390,6 +3415,46 @@ static void generate_error_name_table(CodeGen *g) {
3390 LLVMSetUnnamedAddr(g->err_name_table, true);3415 LLVMSetUnnamedAddr(g->err_name_table, true);
3391}3416}
33923417
3418static void generate_enum_name_tables(CodeGen *g) {
3419 TypeTableEntry *str_type = get_slice_type(g, g->builtin_types.entry_u8, true);
3420 TypeTableEntry *u8_ptr_type = str_type->data.structure.fields[0].type_entry;
3421
3422 for (size_t enum_i = 0; enum_i < g->name_table_enums.length; enum_i += 1) {
3423 TypeTableEntry *enum_tag_type = g->name_table_enums.at(enum_i);
3424 assert(enum_tag_type->id == TypeTableEntryIdEnumTag);
3425 TypeTableEntry *enum_type = enum_tag_type->data.enum_tag.enum_type;
3426
3427 size_t field_count = enum_type->data.enumeration.src_field_count;
3428 LLVMValueRef *values = allocate<LLVMValueRef>(field_count);
3429 for (size_t field_i = 0; field_i < field_count; field_i += 1) {
3430 Buf *name = enum_type->data.enumeration.fields[field_i].name;
3431
3432 LLVMValueRef str_init = LLVMConstString(buf_ptr(name), buf_len(name), true);
3433 LLVMValueRef str_global = LLVMAddGlobal(g->module, LLVMTypeOf(str_init), "");
3434 LLVMSetInitializer(str_global, str_init);
3435 LLVMSetLinkage(str_global, LLVMPrivateLinkage);
3436 LLVMSetGlobalConstant(str_global, true);
3437 LLVMSetUnnamedAddr(str_global, true);
3438
3439 LLVMValueRef fields[] = {
3440 LLVMConstBitCast(str_global, u8_ptr_type->type_ref),
3441 LLVMConstInt(g->builtin_types.entry_usize->type_ref, buf_len(name), false),
3442 };
3443 values[field_i] = LLVMConstNamedStruct(str_type->type_ref, fields, 2);
3444 }
3445
3446 LLVMValueRef name_table_init = LLVMConstArray(str_type->type_ref, values, field_count);
3447
3448 Buf *table_name = buf_sprintf("%s_name_table", buf_ptr(&enum_type->name));
3449 LLVMValueRef name_table = LLVMAddGlobal(g->module, LLVMTypeOf(name_table_init), buf_ptr(table_name));
3450 LLVMSetInitializer(name_table, name_table_init);
3451 LLVMSetLinkage(name_table, LLVMPrivateLinkage);
3452 LLVMSetGlobalConstant(name_table, true);
3453 LLVMSetUnnamedAddr(name_table, true);
3454 enum_tag_type->data.enum_tag.name_table = name_table;
3455 }
3456}
3457
3393static void build_all_basic_blocks(CodeGen *g, FnTableEntry *fn) {3458static void build_all_basic_blocks(CodeGen *g, FnTableEntry *fn) {
3394 IrExecutable *executable = &fn->analyzed_executable;3459 IrExecutable *executable = &fn->analyzed_executable;
3395 assert(executable->basic_block_list.length > 0);3460 assert(executable->basic_block_list.length > 0);
...@@ -3428,6 +3493,7 @@ static void do_code_gen(CodeGen *g) {...@@ -3428,6 +3493,7 @@ static void do_code_gen(CodeGen *g) {
34283493
3429 delete_unused_builtin_fns(g);3494 delete_unused_builtin_fns(g);
3430 generate_error_name_table(g);3495 generate_error_name_table(g);
3496 generate_enum_name_tables(g);
34313497
3432 // Generate module level variables3498 // Generate module level variables
3433 for (size_t i = 0; i < g->global_vars.length; i += 1) {3499 for (size_t i = 0; i < g->global_vars.length; i += 1) {
...@@ -3800,7 +3866,8 @@ static const GlobalLinkageValue global_linkage_values[] = {...@@ -3800,7 +3866,8 @@ static const GlobalLinkageValue global_linkage_values[] = {
3800static void init_enum_debug_info(CodeGen *g, TypeTableEntry *enum_type) {3866static void init_enum_debug_info(CodeGen *g, TypeTableEntry *enum_type) {
3801 uint32_t field_count = enum_type->data.enumeration.src_field_count;3867 uint32_t field_count = enum_type->data.enumeration.src_field_count;
38023868
3803 TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(g, field_count);3869 TypeTableEntry *tag_int_type = get_smallest_unsigned_int_type(g, field_count);
3870 TypeTableEntry *tag_type_entry = create_enum_tag_type(g, enum_type, tag_int_type);
3804 enum_type->data.enumeration.tag_type = tag_type_entry;3871 enum_type->data.enumeration.tag_type = tag_type_entry;
38053872
3806 ZigLLVMDIEnumerator **di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count);3873 ZigLLVMDIEnumerator **di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count);
...@@ -4327,6 +4394,7 @@ static void define_builtin_fns(CodeGen *g) {...@@ -4327,6 +4394,7 @@ static void define_builtin_fns(CodeGen *g) {
4327 create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1);4394 create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1);
4328 create_builtin_fn(g, BuiltinFnIdPtrCast, "ptrcast", 2);4395 create_builtin_fn(g, BuiltinFnIdPtrCast, "ptrcast", 2);
4329 create_builtin_fn(g, BuiltinFnIdIntToPtr, "intToPtr", 2);4396 create_builtin_fn(g, BuiltinFnIdIntToPtr, "intToPtr", 2);
4397 create_builtin_fn(g, BuiltinFnIdEnumTagName, "enumTagName", 1);
4330}4398}
43314399
4332static void add_compile_var(CodeGen *g, const char *name, ConstExprValue *value) {4400static void add_compile_var(CodeGen *g, const char *name, ConstExprValue *value) {
src/ir.cpp+74-4
...@@ -541,6 +541,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPanic *) {...@@ -541,6 +541,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPanic *) {
541 return IrInstructionIdPanic;541 return IrInstructionIdPanic;
542}542}
543543
544static constexpr IrInstructionId ir_instruction_id(IrInstructionEnumTagName *) {
545 return IrInstructionIdEnumTagName;
546}
547
544template<typename T>548template<typename T>
545static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {549static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
546 T *special_instruction = allocate<T>(1);550 T *special_instruction = allocate<T>(1);
...@@ -2130,6 +2134,17 @@ static IrInstruction *ir_build_panic(IrBuilder *irb, Scope *scope, AstNode *sour...@@ -2130,6 +2134,17 @@ static IrInstruction *ir_build_panic(IrBuilder *irb, Scope *scope, AstNode *sour
2130 return &instruction->base;2134 return &instruction->base;
2131}2135}
21322136
2137static IrInstruction *ir_build_enum_tag_name(IrBuilder *irb, Scope *scope, AstNode *source_node,
2138 IrInstruction *target)
2139{
2140 IrInstructionEnumTagName *instruction = ir_build_instruction<IrInstructionEnumTagName>(irb, scope, source_node);
2141 instruction->target = target;
2142
2143 ir_ref_instruction(target, irb->current_basic_block);
2144
2145 return &instruction->base;
2146}
2147
2133static IrInstruction *ir_instruction_br_get_dep(IrInstructionBr *instruction, size_t index) {2148static IrInstruction *ir_instruction_br_get_dep(IrInstructionBr *instruction, size_t index) {
2134 return nullptr;2149 return nullptr;
2135}2150}
...@@ -2787,6 +2802,13 @@ static IrInstruction *ir_instruction_panic_get_dep(IrInstructionPanic *instructi...@@ -2787,6 +2802,13 @@ static IrInstruction *ir_instruction_panic_get_dep(IrInstructionPanic *instructi
2787 }2802 }
2788}2803}
27892804
2805static IrInstruction *ir_instruction_enumtagname_get_dep(IrInstructionEnumTagName *instruction, size_t index) {
2806 switch (index) {
2807 case 0: return instruction->target;
2808 default: return nullptr;
2809 }
2810}
2811
2790static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t index) {2812static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t index) {
2791 switch (instruction->id) {2813 switch (instruction->id) {
2792 case IrInstructionIdInvalid:2814 case IrInstructionIdInvalid:
...@@ -2975,6 +2997,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t...@@ -2975,6 +2997,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
2975 return ir_instruction_declref_get_dep((IrInstructionDeclRef *) instruction, index);2997 return ir_instruction_declref_get_dep((IrInstructionDeclRef *) instruction, index);
2976 case IrInstructionIdPanic:2998 case IrInstructionIdPanic:
2977 return ir_instruction_panic_get_dep((IrInstructionPanic *) instruction, index);2999 return ir_instruction_panic_get_dep((IrInstructionPanic *) instruction, index);
3000 case IrInstructionIdEnumTagName:
3001 return ir_instruction_enumtagname_get_dep((IrInstructionEnumTagName *) instruction, index);
2978 }3002 }
2979 zig_unreachable();3003 zig_unreachable();
2980}3004}
...@@ -4239,6 +4263,16 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4239,6 +4263,16 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
42394263
4240 return ir_build_int_to_ptr(irb, scope, node, arg0_value, arg1_value);4264 return ir_build_int_to_ptr(irb, scope, node, arg0_value, arg1_value);
4241 }4265 }
4266 case BuiltinFnIdEnumTagName:
4267 {
4268 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4269 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
4270 if (arg0_value == irb->codegen->invalid_instruction)
4271 return arg0_value;
4272
4273 IrInstruction *actual_tag = ir_build_enum_tag(irb, scope, node, arg0_value);
4274 return ir_build_enum_tag_name(irb, scope, node, actual_tag);
4275 }
4242 }4276 }
4243 zig_unreachable();4277 zig_unreachable();
4244}4278}
...@@ -10290,6 +10324,8 @@ static IrInstruction *ir_analyze_enum_tag(IrAnalyze *ira, IrInstruction *source_...@@ -10290,6 +10324,8 @@ static IrInstruction *ir_analyze_enum_tag(IrAnalyze *ira, IrInstruction *source_
10290 return ira->codegen->invalid_instruction;10324 return ira->codegen->invalid_instruction;
10291 }10325 }
1029210326
10327 TypeTableEntry *tag_type = value->value.type->data.enumeration.tag_type;
10328
10293 if (instr_is_comptime(value)) {10329 if (instr_is_comptime(value)) {
10294 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad);10330 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad);
10295 if (!val)10331 if (!val)
...@@ -10297,13 +10333,15 @@ static IrInstruction *ir_analyze_enum_tag(IrAnalyze *ira, IrInstruction *source_...@@ -10297,13 +10333,15 @@ static IrInstruction *ir_analyze_enum_tag(IrAnalyze *ira, IrInstruction *source_
1029710333
10298 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb,10334 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb,
10299 source_instr->scope, source_instr->source_node);10335 source_instr->scope, source_instr->source_node);
10300 const_instruction->base.value.type = value->value.type->data.enumeration.tag_type;10336 const_instruction->base.value.type = tag_type;
10301 const_instruction->base.value.special = ConstValSpecialStatic;10337 const_instruction->base.value.special = ConstValSpecialStatic;
10302 bignum_init_unsigned(&const_instruction->base.value.data.x_bignum, val->data.x_enum.tag);10338 bignum_init_unsigned(&const_instruction->base.value.data.x_bignum, val->data.x_enum.tag);
10303 return &const_instruction->base;10339 return &const_instruction->base;
10304 }10340 }
1030510341
10306 zig_panic("TODO runtime enum tag instruction");10342 IrInstruction *result = ir_build_enum_tag(&ira->new_irb, source_instr->scope, source_instr->source_node, value);
10343 result->value.type = tag_type;
10344 return result;
10307}10345}
1030810346
10309static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira,10347static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira,
...@@ -11097,6 +11135,35 @@ static TypeTableEntry *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruc...@@ -11097,6 +11135,35 @@ static TypeTableEntry *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruc
11097 return str_type;11135 return str_type;
11098}11136}
1109911137
11138static TypeTableEntry *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstructionEnumTagName *instruction) {
11139 IrInstruction *target = instruction->target->other;
11140 if (type_is_invalid(target->value.type))
11141 return ira->codegen->builtin_types.entry_invalid;
11142
11143 assert(target->value.type->id == TypeTableEntryIdEnumTag);
11144
11145 if (instr_is_comptime(target)) {
11146 TypeTableEntry *enum_type = target->value.type->data.enum_tag.enum_type;
11147 uint64_t tag_value = target->value.data.x_bignum.data.x_uint;
11148 TypeEnumField *field = &enum_type->data.enumeration.fields[tag_value];
11149 ConstExprValue *array_val = create_const_str_lit(ira->codegen, field->name);
11150 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
11151 init_const_slice(ira->codegen, out_val, array_val, 0, buf_len(field->name), true);
11152 return out_val->type;
11153 }
11154
11155 if (!target->value.type->data.enum_tag.generate_name_table) {
11156 target->value.type->data.enum_tag.generate_name_table = true;
11157 ira->codegen->name_table_enums.append(target->value.type);
11158 }
11159
11160 IrInstruction *result = ir_build_enum_tag_name(&ira->new_irb, instruction->base.scope,
11161 instruction->base.source_node, target);
11162 ir_link_new_instruction(result, &instruction->base);
11163 result->value.type = get_slice_type(ira->codegen, ira->codegen->builtin_types.entry_u8, true);
11164 return result->value.type;
11165}
11166
11100static TypeTableEntry *ir_analyze_instruction_type_name(IrAnalyze *ira, IrInstructionTypeName *instruction) {11167static TypeTableEntry *ir_analyze_instruction_type_name(IrAnalyze *ira, IrInstructionTypeName *instruction) {
11101 IrInstruction *type_value = instruction->type_value->other;11168 IrInstruction *type_value = instruction->type_value->other;
11102 TypeTableEntry *type_entry = ir_resolve_type(ira, type_value);11169 TypeTableEntry *type_entry = ir_resolve_type(ira, type_value);
...@@ -12641,6 +12708,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi...@@ -12641,6 +12708,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
12641 return ir_analyze_instruction_ptr_cast(ira, (IrInstructionPtrCast *)instruction);12708 return ir_analyze_instruction_ptr_cast(ira, (IrInstructionPtrCast *)instruction);
12642 case IrInstructionIdIntToPtr:12709 case IrInstructionIdIntToPtr:
12643 return ir_analyze_instruction_int_to_ptr(ira, (IrInstructionIntToPtr *)instruction);12710 return ir_analyze_instruction_int_to_ptr(ira, (IrInstructionIntToPtr *)instruction);
12711 case IrInstructionIdEnumTagName:
12712 return ir_analyze_instruction_enum_tag_name(ira, (IrInstructionEnumTagName *)instruction);
12644 case IrInstructionIdMaybeWrap:12713 case IrInstructionIdMaybeWrap:
12645 case IrInstructionIdErrWrapCode:12714 case IrInstructionIdErrWrapCode:
12646 case IrInstructionIdErrWrapPayload:12715 case IrInstructionIdErrWrapPayload:
...@@ -12792,7 +12861,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -12792,7 +12861,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
12792 case IrInstructionIdRef:12861 case IrInstructionIdRef:
12793 case IrInstructionIdMinValue:12862 case IrInstructionIdMinValue:
12794 case IrInstructionIdMaxValue:12863 case IrInstructionIdMaxValue:
12795 case IrInstructionIdErrName:
12796 case IrInstructionIdEmbedFile:12864 case IrInstructionIdEmbedFile:
12797 case IrInstructionIdDivExact:12865 case IrInstructionIdDivExact:
12798 case IrInstructionIdTruncate:12866 case IrInstructionIdTruncate:
...@@ -12819,9 +12887,11 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -12819,9 +12887,11 @@ bool ir_has_side_effects(IrInstruction *instruction) {
12819 case IrInstructionIdIntToErr:12887 case IrInstructionIdIntToErr:
12820 case IrInstructionIdErrToInt:12888 case IrInstructionIdErrToInt:
12821 case IrInstructionIdTestType:12889 case IrInstructionIdTestType:
12822 case IrInstructionIdTypeName:
12823 case IrInstructionIdCanImplicitCast:12890 case IrInstructionIdCanImplicitCast:
12824 case IrInstructionIdDeclRef:12891 case IrInstructionIdDeclRef:
12892 case IrInstructionIdErrName:
12893 case IrInstructionIdTypeName:
12894 case IrInstructionIdEnumTagName:
12825 return false;12895 return false;
12826 case IrInstructionIdAsm:12896 case IrInstructionIdAsm:
12827 {12897 {
src/ir_print.cpp+10-4
...@@ -816,15 +816,18 @@ static void ir_print_check_switch_prongs(IrPrint *irp, IrInstructionCheckSwitchP...@@ -816,15 +816,18 @@ static void ir_print_check_switch_prongs(IrPrint *irp, IrInstructionCheckSwitchP
816}816}
817817
818static void ir_print_test_type(IrPrint *irp, IrInstructionTestType *instruction) {818static void ir_print_test_type(IrPrint *irp, IrInstructionTestType *instruction) {
819 fprintf(irp->f, "@testType(");819 fprintf(irp->f, "testtype ");
820 ir_print_other_instruction(irp, instruction->type_value);820 ir_print_other_instruction(irp, instruction->type_value);
821 fprintf(irp->f, ")");
822}821}
823822
824static void ir_print_type_name(IrPrint *irp, IrInstructionTypeName *instruction) {823static void ir_print_type_name(IrPrint *irp, IrInstructionTypeName *instruction) {
825 fprintf(irp->f, "@typeName(");824 fprintf(irp->f, "typename ");
826 ir_print_other_instruction(irp, instruction->type_value);825 ir_print_other_instruction(irp, instruction->type_value);
827 fprintf(irp->f, ")");826}
827
828static void ir_print_enum_tag_name(IrPrint *irp, IrInstructionEnumTagName *instruction) {
829 fprintf(irp->f, "enumtagname ");
830 ir_print_other_instruction(irp, instruction->target);
828}831}
829832
830static void ir_print_can_implicit_cast(IrPrint *irp, IrInstructionCanImplicitCast *instruction) {833static void ir_print_can_implicit_cast(IrPrint *irp, IrInstructionCanImplicitCast *instruction) {
...@@ -1131,6 +1134,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1131,6 +1134,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1131 case IrInstructionIdTypeName:1134 case IrInstructionIdTypeName:
1132 ir_print_type_name(irp, (IrInstructionTypeName *)instruction);1135 ir_print_type_name(irp, (IrInstructionTypeName *)instruction);
1133 break;1136 break;
1137 case IrInstructionIdEnumTagName:
1138 ir_print_enum_tag_name(irp, (IrInstructionEnumTagName *)instruction);
1139 break;
1134 case IrInstructionIdCanImplicitCast:1140 case IrInstructionIdCanImplicitCast:
1135 ir_print_can_implicit_cast(irp, (IrInstructionCanImplicitCast *)instruction);1141 ir_print_can_implicit_cast(irp, (IrInstructionCanImplicitCast *)instruction);
1136 break;1142 break;
std/build.zig+3-131
...@@ -137,13 +137,13 @@ pub const Builder = struct {...@@ -137,13 +137,13 @@ pub const Builder = struct {
137 Target.Native => {},137 Target.Native => {},
138 Target.Cross => |cross_target| {138 Target.Cross => |cross_target| {
139 %return zig_args.append("--target-arch");139 %return zig_args.append("--target-arch");
140 %return zig_args.append(targetArchName(cross_target.arch));140 %return zig_args.append(@enumTagName(cross_target.arch));
141141
142 %return zig_args.append("--target-os");142 %return zig_args.append("--target-os");
143 %return zig_args.append(targetOsName(cross_target.os));143 %return zig_args.append(@enumTagName(cross_target.os));
144144
145 %return zig_args.append("--target-environ");145 %return zig_args.append("--target-environ");
146 %return zig_args.append(targetEnvironName(cross_target.environ));146 %return zig_args.append(@enumTagName(cross_target.environ));
147 },147 },
148 }148 }
149149
...@@ -458,131 +458,3 @@ fn printInvocation(exe_name: []const u8, args: &const List([]const u8)) {...@@ -458,131 +458,3 @@ fn printInvocation(exe_name: []const u8, args: &const List([]const u8)) {
458 }458 }
459 %%io.stderr.printf("\n");459 %%io.stderr.printf("\n");
460}460}
461
462// TODO issue #299
463fn targetOsName(target_os: Os) -> []const u8 {
464 return switch (target_os) {
465 Os.freestanding => "freestanding",
466 Os.cloudabi => "cloudabi",
467 Os.darwin => "darwin",
468 Os.dragonfly => "dragonfly",
469 Os.freebsd => "freebsd",
470 Os.ios => "ios",
471 Os.kfreebsd => "kfreebsd",
472 Os.linux => "linux",
473 Os.lv2 => "lv2",
474 Os.macosx => "macosx",
475 Os.netbsd => "netbsd",
476 Os.openbsd => "openbsd",
477 Os.solaris => "solaris",
478 Os.windows => "windows",
479 Os.haiku => "haiku",
480 Os.minix => "minix",
481 Os.rtems => "rtems",
482 Os.nacl => "nacl",
483 Os.cnk => "cnk",
484 Os.bitrig => "bitrig",
485 Os.aix => "aix",
486 Os.cuda => "cuda",
487 Os.nvcl => "nvcl",
488 Os.amdhsa => "amdhsa",
489 Os.ps4 => "ps4",
490 Os.elfiamcu => "elfiamcu",
491 Os.tvos => "tvos",
492 Os.watchos => "watchos",
493 Os.mesa3d => "mesa3d",
494 };
495}
496
497// TODO issue #299
498fn targetArchName(target_arch: Arch) -> []const u8 {
499 return switch (target_arch) {
500 Arch.armv8_2a => "armv8_2a",
501 Arch.armv8_1a => "armv8_1a",
502 Arch.armv8 => "armv8",
503 Arch.armv8m_baseline => "armv8m_baseline",
504 Arch.armv8m_mainline => "armv8m_mainline",
505 Arch.armv7 => "armv7",
506 Arch.armv7em => "armv7em",
507 Arch.armv7m => "armv7m",
508 Arch.armv7s => "armv7s",
509 Arch.armv7k => "armv7k",
510 Arch.armv6 => "armv6",
511 Arch.armv6m => "armv6m",
512 Arch.armv6k => "armv6k",
513 Arch.armv6t2 => "armv6t2",
514 Arch.armv5 => "armv5",
515 Arch.armv5te => "armv5te",
516 Arch.armv4t => "armv4t",
517 Arch.armeb => "armeb",
518 Arch.aarch64 => "aarch64",
519 Arch.aarch64_be => "aarch64_be",
520 Arch.avr => "avr",
521 Arch.bpfel => "bpfel",
522 Arch.bpfeb => "bpfeb",
523 Arch.hexagon => "hexagon",
524 Arch.mips => "mips",
525 Arch.mipsel => "mipsel",
526 Arch.mips64 => "mips64",
527 Arch.mips64el => "mips64el",
528 Arch.msp430 => "msp430",
529 Arch.powerpc => "powerpc",
530 Arch.powerpc64 => "powerpc64",
531 Arch.powerpc64le => "powerpc64le",
532 Arch.r600 => "r600",
533 Arch.amdgcn => "amdgcn",
534 Arch.sparc => "sparc",
535 Arch.sparcv9 => "sparcv9",
536 Arch.sparcel => "sparcel",
537 Arch.s390x => "s390x",
538 Arch.tce => "tce",
539 Arch.thumb => "thumb",
540 Arch.thumbeb => "thumbeb",
541 Arch.i386 => "i386",
542 Arch.x86_64 => "x86_64",
543 Arch.xcore => "xcore",
544 Arch.nvptx => "nvptx",
545 Arch.nvptx64 => "nvptx64",
546 Arch.le32 => "le32",
547 Arch.le64 => "le64",
548 Arch.amdil => "amdil",
549 Arch.amdil64 => "amdil64",
550 Arch.hsail => "hsail",
551 Arch.hsail64 => "hsail64",
552 Arch.spir => "spir",
553 Arch.spir64 => "spir64",
554 Arch.kalimbav3 => "kalimbav3",
555 Arch.kalimbav4 => "kalimbav4",
556 Arch.kalimbav5 => "kalimbav5",
557 Arch.shave => "shave",
558 Arch.lanai => "lanai",
559 Arch.wasm32 => "wasm32",
560 Arch.wasm64 => "wasm64",
561 Arch.renderscript32 => "renderscript32",
562 Arch.renderscript64 => "renderscript64",
563 };
564}
565
566// TODO issue #299
567fn targetEnvironName(target_environ: Environ) -> []const u8 {
568 return switch (target_environ) {
569 Environ.gnu => "gnu",
570 Environ.gnuabi64 => "gnuabi64",
571 Environ.gnueabi => "gnueabi",
572 Environ.gnueabihf => "gnueabihf",
573 Environ.gnux32 => "gnux32",
574 Environ.code16 => "code16",
575 Environ.eabi => "eabi",
576 Environ.eabihf => "eabihf",
577 Environ.android => "android",
578 Environ.musl => "musl",
579 Environ.musleabi => "musleabi",
580 Environ.musleabihf => "musleabihf",
581 Environ.msvc => "msvc",
582 Environ.itanium => "itanium",
583 Environ.cygnus => "cygnus",
584 Environ.amdopencl => "amdopencl",
585 Environ.coreclr => "coreclr",
586 };
587}
588
std/os/index.zig+1-1
...@@ -272,7 +272,7 @@ pub fn posixExecve(exe_path: []const u8, argv: []const []const u8, env_map: &con...@@ -272,7 +272,7 @@ pub fn posixExecve(exe_path: []const u8, argv: []const []const u8, env_map: &con
272 return posixExecveErrnoToErr(posix.getErrno(posix.execve(path_buf.ptr, argv_buf.ptr, envp_buf.ptr)));272 return posixExecveErrnoToErr(posix.getErrno(posix.execve(path_buf.ptr, argv_buf.ptr, envp_buf.ptr)));
273 }273 }
274274
275 const PATH = getEnv("PATH") ?? ([]const u8)("/usr/local/bin:/bin/:/usr/bin"); // TODO issue #299275 const PATH = getEnv("PATH") ?? "/usr/local/bin:/bin/:/usr/bin";
276 // PATH.len because it is >= the largest search_path276 // PATH.len because it is >= the largest search_path
277 // +1 for the / to join the search path and exe_path277 // +1 for the / to join the search path and exe_path
278 // +1 for the null terminating byte278 // +1 for the null terminating byte
test/cases/enum.zig+17
...@@ -1,4 +1,5 @@...@@ -1,4 +1,5 @@
1const assert = @import("std").debug.assert;1const assert = @import("std").debug.assert;
2const mem = @import("std").mem;
23
3test "enumType" {4test "enumType" {
4 const foo1 = Foo.One {13};5 const foo1 = Foo.One {13};
...@@ -103,3 +104,19 @@ const IntToEnumNumber = enum {...@@ -103,3 +104,19 @@ const IntToEnumNumber = enum {
103 Three,104 Three,
104 Four,105 Four,
105};106};
107
108
109test "enumTagName builtin function" {
110 assert(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));
111 comptime assert(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));
112}
113
114fn testEnumTagNameBare(n: BareNumber) -> []const u8 {
115 return @enumTagName(n);
116}
117
118const BareNumber = enum {
119 One,
120 Two,
121 Three,
122};