| author | |
| committer | |
| log | 095591f0b0f0d09bb1589fc404c2e7fdeac4bee4 |
| tree | d98a149b0a2472bdaef45b15bdcd42e4d6a42566 |
| parent | 7611ed3484ad810fe10d3c303a04d66bfa0bd6fd |
closes #29910 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 | 625 | ### @intToPtr(comptime DestType: type, int: usize) -> DestType |
| 626 | 626 | |
| 627 | 627 | Converts an integer to a pointer. To convert the other way, use `usize(ptr)`. |
| 628 | ||
| 629 | ### @enumTagName(value: var) -> []const u8 | |
| 630 | ||
| 631 | Converts an enum tag name to a slice of bytes. Example: |
src/all_types.hpp+12| ... | ... | @@ -966,6 +966,8 @@ struct TypeTableEntryEnum { |
| 966 | 966 | struct TypeTableEntryEnumTag { |
| 967 | 967 | TypeTableEntry *enum_type; |
| 968 | 968 | TypeTableEntry *int_type; |
| 969 | bool generate_name_table; | |
| 970 | LLVMValueRef name_table; | |
| 969 | 971 | }; |
| 970 | 972 | |
| 971 | 973 | struct TypeTableEntryUnion { |
| ... | ... | @@ -1200,6 +1202,7 @@ enum BuiltinFnId { |
| 1200 | 1202 | BuiltinFnIdPanic, |
| 1201 | 1203 | BuiltinFnIdPtrCast, |
| 1202 | 1204 | BuiltinFnIdIntToPtr, |
| 1205 | BuiltinFnIdEnumTagName, | |
| 1203 | 1206 | }; |
| 1204 | 1207 | |
| 1205 | 1208 | struct BuiltinFnEntry { |
| ... | ... | @@ -1464,6 +1467,8 @@ struct CodeGen { |
| 1464 | 1467 | |
| 1465 | 1468 | Buf global_asm; |
| 1466 | 1469 | ZigList<Buf *> link_objects; |
| 1470 | ||
| 1471 | ZigList<TypeTableEntry *> name_table_enums; | |
| 1467 | 1472 | }; |
| 1468 | 1473 | |
| 1469 | 1474 | enum VarLinkage { |
| ... | ... | @@ -1742,6 +1747,7 @@ enum IrInstructionId { |
| 1742 | 1747 | IrInstructionIdSetGlobalLinkage, |
| 1743 | 1748 | IrInstructionIdDeclRef, |
| 1744 | 1749 | IrInstructionIdPanic, |
| 1750 | IrInstructionIdEnumTagName, | |
| 1745 | 1751 | }; |
| 1746 | 1752 | |
| 1747 | 1753 | struct IrInstruction { |
| ... | ... | @@ -2481,6 +2487,12 @@ struct IrInstructionPanic { |
| 2481 | 2487 | IrInstruction *msg; |
| 2482 | 2488 | }; |
| 2483 | 2489 | |
| 2490 | struct IrInstructionEnumTagName { | |
| 2491 | IrInstruction base; | |
| 2492 | ||
| 2493 | IrInstruction *target; | |
| 2494 | }; | |
| 2495 | ||
| 2484 | 2496 | static const size_t slice_ptr_index = 0; |
| 2485 | 2497 | static const size_t slice_len_index = 1; |
| 2486 | 2498 |
src/analyze.cpp+1-1| ... | ... | @@ -1181,7 +1181,7 @@ bool type_is_invalid(TypeTableEntry *type_entry) { |
| 1181 | 1181 | } |
| 1182 | 1182 | |
| 1183 | 1183 | |
| 1184 | static TypeTableEntry *create_enum_tag_type(CodeGen *g, TypeTableEntry *enum_type, TypeTableEntry *int_type) { | |
| 1184 | TypeTableEntry *create_enum_tag_type(CodeGen *g, TypeTableEntry *enum_type, TypeTableEntry *int_type) { | |
| 1185 | 1185 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnumTag); |
| 1186 | 1186 | |
| 1187 | 1187 | buf_resize(&entry->name, 0); |
src/analyze.hpp+1| ... | ... | @@ -149,5 +149,6 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val); |
| 149 | 149 | TypeTableEntry *make_int_type(CodeGen *g, bool is_signed, size_t size_in_bits); |
| 150 | 150 | ConstParent *get_const_val_parent(ConstExprValue *value); |
| 151 | 151 | FnTableEntry *get_extern_panic_fn(CodeGen *g); |
| 152 | TypeTableEntry *create_enum_tag_type(CodeGen *g, TypeTableEntry *enum_type, TypeTableEntry *int_type); | |
| 152 | 153 | |
| 153 | 154 | #endif |
src/codegen.cpp+69-1| ... | ... | @@ -2134,6 +2134,29 @@ static LLVMValueRef ir_render_err_name(CodeGen *g, IrExecutable *executable, IrI |
| 2134 | 2134 | return LLVMBuildInBoundsGEP(g->builder, g->err_name_table, indices, 2, ""); |
| 2135 | 2135 | } |
| 2136 | 2136 | |
| 2137 | static 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 | ||
| 2137 | 2160 | static LLVMAtomicOrdering to_LLVMAtomicOrdering(AtomicOrder atomic_order) { |
| 2138 | 2161 | switch (atomic_order) { |
| 2139 | 2162 | case AtomicOrderUnordered: return LLVMAtomicOrderingUnordered; |
| ... | ... | @@ -2830,6 +2853,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 2830 | 2853 | return ir_render_container_init_list(g, executable, (IrInstructionContainerInitList *)instruction); |
| 2831 | 2854 | case IrInstructionIdPanic: |
| 2832 | 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 | 2859 | zig_unreachable(); |
| 2835 | 2860 | } |
| ... | ... | @@ -3390,6 +3415,46 @@ static void generate_error_name_table(CodeGen *g) { |
| 3390 | 3415 | LLVMSetUnnamedAddr(g->err_name_table, true); |
| 3391 | 3416 | } |
| 3392 | 3417 | |
| 3418 | static 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 | ||
| 3393 | 3458 | static void build_all_basic_blocks(CodeGen *g, FnTableEntry *fn) { |
| 3394 | 3459 | IrExecutable *executable = &fn->analyzed_executable; |
| 3395 | 3460 | assert(executable->basic_block_list.length > 0); |
| ... | ... | @@ -3428,6 +3493,7 @@ static void do_code_gen(CodeGen *g) { |
| 3428 | 3493 | |
| 3429 | 3494 | delete_unused_builtin_fns(g); |
| 3430 | 3495 | generate_error_name_table(g); |
| 3496 | generate_enum_name_tables(g); | |
| 3431 | 3497 | |
| 3432 | 3498 | // Generate module level variables |
| 3433 | 3499 | for (size_t i = 0; i < g->global_vars.length; i += 1) { |
| ... | ... | @@ -3800,7 +3866,8 @@ static const GlobalLinkageValue global_linkage_values[] = { |
| 3800 | 3866 | static void init_enum_debug_info(CodeGen *g, TypeTableEntry *enum_type) { |
| 3801 | 3867 | uint32_t field_count = enum_type->data.enumeration.src_field_count; |
| 3802 | 3868 | |
| 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 | 3871 | enum_type->data.enumeration.tag_type = tag_type_entry; |
| 3805 | 3872 | |
| 3806 | 3873 | ZigLLVMDIEnumerator **di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count); |
| ... | ... | @@ -4327,6 +4394,7 @@ static void define_builtin_fns(CodeGen *g) { |
| 4327 | 4394 | create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1); |
| 4328 | 4395 | create_builtin_fn(g, BuiltinFnIdPtrCast, "ptrcast", 2); |
| 4329 | 4396 | create_builtin_fn(g, BuiltinFnIdIntToPtr, "intToPtr", 2); |
| 4397 | create_builtin_fn(g, BuiltinFnIdEnumTagName, "enumTagName", 1); | |
| 4330 | 4398 | } |
| 4331 | 4399 | |
| 4332 | 4400 | static 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 | 541 | return IrInstructionIdPanic; |
| 542 | 542 | } |
| 543 | 543 | |
| 544 | static constexpr IrInstructionId ir_instruction_id(IrInstructionEnumTagName *) { | |
| 545 | return IrInstructionIdEnumTagName; | |
| 546 | } | |
| 547 | ||
| 544 | 548 | template<typename T> |
| 545 | 549 | static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { |
| 546 | 550 | T *special_instruction = allocate<T>(1); |
| ... | ... | @@ -2130,6 +2134,17 @@ static IrInstruction *ir_build_panic(IrBuilder *irb, Scope *scope, AstNode *sour |
| 2130 | 2134 | return &instruction->base; |
| 2131 | 2135 | } |
| 2132 | 2136 | |
| 2137 | static 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 | ||
| 2133 | 2148 | static IrInstruction *ir_instruction_br_get_dep(IrInstructionBr *instruction, size_t index) { |
| 2134 | 2149 | return nullptr; |
| 2135 | 2150 | } |
| ... | ... | @@ -2787,6 +2802,13 @@ static IrInstruction *ir_instruction_panic_get_dep(IrInstructionPanic *instructi |
| 2787 | 2802 | } |
| 2788 | 2803 | } |
| 2789 | 2804 | |
| 2805 | static 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 | ||
| 2790 | 2812 | static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t index) { |
| 2791 | 2813 | switch (instruction->id) { |
| 2792 | 2814 | case IrInstructionIdInvalid: |
| ... | ... | @@ -2975,6 +2997,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t |
| 2975 | 2997 | return ir_instruction_declref_get_dep((IrInstructionDeclRef *) instruction, index); |
| 2976 | 2998 | case IrInstructionIdPanic: |
| 2977 | 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 | 3003 | zig_unreachable(); |
| 2980 | 3004 | } |
| ... | ... | @@ -4239,6 +4263,16 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4239 | 4263 | |
| 4240 | 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 | 4277 | zig_unreachable(); |
| 4244 | 4278 | } |
| ... | ... | @@ -10290,6 +10324,8 @@ static IrInstruction *ir_analyze_enum_tag(IrAnalyze *ira, IrInstruction *source_ |
| 10290 | 10324 | return ira->codegen->invalid_instruction; |
| 10291 | 10325 | } |
| 10292 | 10326 | |
| 10327 | TypeTableEntry *tag_type = value->value.type->data.enumeration.tag_type; | |
| 10328 | ||
| 10293 | 10329 | if (instr_is_comptime(value)) { |
| 10294 | 10330 | ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); |
| 10295 | 10331 | if (!val) |
| ... | ... | @@ -10297,13 +10333,15 @@ static IrInstruction *ir_analyze_enum_tag(IrAnalyze *ira, IrInstruction *source_ |
| 10297 | 10333 | |
| 10298 | 10334 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, |
| 10299 | 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 | 10337 | const_instruction->base.value.special = ConstValSpecialStatic; |
| 10302 | 10338 | bignum_init_unsigned(&const_instruction->base.value.data.x_bignum, val->data.x_enum.tag); |
| 10303 | 10339 | return &const_instruction->base; |
| 10304 | 10340 | } |
| 10305 | 10341 | |
| 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 | } |
| 10308 | 10346 | |
| 10309 | 10347 | static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira, |
| ... | ... | @@ -11097,6 +11135,35 @@ static TypeTableEntry *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruc |
| 11097 | 11135 | return str_type; |
| 11098 | 11136 | } |
| 11099 | 11137 | |
| 11138 | static 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 | ||
| 11100 | 11167 | static TypeTableEntry *ir_analyze_instruction_type_name(IrAnalyze *ira, IrInstructionTypeName *instruction) { |
| 11101 | 11168 | IrInstruction *type_value = instruction->type_value->other; |
| 11102 | 11169 | TypeTableEntry *type_entry = ir_resolve_type(ira, type_value); |
| ... | ... | @@ -12641,6 +12708,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 12641 | 12708 | return ir_analyze_instruction_ptr_cast(ira, (IrInstructionPtrCast *)instruction); |
| 12642 | 12709 | case IrInstructionIdIntToPtr: |
| 12643 | 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 | 12713 | case IrInstructionIdMaybeWrap: |
| 12645 | 12714 | case IrInstructionIdErrWrapCode: |
| 12646 | 12715 | case IrInstructionIdErrWrapPayload: |
| ... | ... | @@ -12792,7 +12861,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 12792 | 12861 | case IrInstructionIdRef: |
| 12793 | 12862 | case IrInstructionIdMinValue: |
| 12794 | 12863 | case IrInstructionIdMaxValue: |
| 12795 | case IrInstructionIdErrName: | |
| 12796 | 12864 | case IrInstructionIdEmbedFile: |
| 12797 | 12865 | case IrInstructionIdDivExact: |
| 12798 | 12866 | case IrInstructionIdTruncate: |
| ... | ... | @@ -12819,9 +12887,11 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 12819 | 12887 | case IrInstructionIdIntToErr: |
| 12820 | 12888 | case IrInstructionIdErrToInt: |
| 12821 | 12889 | case IrInstructionIdTestType: |
| 12822 | case IrInstructionIdTypeName: | |
| 12823 | 12890 | case IrInstructionIdCanImplicitCast: |
| 12824 | 12891 | case IrInstructionIdDeclRef: |
| 12892 | case IrInstructionIdErrName: | |
| 12893 | case IrInstructionIdTypeName: | |
| 12894 | case IrInstructionIdEnumTagName: | |
| 12825 | 12895 | return false; |
| 12826 | 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 | 816 | } |
| 817 | 817 | |
| 818 | 818 | static void ir_print_test_type(IrPrint *irp, IrInstructionTestType *instruction) { |
| 819 | fprintf(irp->f, "@testType("); | |
| 819 | fprintf(irp->f, "testtype "); | |
| 820 | 820 | ir_print_other_instruction(irp, instruction->type_value); |
| 821 | fprintf(irp->f, ")"); | |
| 822 | 821 | } |
| 823 | 822 | |
| 824 | 823 | static void ir_print_type_name(IrPrint *irp, IrInstructionTypeName *instruction) { |
| 825 | fprintf(irp->f, "@typeName("); | |
| 824 | fprintf(irp->f, "typename "); | |
| 826 | 825 | ir_print_other_instruction(irp, instruction->type_value); |
| 827 | fprintf(irp->f, ")"); | |
| 826 | } | |
| 827 | ||
| 828 | static 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 | } |
| 829 | 832 | |
| 830 | 833 | static void ir_print_can_implicit_cast(IrPrint *irp, IrInstructionCanImplicitCast *instruction) { |
| ... | ... | @@ -1131,6 +1134,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 1131 | 1134 | case IrInstructionIdTypeName: |
| 1132 | 1135 | ir_print_type_name(irp, (IrInstructionTypeName *)instruction); |
| 1133 | 1136 | break; |
| 1137 | case IrInstructionIdEnumTagName: | |
| 1138 | ir_print_enum_tag_name(irp, (IrInstructionEnumTagName *)instruction); | |
| 1139 | break; | |
| 1134 | 1140 | case IrInstructionIdCanImplicitCast: |
| 1135 | 1141 | ir_print_can_implicit_cast(irp, (IrInstructionCanImplicitCast *)instruction); |
| 1136 | 1142 | break; |
std/build.zig+3-131| ... | ... | @@ -137,13 +137,13 @@ pub const Builder = struct { |
| 137 | 137 | Target.Native => {}, |
| 138 | 138 | Target.Cross => |cross_target| { |
| 139 | 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)); | |
| 141 | 141 | |
| 142 | 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)); | |
| 144 | 144 | |
| 145 | 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 | } |
| 149 | 149 | |
| ... | ... | @@ -458,131 +458,3 @@ fn printInvocation(exe_name: []const u8, args: &const List([]const u8)) { |
| 458 | 458 | } |
| 459 | 459 | %%io.stderr.printf("\n"); |
| 460 | 460 | } |
| 461 | ||
| 462 | // TODO issue #299 | |
| 463 | fn 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 | |
| 498 | fn 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 | |
| 567 | fn 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 | 272 | return posixExecveErrnoToErr(posix.getErrno(posix.execve(path_buf.ptr, argv_buf.ptr, envp_buf.ptr))); |
| 273 | 273 | } |
| 274 | 274 | |
| 275 | const PATH = getEnv("PATH") ?? ([]const u8)("/usr/local/bin:/bin/:/usr/bin"); // TODO issue #299 | |
| 275 | const PATH = getEnv("PATH") ?? "/usr/local/bin:/bin/:/usr/bin"; | |
| 276 | 276 | // PATH.len because it is >= the largest search_path |
| 277 | 277 | // +1 for the / to join the search path and exe_path |
| 278 | 278 | // +1 for the null terminating byte |
test/cases/enum.zig+17| ... | ... | @@ -1,4 +1,5 @@ |
| 1 | 1 | const assert = @import("std").debug.assert; |
| 2 | const mem = @import("std").mem; | |
| 2 | 3 | |
| 3 | 4 | test "enumType" { |
| 4 | 5 | const foo1 = Foo.One {13}; |
| ... | ... | @@ -103,3 +104,19 @@ const IntToEnumNumber = enum { |
| 103 | 104 | Three, |
| 104 | 105 | Four, |
| 105 | 106 | }; |
| 107 | ||
| 108 | ||
| 109 | test "enumTagName builtin function" { | |
| 110 | assert(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three")); | |
| 111 | comptime assert(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three")); | |
| 112 | } | |
| 113 | ||
| 114 | fn testEnumTagNameBare(n: BareNumber) -> []const u8 { | |
| 115 | return @enumTagName(n); | |
| 116 | } | |
| 117 | ||
| 118 | const BareNumber = enum { | |
| 119 | One, | |
| 120 | Two, | |
| 121 | Three, | |
| 122 | }; |