diff --git a/src/all_types.hpp b/src/all_types.hpp index 7947820590..a46f664c14 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1041,7 +1041,6 @@ enum BuiltinFnId { BuiltinFnIdUnreachable, BuiltinFnIdSetFnTest, BuiltinFnIdSetFnVisible, - BuiltinFnIdSetFnNoInline, BuiltinFnIdSetDebugSafety, }; @@ -1395,6 +1394,7 @@ enum IrInstructionId { IrInstructionIdRef, IrInstructionIdMinValue, IrInstructionIdMaxValue, + IrInstructionIdCompileErr, }; struct IrInstruction { @@ -1805,6 +1805,12 @@ struct IrInstructionMaxValue { IrInstruction *value; }; +struct IrInstructionCompileErr { + IrInstruction base; + + IrInstruction *msg; +}; + enum LValPurpose { LValPurposeNone, LValPurposeAssign, diff --git a/src/codegen.cpp b/src/codegen.cpp index 0fe7604a51..f40c59691a 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1823,6 +1823,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, case IrInstructionIdContainerInitFields: case IrInstructionIdMinValue: case IrInstructionIdMaxValue: + case IrInstructionIdCompileErr: zig_unreachable(); case IrInstructionIdReturn: return ir_render_return(g, executable, (IrInstructionReturn *)instruction); @@ -3068,7 +3069,6 @@ static void define_builtin_fns(CodeGen *g) { create_builtin_fn(g, BuiltinFnIdUnreachable, "unreachable", 0); create_builtin_fn(g, BuiltinFnIdSetFnTest, "setFnTest", 1); create_builtin_fn(g, BuiltinFnIdSetFnVisible, "setFnVisible", 2); - create_builtin_fn(g, BuiltinFnIdSetFnNoInline, "setFnNoInline", 2); create_builtin_fn(g, BuiltinFnIdSetDebugSafety, "setDebugSafety", 2); } diff --git a/src/ir.cpp b/src/ir.cpp index cc270a012d..3fc115cc1c 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -314,6 +314,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionMaxValue *) { return IrInstructionIdMaxValue; } +static constexpr IrInstructionId ir_instruction_id(IrInstructionCompileErr *) { + return IrInstructionIdCompileErr; +} + template static T *ir_create_instruction(IrExecutable *exec, Scope *scope, AstNode *source_node) { T *special_instruction = allocate(1); @@ -1267,6 +1271,15 @@ static IrInstruction *ir_build_max_value(IrBuilder *irb, Scope *scope, AstNode * return &instruction->base; } +static IrInstruction *ir_build_compile_err(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *msg) { + IrInstructionCompileErr *instruction = ir_build_instruction(irb, scope, source_node); + instruction->msg = msg; + + ir_ref_instruction(msg); + + return &instruction->base; +} + static void ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, bool gen_error_defers, bool gen_maybe_defers) @@ -1924,6 +1937,15 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo return ir_build_min_value(irb, scope, node, arg0_value); } + case BuiltinFnIdCompileErr: + { + 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; + + return ir_build_compile_err(irb, scope, node, arg0_value); + } case BuiltinFnIdMemcpy: case BuiltinFnIdMemset: case BuiltinFnIdAlignof: @@ -1935,7 +1957,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo case BuiltinFnIdCInclude: case BuiltinFnIdCDefine: case BuiltinFnIdCUndef: - case BuiltinFnIdCompileErr: case BuiltinFnIdCImport: case BuiltinFnIdErrName: case BuiltinFnIdBreakpoint: @@ -1947,7 +1968,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo case BuiltinFnIdDivExact: case BuiltinFnIdTruncate: case BuiltinFnIdIntType: - case BuiltinFnIdSetFnNoInline: zig_panic("TODO IR gen more builtin functions"); } zig_unreachable(); @@ -6782,6 +6802,18 @@ static TypeTableEntry *ir_analyze_instruction_max_value(IrAnalyze *ira, return ir_analyze_min_max(ira, &instruction->base, instruction->value->other, true); } +static TypeTableEntry *ir_analyze_instruction_compile_err(IrAnalyze *ira, + IrInstructionCompileErr *instruction) +{ + IrInstruction *msg_value = instruction->msg->other; + Buf *msg_buf = ir_resolve_str(ira, msg_value); + if (!msg_buf) + return ira->codegen->builtin_types.entry_invalid; + + ir_add_error(ira, &instruction->base, msg_buf); + return ira->codegen->builtin_types.entry_invalid; +} + static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { switch (instruction->id) { case IrInstructionIdInvalid: @@ -6870,6 +6902,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi return ir_analyze_instruction_min_value(ira, (IrInstructionMinValue *)instruction); case IrInstructionIdMaxValue: return ir_analyze_instruction_max_value(ira, (IrInstructionMaxValue *)instruction); + case IrInstructionIdCompileErr: + return ir_analyze_instruction_compile_err(ira, (IrInstructionCompileErr *)instruction); case IrInstructionIdCast: case IrInstructionIdStructFieldPtr: case IrInstructionIdEnumFieldPtr: @@ -6964,6 +6998,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { case IrInstructionIdSetFnVisible: case IrInstructionIdSetDebugSafety: case IrInstructionIdImport: + case IrInstructionIdCompileErr: return true; case IrInstructionIdPhi: case IrInstructionIdUnOp: @@ -7291,20 +7326,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { // return dest_type; //} // -//static TypeTableEntry *analyze_compile_err(CodeGen *g, ImportTableEntry *import, -// BlockContext *context, AstNode *node) -//{ -// AstNode *first_param_node = node->data.fn_call_expr.params.at(0); -// Buf *err_msg = resolve_const_expr_str(g, import, context, first_param_node->parent_field); -// if (!err_msg) { -// return g->builtin_types.entry_invalid; -// } -// -// add_node_error(g, node, err_msg); -// -// return g->builtin_types.entry_invalid; -//} -// //static TypeTableEntry *analyze_int_type(CodeGen *g, ImportTableEntry *import, // BlockContext *context, AstNode *node) //{ @@ -7344,41 +7365,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { // //} // -//static TypeTableEntry *analyze_set_fn_no_inline(CodeGen *g, ImportTableEntry *import, -// BlockContext *context, AstNode *node) -//{ -// AstNode **fn_node = &node->data.fn_call_expr.params.at(0); -// AstNode **value_node = &node->data.fn_call_expr.params.at(1); -// -// FnTableEntry *fn_entry = resolve_const_expr_fn(g, import, context, fn_node); -// if (!fn_entry) { -// return g->builtin_types.entry_invalid; -// } -// -// bool is_noinline; -// bool ok = resolve_const_expr_bool(g, import, context, value_node, &is_noinline); -// if (!ok) { -// return g->builtin_types.entry_invalid; -// } -// -// if (fn_entry->fn_no_inline_set_node) { -// ErrorMsg *msg = add_node_error(g, node, buf_sprintf("function no inline attribute set twice")); -// add_error_note(g, msg, fn_entry->fn_no_inline_set_node, buf_sprintf("first set here")); -// return g->builtin_types.entry_invalid; -// } -// fn_entry->fn_no_inline_set_node = node; -// -// if (fn_entry->fn_inline == FnInlineAlways) { -// add_node_error(g, node, buf_sprintf("function is both inline and noinline")); -// fn_entry->proto_node->data.fn_proto.skip = true; -// return g->builtin_types.entry_invalid; -// } else if (is_noinline) { -// fn_entry->fn_inline = FnInlineNever; -// } -// -// return g->builtin_types.entry_void; -//} -// //static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, // TypeTableEntry *expected_type, AstNode *node) //{ @@ -7566,8 +7552,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { // return analyze_div_exact(g, import, context, node); // case BuiltinFnIdTruncate: // return analyze_truncate(g, import, context, node); -// case BuiltinFnIdCompileErr: -// return analyze_compile_err(g, import, context, node); // case BuiltinFnIdIntType: // return analyze_int_type(g, import, context, node); // case BuiltinFnIdSetFnTest: diff --git a/src/ir_print.cpp b/src/ir_print.cpp index 8310cdf636..69df7d42cf 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -670,6 +670,12 @@ static void ir_print_max_value(IrPrint *irp, IrInstructionMaxValue *instruction) fprintf(irp->f, ")"); } +static void ir_print_compile_err(IrPrint *irp, IrInstructionCompileErr *instruction) { + fprintf(irp->f, "@compileError("); + ir_print_other_instruction(irp, instruction->msg); + fprintf(irp->f, ")"); +} + static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { ir_print_prefix(irp, instruction); switch (instruction->id) { @@ -813,6 +819,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { case IrInstructionIdMaxValue: ir_print_max_value(irp, (IrInstructionMaxValue *)instruction); break; + case IrInstructionIdCompileErr: + ir_print_compile_err(irp, (IrInstructionCompileErr *)instruction); + break; } fprintf(irp->f, "\n"); }