| ... | ... | @@ -318,6 +318,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCompileErr *) { |
| 318 | 318 | return IrInstructionIdCompileErr; |
| 319 | 319 | } |
| 320 | 320 | |
| 321 | static constexpr IrInstructionId ir_instruction_id(IrInstructionErrName *) { |
| 322 | return IrInstructionIdErrName; |
| 323 | } |
| 324 | |
| 321 | 325 | template<typename T> |
| 322 | 326 | static T *ir_create_instruction(IrExecutable *exec, Scope *scope, AstNode *source_node) { |
| 323 | 327 | T *special_instruction = allocate<T>(1); |
| ... | ... | @@ -508,8 +512,8 @@ static IrInstruction *ir_build_const_bound_fn(IrBuilder *irb, Scope *scope, AstN |
| 508 | 512 | return &const_instruction->base; |
| 509 | 513 | } |
| 510 | 514 | |
| 511 | | static IrInstruction *ir_build_const_str_lit(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *str) { |
| 512 | | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); |
| 515 | static IrInstruction *ir_create_const_str_lit(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *str) { |
| 516 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb->exec, scope, source_node); |
| 513 | 517 | TypeTableEntry *u8_type = irb->codegen->builtin_types.entry_u8; |
| 514 | 518 | TypeTableEntry *type_entry = get_array_type(irb->codegen, u8_type, buf_len(str)); |
| 515 | 519 | const_instruction->base.type_entry = type_entry; |
| ... | ... | @@ -526,6 +530,11 @@ static IrInstruction *ir_build_const_str_lit(IrBuilder *irb, Scope *scope, AstNo |
| 526 | 530 | |
| 527 | 531 | return &const_instruction->base; |
| 528 | 532 | } |
| 533 | static IrInstruction *ir_build_const_str_lit(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *str) { |
| 534 | IrInstruction *instruction = ir_create_const_str_lit(irb, scope, source_node, str); |
| 535 | ir_instruction_append(irb->current_basic_block, instruction); |
| 536 | return instruction; |
| 537 | } |
| 529 | 538 | |
| 530 | 539 | static IrInstruction *ir_build_const_c_str_lit(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *str) { |
| 531 | 540 | // first we build the underlying array |
| ... | ... | @@ -1229,15 +1238,6 @@ static IrInstruction *ir_build_array_len(IrBuilder *irb, Scope *scope, AstNode * |
| 1229 | 1238 | return &instruction->base; |
| 1230 | 1239 | } |
| 1231 | 1240 | |
| 1232 | | static IrInstruction *ir_build_array_len_from(IrBuilder *irb, IrInstruction *old_instruction, |
| 1233 | | IrInstruction *array_value) |
| 1234 | | { |
| 1235 | | IrInstruction *new_instruction = ir_build_array_len(irb, old_instruction->scope, |
| 1236 | | old_instruction->source_node, array_value); |
| 1237 | | ir_link_new_instruction(new_instruction, old_instruction); |
| 1238 | | return new_instruction; |
| 1239 | | } |
| 1240 | | |
| 1241 | 1241 | static IrInstruction *ir_build_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { |
| 1242 | 1242 | IrInstructionRef *instruction = ir_build_instruction<IrInstructionRef>(irb, scope, source_node); |
| 1243 | 1243 | instruction->value = value; |
| ... | ... | @@ -1280,6 +1280,22 @@ static IrInstruction *ir_build_compile_err(IrBuilder *irb, Scope *scope, AstNode |
| 1280 | 1280 | return &instruction->base; |
| 1281 | 1281 | } |
| 1282 | 1282 | |
| 1283 | static IrInstruction *ir_build_err_name(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { |
| 1284 | IrInstructionErrName *instruction = ir_build_instruction<IrInstructionErrName>(irb, scope, source_node); |
| 1285 | instruction->value = value; |
| 1286 | |
| 1287 | ir_ref_instruction(value); |
| 1288 | |
| 1289 | return &instruction->base; |
| 1290 | } |
| 1291 | |
| 1292 | static IrInstruction *ir_build_err_name_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *value) { |
| 1293 | IrInstruction *new_instruction = ir_build_err_name(irb, old_instruction->scope, |
| 1294 | old_instruction->source_node, value); |
| 1295 | ir_link_new_instruction(new_instruction, old_instruction); |
| 1296 | return new_instruction; |
| 1297 | } |
| 1298 | |
| 1283 | 1299 | |
| 1284 | 1300 | static void ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, |
| 1285 | 1301 | bool gen_error_defers, bool gen_maybe_defers) |
| ... | ... | @@ -1946,6 +1962,15 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 1946 | 1962 | |
| 1947 | 1963 | return ir_build_compile_err(irb, scope, node, arg0_value); |
| 1948 | 1964 | } |
| 1965 | case BuiltinFnIdErrName: |
| 1966 | { |
| 1967 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| 1968 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); |
| 1969 | if (arg0_value == irb->codegen->invalid_instruction) |
| 1970 | return arg0_value; |
| 1971 | |
| 1972 | return ir_build_err_name(irb, scope, node, arg0_value); |
| 1973 | } |
| 1949 | 1974 | case BuiltinFnIdMemcpy: |
| 1950 | 1975 | case BuiltinFnIdMemset: |
| 1951 | 1976 | case BuiltinFnIdAlignof: |
| ... | ... | @@ -1958,7 +1983,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 1958 | 1983 | case BuiltinFnIdCDefine: |
| 1959 | 1984 | case BuiltinFnIdCUndef: |
| 1960 | 1985 | case BuiltinFnIdCImport: |
| 1961 | | case BuiltinFnIdErrName: |
| 1962 | 1986 | case BuiltinFnIdBreakpoint: |
| 1963 | 1987 | case BuiltinFnIdReturnAddress: |
| 1964 | 1988 | case BuiltinFnIdFrameAddress: |
| ... | ... | @@ -2834,6 +2858,11 @@ static IrInstruction *ir_gen_type_literal(IrBuilder *irb, Scope *scope, AstNode |
| 2834 | 2858 | return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_type); |
| 2835 | 2859 | } |
| 2836 | 2860 | |
| 2861 | static IrInstruction *ir_gen_error_type(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 2862 | assert(node->type == NodeTypeErrorType); |
| 2863 | return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_pure_error); |
| 2864 | } |
| 2865 | |
| 2837 | 2866 | static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode *node) { |
| 2838 | 2867 | assert(node->type == NodeTypeDefer); |
| 2839 | 2868 | |
| ... | ... | @@ -2903,6 +2932,8 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 2903 | 2932 | return ir_lval_wrap(irb, scope, ir_gen_goto(irb, scope, node), lval); |
| 2904 | 2933 | case NodeTypeTypeLiteral: |
| 2905 | 2934 | return ir_lval_wrap(irb, scope, ir_gen_type_literal(irb, scope, node), lval); |
| 2935 | case NodeTypeErrorType: |
| 2936 | return ir_lval_wrap(irb, scope, ir_gen_error_type(irb, scope, node), lval); |
| 2906 | 2937 | case NodeTypeBreak: |
| 2907 | 2938 | return ir_lval_wrap(irb, scope, ir_gen_break(irb, scope, node), lval); |
| 2908 | 2939 | case NodeTypeContinue: |
| ... | ... | @@ -2913,7 +2944,6 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 2913 | 2944 | case NodeTypeSliceExpr: |
| 2914 | 2945 | case NodeTypeCharLiteral: |
| 2915 | 2946 | case NodeTypeZeroesLiteral: |
| 2916 | | case NodeTypeErrorType: |
| 2917 | 2947 | case NodeTypeVarLiteral: |
| 2918 | 2948 | case NodeTypeRoot: |
| 2919 | 2949 | case NodeTypeFnProto: |
| ... | ... | @@ -5564,7 +5594,20 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru |
| 5564 | 5594 | return ira->codegen->builtin_types.entry_invalid; |
| 5565 | 5595 | } |
| 5566 | 5596 | } else if (child_type->id == TypeTableEntryIdPureError) { |
| 5567 | | zig_panic("TODO error type field"); |
| 5597 | auto err_table_entry = ira->codegen->error_table.maybe_get(field_name); |
| 5598 | if (err_table_entry) { |
| 5599 | ConstExprValue *const_val = allocate<ConstExprValue>(1); |
| 5600 | const_val->special = ConstValSpecialStatic; |
| 5601 | const_val->data.x_pure_err = err_table_entry->value; |
| 5602 | |
| 5603 | bool depends_on_compile_var = container_ptr->static_value.depends_on_compile_var; |
| 5604 | return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, const_val, |
| 5605 | child_type, depends_on_compile_var, ConstPtrSpecialNone); |
| 5606 | } |
| 5607 | |
| 5608 | ir_add_error(ira, &field_ptr_instruction->base, |
| 5609 | buf_sprintf("use of undeclared error value '%s'", buf_ptr(field_name))); |
| 5610 | return ira->codegen->builtin_types.entry_invalid; |
| 5568 | 5611 | } else if (child_type->id == TypeTableEntryIdInt) { |
| 5569 | 5612 | zig_panic("TODO integer type field"); |
| 5570 | 5613 | } else { |
| ... | ... | @@ -6525,7 +6568,12 @@ static TypeTableEntry *ir_analyze_instruction_array_len(IrAnalyze *ira, |
| 6525 | 6568 | len_val->data.x_bignum.data.x_uint, depends_on_compile_var); |
| 6526 | 6569 | } |
| 6527 | 6570 | } |
| 6528 | | ir_build_array_len_from(&ira->new_irb, &array_len_instruction->base, array_value); |
| 6571 | TypeStructField *field = find_struct_type_field(canon_type, buf_create_from_str("len")); |
| 6572 | assert(field); |
| 6573 | IrInstruction *len_ptr = ir_build_struct_field_ptr(&ira->new_irb, array_len_instruction->base.scope, |
| 6574 | array_len_instruction->base.source_node, array_value, field); |
| 6575 | len_ptr->type_entry = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_usize, true); |
| 6576 | ir_build_load_ptr_from(&ira->new_irb, &array_len_instruction->base, len_ptr); |
| 6529 | 6577 | return ira->codegen->builtin_types.entry_usize; |
| 6530 | 6578 | } else { |
| 6531 | 6579 | add_node_error(ira->codegen, array_len_instruction->base.source_node, |
| ... | ... | @@ -6814,6 +6862,31 @@ static TypeTableEntry *ir_analyze_instruction_compile_err(IrAnalyze *ira, |
| 6814 | 6862 | return ira->codegen->builtin_types.entry_invalid; |
| 6815 | 6863 | } |
| 6816 | 6864 | |
| 6865 | static TypeTableEntry *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstructionErrName *instruction) { |
| 6866 | IrInstruction *value = instruction->value->other; |
| 6867 | if (value->type_entry->id == TypeTableEntryIdInvalid) |
| 6868 | return ira->codegen->builtin_types.entry_invalid; |
| 6869 | |
| 6870 | IrInstruction *casted_value = ir_get_casted_value(ira, value, value->type_entry); |
| 6871 | if (casted_value->type_entry->id == TypeTableEntryIdInvalid) |
| 6872 | return ira->codegen->builtin_types.entry_invalid; |
| 6873 | |
| 6874 | TypeTableEntry *str_type = get_slice_type(ira->codegen, ira->codegen->builtin_types.entry_u8, true); |
| 6875 | if (casted_value->static_value.special == ConstValSpecialStatic) { |
| 6876 | ErrorTableEntry *err = casted_value->static_value.data.x_pure_err; |
| 6877 | IrInstruction *new_instruction = ir_create_const_str_lit(&ira->new_irb, instruction->base.scope, |
| 6878 | instruction->base.source_node, &err->name); |
| 6879 | ir_link_new_instruction(new_instruction, &instruction->base); |
| 6880 | new_instruction->static_value.special = ConstValSpecialStatic; |
| 6881 | new_instruction->static_value.depends_on_compile_var = casted_value->static_value.depends_on_compile_var; |
| 6882 | return str_type; |
| 6883 | } |
| 6884 | |
| 6885 | ira->codegen->generate_error_name_table = true; |
| 6886 | ir_build_err_name_from(&ira->new_irb, &instruction->base, value); |
| 6887 | return str_type; |
| 6888 | } |
| 6889 | |
| 6817 | 6890 | static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { |
| 6818 | 6891 | switch (instruction->id) { |
| 6819 | 6892 | case IrInstructionIdInvalid: |
| ... | ... | @@ -6904,6 +6977,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 6904 | 6977 | return ir_analyze_instruction_max_value(ira, (IrInstructionMaxValue *)instruction); |
| 6905 | 6978 | case IrInstructionIdCompileErr: |
| 6906 | 6979 | return ir_analyze_instruction_compile_err(ira, (IrInstructionCompileErr *)instruction); |
| 6980 | case IrInstructionIdErrName: |
| 6981 | return ir_analyze_instruction_err_name(ira, (IrInstructionErrName *)instruction); |
| 6907 | 6982 | case IrInstructionIdCast: |
| 6908 | 6983 | case IrInstructionIdStructFieldPtr: |
| 6909 | 6984 | case IrInstructionIdEnumFieldPtr: |
| ... | ... | @@ -7033,6 +7108,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 7033 | 7108 | case IrInstructionIdRef: |
| 7034 | 7109 | case IrInstructionIdMinValue: |
| 7035 | 7110 | case IrInstructionIdMaxValue: |
| 7111 | case IrInstructionIdErrName: |
| 7036 | 7112 | return false; |
| 7037 | 7113 | case IrInstructionIdAsm: |
| 7038 | 7114 | { |
| ... | ... | @@ -7103,25 +7179,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 7103 | 7179 | // return resolve_expr_const_val_as_import(g, node, child_import); |
| 7104 | 7180 | //} |
| 7105 | 7181 | // |
| 7106 | | //static TypeTableEntry *analyze_err_name(CodeGen *g, ImportTableEntry *import, |
| 7107 | | // BlockContext *context, AstNode *node) |
| 7108 | | //{ |
| 7109 | | // assert(node->type == NodeTypeFnCallExpr); |
| 7110 | | // |
| 7111 | | // AstNode *err_value = node->data.fn_call_expr.params.at(0); |
| 7112 | | // TypeTableEntry *resolved_type = analyze_expression(g, import, context, |
| 7113 | | // g->builtin_types.entry_pure_error, err_value); |
| 7114 | | // |
| 7115 | | // if (resolved_type->id == TypeTableEntryIdInvalid) { |
| 7116 | | // return resolved_type; |
| 7117 | | // } |
| 7118 | | // |
| 7119 | | // g->generate_error_name_table = true; |
| 7120 | | // |
| 7121 | | // TypeTableEntry *str_type = get_slice_type(g, g->builtin_types.entry_u8, true); |
| 7122 | | // return str_type; |
| 7123 | | //} |
| 7124 | | // |
| 7125 | 7182 | //static TypeTableEntry *analyze_embed_file(CodeGen *g, ImportTableEntry *import, |
| 7126 | 7183 | // BlockContext *context, AstNode *node) |
| 7127 | 7184 | //{ |
| ... | ... | @@ -7533,8 +7590,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 7533 | 7590 | // return analyze_import(g, import, context, node); |
| 7534 | 7591 | // case BuiltinFnIdCImport: |
| 7535 | 7592 | // return analyze_c_import(g, import, context, node); |
| 7536 | | // case BuiltinFnIdErrName: |
| 7537 | | // return analyze_err_name(g, import, context, node); |
| 7538 | 7593 | // case BuiltinFnIdBreakpoint: |
| 7539 | 7594 | // mark_impure_fn(g, context, node); |
| 7540 | 7595 | // return g->builtin_types.entry_void; |
| ... | ... | @@ -7927,21 +7982,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 7927 | 7982 | // } |
| 7928 | 7983 | //} |
| 7929 | 7984 | // |
| 7930 | | //static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *import, |
| 7931 | | // BlockContext *context, AstNode *node, Buf *err_name) |
| 7932 | | //{ |
| 7933 | | // auto err_table_entry = g->error_table.maybe_get(err_name); |
| 7934 | | // |
| 7935 | | // if (err_table_entry) { |
| 7936 | | // return resolve_expr_const_val_as_err(g, node, err_table_entry->value); |
| 7937 | | // } |
| 7938 | | // |
| 7939 | | // add_node_error(g, node, |
| 7940 | | // buf_sprintf("use of undeclared error value '%s'", buf_ptr(err_name))); |
| 7941 | | // |
| 7942 | | // return g->builtin_types.entry_invalid; |
| 7943 | | //} |
| 7944 | | // |
| 7945 | 7985 | //static void validate_voided_expr(CodeGen *g, AstNode *source_node, TypeTableEntry *type_entry) { |
| 7946 | 7986 | // if (type_entry->id == TypeTableEntryIdMetaType) { |
| 7947 | 7987 | // add_node_error(g, first_executing_node(source_node), buf_sprintf("expected expression, found type")); |
| ... | ... | @@ -7952,32 +7992,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 7952 | 7992 | // |
| 7953 | 7993 | |
| 7954 | 7994 | |
| 7955 | | //static LLVMValueRef gen_err_name(CodeGen *g, AstNode *node) { |
| 7956 | | // assert(node->type == NodeTypeFnCallExpr); |
| 7957 | | // assert(g->generate_error_name_table); |
| 7958 | | // |
| 7959 | | // if (g->error_decls.length == 1) { |
| 7960 | | // LLVMBuildUnreachable(g->builder); |
| 7961 | | // return nullptr; |
| 7962 | | // } |
| 7963 | | // |
| 7964 | | // |
| 7965 | | // AstNode *err_val_node = node->data.fn_call_expr.params.at(0); |
| 7966 | | // LLVMValueRef err_val = gen_expr(g, err_val_node); |
| 7967 | | // |
| 7968 | | // if (want_debug_safety(g, node)) { |
| 7969 | | // LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(err_val)); |
| 7970 | | // LLVMValueRef end_val = LLVMConstInt(LLVMTypeOf(err_val), g->error_decls.length, false); |
| 7971 | | // add_bounds_check(g, err_val, LLVMIntNE, zero, LLVMIntULT, end_val); |
| 7972 | | // } |
| 7973 | | // |
| 7974 | | // LLVMValueRef indices[] = { |
| 7975 | | // LLVMConstNull(g->builtin_types.entry_usize->type_ref), |
| 7976 | | // err_val, |
| 7977 | | // }; |
| 7978 | | // return LLVMBuildInBoundsGEP(g->builder, g->err_name_table, indices, 2, ""); |
| 7979 | | //} |
| 7980 | | // |
| 7981 | 7995 | //static LLVMValueRef gen_cmp_exchange(CodeGen *g, AstNode *node) { |
| 7982 | 7996 | // assert(node->type == NodeTypeFnCallExpr); |
| 7983 | 7997 | // |
| ... | ... | @@ -8179,8 +8193,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 8179 | 8193 | // zig_unreachable(); |
| 8180 | 8194 | // case BuiltinFnIdCompileVar: |
| 8181 | 8195 | // return nullptr; |
| 8182 | | // case BuiltinFnIdErrName: |
| 8183 | | // return gen_err_name(g, node); |
| 8184 | 8196 | // case BuiltinFnIdBreakpoint: |
| 8185 | 8197 | // return LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, ""); |
| 8186 | 8198 | // case BuiltinFnIdFrameAddress: |