authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-10-09 02:20:01-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-10-09 02:20:01-04:00
log77ae3442ef2dee1659ab5778f43c00026fd21dd9
tree3a9a3eae379ec2412608bc433d03df2a590e815b
parent07fe60ded1727d528d3ae36b892aa7c84262ed96

explicit casting works with IR


7 files changed, 835 insertions(+), 670 deletions(-)

src/all_types.hpp+5-2
......@@ -29,6 +29,7 @@ struct TypeStructField;
2929struct CodeGen;
3030struct ConstExprValue;
3131struct IrInstruction;
32struct IrInstructionCast;
3233struct IrBasicBlock;
3334
3435struct IrExecutable {
......@@ -1121,7 +1122,7 @@ struct FnTableEntry {
11211122 AstNode *fn_test_set_node;
11221123 AstNode *fn_static_eval_set_node;
11231124
1124 ZigList<AstNode *> cast_alloca_list;
1125 ZigList<IrInstructionCast *> cast_alloca_list;
11251126 ZigList<StructValExprCodeGen *> struct_val_expr_alloca_list;
11261127 ZigList<VariableTableEntry *> variable_list;
11271128 ZigList<AstNode *> goto_list;
......@@ -1435,6 +1436,7 @@ struct IrInstruction {
14351436 // if ref_count is zero, instruction can be omitted in codegen
14361437 size_t ref_count;
14371438 IrInstruction *other;
1439 ReturnKnowledge return_knowledge;
14381440};
14391441
14401442struct IrInstructionCondBr {
......@@ -1547,7 +1549,8 @@ struct IrInstructionCast {
15471549
15481550 IrInstruction *value;
15491551 IrInstruction *dest_type;
1550 bool is_implicit;
1552 CastOp cast_op;
1553 LLVMValueRef tmp_ptr;
15511554};
15521555
15531556#endif
src/analyze.cpp+11-290
......@@ -25,8 +25,6 @@ static VariableTableEntry *analyze_variable_declaration(CodeGen *g, ImportTableE
2525 BlockContext *context, TypeTableEntry *expected_type, AstNode *node);
2626static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *struct_type);
2727static TypeTableEntry *unwrapped_node_type(AstNode *node);
28static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
29 AstNode *node);
3028static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *import,
3129 BlockContext *context, AstNode *node, Buf *err_name);
3230static TypeTableEntry *analyze_block_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
......@@ -115,7 +113,7 @@ AstNode *first_executing_node(AstNode *node) {
115113 zig_unreachable();
116114}
117115
118static void mark_impure_fn(CodeGen *g, BlockContext *context, AstNode *node) {
116void mark_impure_fn(CodeGen *g, BlockContext *context, AstNode *node) {
119117 if (!context->fn_entry) return;
120118 if (!context->fn_entry->is_pure) return;
121119
......@@ -261,11 +259,6 @@ uint64_t type_size(CodeGen *g, TypeTableEntry *type_entry) {
261259 }
262260}
263261
264static bool is_u8(TypeTableEntry *type) {
265 return type->id == TypeTableEntryIdInt &&
266 !type->data.integral.is_signed && type->data.integral.bit_count == 8;
267}
268
269262static bool is_slice(TypeTableEntry *type) {
270263 return type->id == TypeTableEntryIdStruct && type->data.structure.is_slice;
271264}
......@@ -4466,30 +4459,7 @@ static TypeTableEntry *analyze_min_max_value(CodeGen *g, ImportTableEntry *impor
44664459 }
44674460}
44684461
4469static TypeTableEntry *resolve_cast(CodeGen *g, BlockContext *context, AstNode *node,
4470 AstNode *expr_node, TypeTableEntry *wanted_type, CastOp op, bool need_alloca)
4471{
4472 node->data.fn_call_expr.cast_op = op;
4473
4474 ConstExprValue *other_val = &get_resolved_expr(expr_node)->const_val;
4475 TypeTableEntry *other_type = get_resolved_expr(expr_node)->type_entry;
4476 ConstExprValue *const_val = &get_resolved_expr(node)->const_val;
4477 if (other_val->ok) {
4478 eval_const_expr_implicit_cast(node->data.fn_call_expr.cast_op, other_val, other_type,
4479 const_val, wanted_type);
4480 }
4481
4482 if (need_alloca) {
4483 if (context->fn_entry) {
4484 context->fn_entry->cast_alloca_list.append(node);
4485 } else {
4486 assert(get_resolved_expr(node)->const_val.ok);
4487 }
4488 }
4489 return wanted_type;
4490}
4491
4492static bool type_is_codegen_pointer(TypeTableEntry *type) {
4462bool type_is_codegen_pointer(TypeTableEntry *type) {
44934463 if (type->id == TypeTableEntryIdPointer) return true;
44944464 if (type->id == TypeTableEntryIdFn) return true;
44954465 if (type->id == TypeTableEntryIdMaybe) {
......@@ -4499,256 +4469,6 @@ static bool type_is_codegen_pointer(TypeTableEntry *type) {
44994469 return false;
45004470}
45014471
4502static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
4503 AstNode *node)
4504{
4505 assert(node->type == NodeTypeFnCallExpr);
4506
4507 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
4508 size_t actual_param_count = node->data.fn_call_expr.params.length;
4509
4510 if (actual_param_count != 1) {
4511 add_node_error(g, fn_ref_expr, buf_sprintf("cast expression expects exactly one parameter"));
4512 return g->builtin_types.entry_invalid;
4513 }
4514
4515 AstNode *expr_node = node->data.fn_call_expr.params.at(0);
4516 TypeTableEntry *wanted_type = resolve_type(g, fn_ref_expr);
4517 TypeTableEntry *actual_type = analyze_expression(g, import, context, nullptr, expr_node);
4518 TypeTableEntry *wanted_type_canon = get_underlying_type(wanted_type);
4519 TypeTableEntry *actual_type_canon = get_underlying_type(actual_type);
4520
4521 if (wanted_type_canon->id == TypeTableEntryIdInvalid ||
4522 actual_type_canon->id == TypeTableEntryIdInvalid)
4523 {
4524 return g->builtin_types.entry_invalid;
4525 }
4526
4527 // explicit match or non-const to const
4528 if (types_match_const_cast_only(wanted_type, actual_type)) {
4529 return resolve_cast(g, context, node, expr_node, wanted_type, CastOpNoop, false);
4530 }
4531
4532 // explicit cast from bool to int
4533 if (wanted_type_canon->id == TypeTableEntryIdInt &&
4534 actual_type_canon->id == TypeTableEntryIdBool)
4535 {
4536 return resolve_cast(g, context, node, expr_node, wanted_type, CastOpBoolToInt, false);
4537 }
4538
4539 // explicit cast from pointer to isize or usize
4540 if ((wanted_type_canon == g->builtin_types.entry_isize || wanted_type_canon == g->builtin_types.entry_usize) &&
4541 type_is_codegen_pointer(actual_type_canon))
4542 {
4543 return resolve_cast(g, context, node, expr_node, wanted_type, CastOpPtrToInt, false);
4544 }
4545
4546
4547 // explicit cast from isize or usize to pointer
4548 if (wanted_type_canon->id == TypeTableEntryIdPointer &&
4549 (actual_type_canon == g->builtin_types.entry_isize || actual_type_canon == g->builtin_types.entry_usize))
4550 {
4551 return resolve_cast(g, context, node, expr_node, wanted_type, CastOpIntToPtr, false);
4552 }
4553
4554 // explicit widening or shortening cast
4555 if ((wanted_type_canon->id == TypeTableEntryIdInt &&
4556 actual_type_canon->id == TypeTableEntryIdInt) ||
4557 (wanted_type_canon->id == TypeTableEntryIdFloat &&
4558 actual_type_canon->id == TypeTableEntryIdFloat))
4559 {
4560 return resolve_cast(g, context, node, expr_node, wanted_type, CastOpWidenOrShorten, false);
4561 }
4562
4563 // explicit cast from int to float
4564 if (wanted_type_canon->id == TypeTableEntryIdFloat &&
4565 actual_type_canon->id == TypeTableEntryIdInt)
4566 {
4567 return resolve_cast(g, context, node, expr_node, wanted_type, CastOpIntToFloat, false);
4568 }
4569
4570 // explicit cast from float to int
4571 if (wanted_type_canon->id == TypeTableEntryIdInt &&
4572 actual_type_canon->id == TypeTableEntryIdFloat)
4573 {
4574 return resolve_cast(g, context, node, expr_node, wanted_type, CastOpFloatToInt, false);
4575 }
4576
4577 // explicit cast from array to slice
4578 if (is_slice(wanted_type) &&
4579 actual_type->id == TypeTableEntryIdArray &&
4580 types_match_const_cast_only(
4581 wanted_type->data.structure.fields[0].type_entry->data.pointer.child_type,
4582 actual_type->data.array.child_type))
4583 {
4584 return resolve_cast(g, context, node, expr_node, wanted_type, CastOpToUnknownSizeArray, true);
4585 }
4586
4587 // explicit cast from []T to []u8 or []u8 to []T
4588 if (is_slice(wanted_type) && is_slice(actual_type) &&
4589 (is_u8(wanted_type->data.structure.fields[0].type_entry->data.pointer.child_type) ||
4590 is_u8(actual_type->data.structure.fields[0].type_entry->data.pointer.child_type)) &&
4591 (wanted_type->data.structure.fields[0].type_entry->data.pointer.is_const ||
4592 !actual_type->data.structure.fields[0].type_entry->data.pointer.is_const))
4593 {
4594 mark_impure_fn(g, context, node);
4595 return resolve_cast(g, context, node, expr_node, wanted_type, CastOpResizeSlice, true);
4596 }
4597
4598 // explicit cast from [N]u8 to []T
4599 if (is_slice(wanted_type) &&
4600 actual_type->id == TypeTableEntryIdArray &&
4601 is_u8(actual_type->data.array.child_type))
4602 {
4603 mark_impure_fn(g, context, node);
4604 uint64_t child_type_size = type_size(g,
4605 wanted_type->data.structure.fields[0].type_entry->data.pointer.child_type);
4606 if (actual_type->data.array.len % child_type_size == 0) {
4607 return resolve_cast(g, context, node, expr_node, wanted_type, CastOpBytesToSlice, true);
4608 } else {
4609 add_node_error(g, node,
4610 buf_sprintf("unable to convert %s to %s: size mismatch",
4611 buf_ptr(&actual_type->name), buf_ptr(&wanted_type->name)));
4612 return g->builtin_types.entry_invalid;
4613 }
4614 }
4615
4616 // explicit cast from pointer to another pointer
4617 if ((actual_type->id == TypeTableEntryIdPointer || actual_type->id == TypeTableEntryIdFn) &&
4618 (wanted_type->id == TypeTableEntryIdPointer || wanted_type->id == TypeTableEntryIdFn))
4619 {
4620 return resolve_cast(g, context, node, expr_node, wanted_type, CastOpPointerReinterpret, false);
4621 }
4622
4623 // explicit cast from maybe pointer to another maybe pointer
4624 if (actual_type->id == TypeTableEntryIdMaybe &&
4625 (actual_type->data.maybe.child_type->id == TypeTableEntryIdPointer ||
4626 actual_type->data.maybe.child_type->id == TypeTableEntryIdFn) &&
4627 wanted_type->id == TypeTableEntryIdMaybe &&
4628 (wanted_type->data.maybe.child_type->id == TypeTableEntryIdPointer ||
4629 wanted_type->data.maybe.child_type->id == TypeTableEntryIdFn))
4630 {
4631 return resolve_cast(g, context, node, expr_node, wanted_type, CastOpPointerReinterpret, false);
4632 }
4633
4634 // explicit cast from child type of maybe type to maybe type
4635 if (wanted_type->id == TypeTableEntryIdMaybe) {
4636 if (types_match_const_cast_only(wanted_type->data.maybe.child_type, actual_type)) {
4637 get_resolved_expr(node)->return_knowledge = ReturnKnowledgeKnownNonNull;
4638 return resolve_cast(g, context, node, expr_node, wanted_type, CastOpMaybeWrap, true);
4639 } else if (actual_type->id == TypeTableEntryIdNumLitInt ||
4640 actual_type->id == TypeTableEntryIdNumLitFloat)
4641 {
4642 if (num_lit_fits_in_other_type(g, expr_node, wanted_type->data.maybe.child_type)) {
4643 get_resolved_expr(node)->return_knowledge = ReturnKnowledgeKnownNonNull;
4644 return resolve_cast(g, context, node, expr_node, wanted_type, CastOpMaybeWrap, true);
4645 } else {
4646 return g->builtin_types.entry_invalid;
4647 }
4648 }
4649 }
4650
4651 // explicit cast from null literal to maybe type
4652 if (wanted_type->id == TypeTableEntryIdMaybe &&
4653 actual_type->id == TypeTableEntryIdNullLit)
4654 {
4655 get_resolved_expr(node)->return_knowledge = ReturnKnowledgeKnownNull;
4656 return resolve_cast(g, context, node, expr_node, wanted_type, CastOpNullToMaybe, true);
4657 }
4658
4659 // explicit cast from child type of error type to error type
4660 if (wanted_type->id == TypeTableEntryIdErrorUnion) {
4661 if (types_match_const_cast_only(wanted_type->data.error.child_type, actual_type)) {
4662 get_resolved_expr(node)->return_knowledge = ReturnKnowledgeKnownNonError;
4663 return resolve_cast(g, context, node, expr_node, wanted_type, CastOpErrorWrap, true);
4664 } else if (actual_type->id == TypeTableEntryIdNumLitInt ||
4665 actual_type->id == TypeTableEntryIdNumLitFloat)
4666 {
4667 if (num_lit_fits_in_other_type(g, expr_node, wanted_type->data.error.child_type)) {
4668 get_resolved_expr(node)->return_knowledge = ReturnKnowledgeKnownNonError;
4669 return resolve_cast(g, context, node, expr_node, wanted_type, CastOpErrorWrap, true);
4670 } else {
4671 return g->builtin_types.entry_invalid;
4672 }
4673 }
4674 }
4675
4676 // explicit cast from pure error to error union type
4677 if (wanted_type->id == TypeTableEntryIdErrorUnion &&
4678 actual_type->id == TypeTableEntryIdPureError)
4679 {
4680 get_resolved_expr(node)->return_knowledge = ReturnKnowledgeKnownError;
4681 return resolve_cast(g, context, node, expr_node, wanted_type, CastOpPureErrorWrap, false);
4682 }
4683
4684 // explicit cast from number literal to another type
4685 if (actual_type->id == TypeTableEntryIdNumLitFloat ||
4686 actual_type->id == TypeTableEntryIdNumLitInt)
4687 {
4688 if (num_lit_fits_in_other_type(g, expr_node, wanted_type_canon)) {
4689 CastOp op;
4690 if ((actual_type->id == TypeTableEntryIdNumLitFloat &&
4691 wanted_type_canon->id == TypeTableEntryIdFloat) ||
4692 (actual_type->id == TypeTableEntryIdNumLitInt &&
4693 wanted_type_canon->id == TypeTableEntryIdInt))
4694 {
4695 op = CastOpNoop;
4696 } else if (wanted_type_canon->id == TypeTableEntryIdInt) {
4697 op = CastOpFloatToInt;
4698 } else if (wanted_type_canon->id == TypeTableEntryIdFloat) {
4699 op = CastOpIntToFloat;
4700 } else {
4701 zig_unreachable();
4702 }
4703 return resolve_cast(g, context, node, expr_node, wanted_type, op, false);
4704 } else {
4705 return g->builtin_types.entry_invalid;
4706 }
4707 }
4708
4709 // explicit cast from %void to integer type which can fit it
4710 bool actual_type_is_void_err = actual_type->id == TypeTableEntryIdErrorUnion &&
4711 !type_has_bits(actual_type->data.error.child_type);
4712 bool actual_type_is_pure_err = actual_type->id == TypeTableEntryIdPureError;
4713 if ((actual_type_is_void_err || actual_type_is_pure_err) &&
4714 wanted_type->id == TypeTableEntryIdInt)
4715 {
4716 BigNum bn;
4717 bignum_init_unsigned(&bn, g->error_decls.length);
4718 if (bignum_fits_in_bits(&bn, wanted_type->data.integral.bit_count,
4719 wanted_type->data.integral.is_signed))
4720 {
4721 return resolve_cast(g, context, node, expr_node, wanted_type, CastOpErrToInt, false);
4722 } else {
4723 add_node_error(g, node,
4724 buf_sprintf("too many error values to fit in '%s'", buf_ptr(&wanted_type->name)));
4725 return g->builtin_types.entry_invalid;
4726 }
4727 }
4728
4729 // explicit cast from integer to enum type with no payload
4730 if (actual_type->id == TypeTableEntryIdInt &&
4731 wanted_type->id == TypeTableEntryIdEnum &&
4732 wanted_type->data.enumeration.gen_field_count == 0)
4733 {
4734 return resolve_cast(g, context, node, expr_node, wanted_type, CastOpIntToEnum, false);
4735 }
4736
4737 // explicit cast from enum type with no payload to integer
4738 if (wanted_type->id == TypeTableEntryIdInt &&
4739 actual_type->id == TypeTableEntryIdEnum &&
4740 actual_type->data.enumeration.gen_field_count == 0)
4741 {
4742 return resolve_cast(g, context, node, expr_node, wanted_type, CastOpEnumToInt, false);
4743 }
4744
4745 add_node_error(g, node,
4746 buf_sprintf("invalid cast from type '%s' to '%s'",
4747 buf_ptr(&actual_type->name),
4748 buf_ptr(&wanted_type->name)));
4749 return g->builtin_types.entry_invalid;
4750}
4751
47524472static TypeTableEntry *analyze_import(CodeGen *g, ImportTableEntry *import, BlockContext *context,
47534473 AstNode *node)
47544474{
......@@ -5866,13 +5586,14 @@ static TypeTableEntry *analyze_fn_call_ptr(CodeGen *g, ImportTableEntry *import,
58665586 }
58675587 }
58685588
5869 if (handle_is_ptr(return_type)) {
5870 if (context->fn_entry) {
5871 context->fn_entry->cast_alloca_list.append(node);
5872 } else if (!result_val->ok) {
5873 add_node_error(g, node, buf_sprintf("unable to evaluate constant expression"));
5874 }
5875 }
5589 // TODO
5590 //if (handle_is_ptr(return_type)) {
5591 // if (context->fn_entry) {
5592 // context->fn_entry->cast_alloca_list.append(node);
5593 // } else if (!result_val->ok) {
5594 // add_node_error(g, node, buf_sprintf("unable to evaluate constant expression"));
5595 // }
5596 //}
58765597
58775598 return return_type;
58785599}
......@@ -6110,7 +5831,7 @@ static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import
61105831
61115832 if (const_val->ok) {
61125833 if (invoke_type_entry->id == TypeTableEntryIdMetaType) {
6113 return analyze_cast_expr(g, import, context, node);
5834 zig_unreachable();
61145835 } else if (invoke_type_entry->id == TypeTableEntryIdFn) {
61155836 AstNode *struct_node;
61165837 if (fn_ref_expr->type == NodeTypeFieldAccessExpr &&
src/analyze.hpp+4
......@@ -49,10 +49,14 @@ TypeTableEntry *resolve_peer_type_compatibility(CodeGen *g, ImportTableEntry *im
4949 BlockContext *block_context, AstNode *parent_source_node,
5050 AstNode **child_nodes, TypeTableEntry **child_types, size_t child_count);
5151
52
53
5254bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *actual_type);
5355VariableTableEntry *find_variable(CodeGen *g, BlockContext *orig_context, Buf *name);
5456AstNode *find_decl(BlockContext *context, Buf *name);
5557void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only);
5658TopLevelDecl *get_as_top_level_decl(AstNode *node);
59void mark_impure_fn(CodeGen *g, BlockContext *context, AstNode *node);
60bool type_is_codegen_pointer(TypeTableEntry *type);
5761
5862#endif
src/codegen.cpp+255-359
......@@ -344,11 +344,10 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, TypeTableEntry *int_type, Bui
344344 return *fn;
345345}
346346
347static LLVMValueRef get_handle_value(CodeGen *g, AstNode *source_node, LLVMValueRef ptr, TypeTableEntry *type) {
347static LLVMValueRef get_handle_value(CodeGen *g, LLVMValueRef ptr, TypeTableEntry *type) {
348348 if (handle_is_ptr(type)) {
349349 return ptr;
350350 } else {
351 set_debug_source_node(g, source_node);
352351 return LLVMBuildLoad(g->builder, ptr, "");
353352 }
354353}
......@@ -378,7 +377,7 @@ static void gen_debug_safety_crash(CodeGen *g) {
378377 LLVMBuildUnreachable(g->builder);
379378}
380379
381static void add_bounds_check(CodeGen *g, AstNode *source_node, LLVMValueRef target_val,
380static void add_bounds_check(CodeGen *g, LLVMValueRef target_val,
382381 LLVMIntPredicate lower_pred, LLVMValueRef lower_value,
383382 LLVMIntPredicate upper_pred, LLVMValueRef upper_value)
384383{
......@@ -391,8 +390,6 @@ static void add_bounds_check(CodeGen *g, AstNode *source_node, LLVMValueRef targ
391390 upper_value = nullptr;
392391 }
393392
394 set_debug_source_node(g, source_node);
395
396393 LLVMBasicBlockRef bounds_check_fail_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "BoundsCheckFail");
397394 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "BoundsCheckOk");
398395 LLVMBasicBlockRef lower_ok_block = upper_value ?
......@@ -425,12 +422,11 @@ static LLVMValueRef gen_err_name(CodeGen *g, AstNode *node) {
425422
426423 AstNode *err_val_node = node->data.fn_call_expr.params.at(0);
427424 LLVMValueRef err_val = gen_expr(g, err_val_node);
428 set_debug_source_node(g, node);
429425
430426 if (want_debug_safety(g, node)) {
431427 LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(err_val));
432428 LLVMValueRef end_val = LLVMConstInt(LLVMTypeOf(err_val), g->error_decls.length, false);
433 add_bounds_check(g, node, err_val, LLVMIntNE, zero, LLVMIntULT, end_val);
429 add_bounds_check(g, err_val, LLVMIntNE, zero, LLVMIntULT, end_val);
434430 }
435431
436432 LLVMValueRef indices[] = {
......@@ -514,15 +510,12 @@ static LLVMValueRef gen_truncate(CodeGen *g, AstNode *node) {
514510
515511 LLVMValueRef src_val = gen_expr(g, src_node);
516512
517 set_debug_source_node(g, node);
518513 return LLVMBuildTrunc(g->builder, src_val, dest_type->type_ref, "");
519514}
520515
521516static LLVMValueRef gen_unreachable(CodeGen *g, AstNode *node) {
522517 assert(node->type == NodeTypeFnCallExpr);
523518
524 set_debug_source_node(g, node);
525
526519 if (want_debug_safety(g, node) || g->is_test_build) {
527520 gen_debug_safety_crash(g);
528521 } else {
......@@ -545,7 +538,6 @@ static LLVMValueRef gen_shl_with_overflow(CodeGen *g, AstNode *node) {
545538 LLVMValueRef val2 = gen_expr(g, node->data.fn_call_expr.params.at(2));
546539 LLVMValueRef ptr_result = gen_expr(g, node->data.fn_call_expr.params.at(3));
547540
548 set_debug_source_node(g, node);
549541 LLVMValueRef result = LLVMBuildShl(g->builder, val1, val2, "");
550542 LLVMValueRef orig_val;
551543 if (int_type->data.integral.is_signed) {
......@@ -590,7 +582,6 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {
590582 operand,
591583 LLVMConstNull(LLVMInt1Type()),
592584 };
593 set_debug_source_node(g, node);
594585 return LLVMBuildCall(g->builder, fn_val, params, 2, "");
595586 }
596587 case BuiltinFnIdAddWithOverflow:
......@@ -622,7 +613,6 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {
622613 op2,
623614 };
624615
625 set_debug_source_node(g, node);
626616 LLVMValueRef result_struct = LLVMBuildCall(g->builder, fn_val, params, 2, "");
627617 LLVMValueRef result = LLVMBuildExtractValue(g->builder, result_struct, 0, "");
628618 LLVMValueRef overflow_bit = LLVMBuildExtractValue(g->builder, result_struct, 1, "");
......@@ -646,7 +636,6 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {
646636
647637 LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);
648638
649 set_debug_source_node(g, node);
650639 LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, dest_ptr, ptr_u8, "");
651640 LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, src_ptr, ptr_u8, "");
652641
......@@ -677,7 +666,6 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {
677666
678667 LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);
679668
680 set_debug_source_node(g, node);
681669 LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, dest_ptr, ptr_u8, "");
682670
683671 uint64_t align_in_bytes = get_memcpy_align(g, dest_type->data.pointer.child_type);
......@@ -707,13 +695,11 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {
707695 case BuiltinFnIdErrName:
708696 return gen_err_name(g, node);
709697 case BuiltinFnIdBreakpoint:
710 set_debug_source_node(g, node);
711698 return LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, "");
712699 case BuiltinFnIdFrameAddress:
713700 case BuiltinFnIdReturnAddress:
714701 {
715702 LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_i32->type_ref);
716 set_debug_source_node(g, node);
717703 return LLVMBuildCall(g->builder, builtin_fn->fn_val, &zero, 1, "");
718704 }
719705 case BuiltinFnIdCmpExchange:
......@@ -760,7 +746,6 @@ static LLVMValueRef gen_enum_value_expr(CodeGen *g, AstNode *node, TypeTableEntr
760746 LLVMValueRef tmp_struct_ptr = node->data.field_access_expr.resolved_struct_val_expr.ptr;
761747
762748 // populate the new tag value
763 set_debug_source_node(g, node);
764749 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, 0, "");
765750 LLVMBuildStore(g->builder, tag_value, tag_field_ptr);
766751
......@@ -804,7 +789,6 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, AstNode *source_node, TypeT
804789 !wanted_type->data.integral.is_signed && actual_type->data.integral.is_signed &&
805790 want_debug_safety(g, source_node))
806791 {
807 set_debug_source_node(g, source_node);
808792 LLVMValueRef zero = LLVMConstNull(actual_type->type_ref);
809793 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntSGE, expr_val, zero, "");
810794
......@@ -822,14 +806,11 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, AstNode *source_node, TypeT
822806 return expr_val;
823807 } else if (actual_bits < wanted_bits) {
824808 if (actual_type->id == TypeTableEntryIdFloat) {
825 set_debug_source_node(g, source_node);
826809 return LLVMBuildFPExt(g->builder, expr_val, wanted_type->type_ref, "");
827810 } else if (actual_type->id == TypeTableEntryIdInt) {
828811 if (actual_type->data.integral.is_signed) {
829 set_debug_source_node(g, source_node);
830812 return LLVMBuildSExt(g->builder, expr_val, wanted_type->type_ref, "");
831813 } else {
832 set_debug_source_node(g, source_node);
833814 return LLVMBuildZExt(g->builder, expr_val, wanted_type->type_ref, "");
834815 }
835816 } else {
......@@ -837,10 +818,8 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, AstNode *source_node, TypeT
837818 }
838819 } else if (actual_bits > wanted_bits) {
839820 if (actual_type->id == TypeTableEntryIdFloat) {
840 set_debug_source_node(g, source_node);
841821 return LLVMBuildFPTrunc(g->builder, expr_val, wanted_type->type_ref, "");
842822 } else if (actual_type->id == TypeTableEntryIdInt) {
843 set_debug_source_node(g, source_node);
844823 LLVMValueRef trunc_val = LLVMBuildTrunc(g->builder, expr_val, wanted_type->type_ref, "");
845824 if (!want_debug_safety(g, source_node)) {
846825 return trunc_val;
......@@ -869,256 +848,11 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, AstNode *source_node, TypeT
869848 }
870849}
871850
872static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {
873 assert(node->type == NodeTypeFnCallExpr);
874
875 AstNode *expr_node = node->data.fn_call_expr.params.at(0);
876
877 LLVMValueRef expr_val = gen_expr(g, expr_node);
878
879 TypeTableEntry *actual_type = get_expr_type(expr_node);
880 TypeTableEntry *wanted_type = get_expr_type(node);
881
882 AstNodeFnCallExpr *cast_expr = &node->data.fn_call_expr;
883
884 switch (cast_expr->cast_op) {
885 case CastOpNoCast:
886 zig_unreachable();
887 case CastOpNoop:
888 return expr_val;
889 case CastOpErrToInt:
890 assert(actual_type->id == TypeTableEntryIdErrorUnion);
891 if (!type_has_bits(actual_type->data.error.child_type)) {
892 return gen_widen_or_shorten(g, node, g->err_tag_type, wanted_type, expr_val);
893 } else {
894 zig_panic("TODO");
895 }
896 case CastOpMaybeWrap:
897 {
898 assert(cast_expr->tmp_ptr);
899 assert(wanted_type->id == TypeTableEntryIdMaybe);
900 assert(actual_type);
901
902 TypeTableEntry *child_type = wanted_type->data.maybe.child_type;
903
904 if (child_type->id == TypeTableEntryIdPointer ||
905 child_type->id == TypeTableEntryIdFn)
906 {
907 return expr_val;
908 } else {
909 set_debug_source_node(g, node);
910 LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, cast_expr->tmp_ptr, 0, "");
911 gen_assign_raw(g, node, BinOpTypeAssign,
912 val_ptr, expr_val, child_type, actual_type);
913
914 set_debug_source_node(g, node);
915 LLVMValueRef maybe_ptr = LLVMBuildStructGEP(g->builder, cast_expr->tmp_ptr, 1, "");
916 LLVMBuildStore(g->builder, LLVMConstAllOnes(LLVMInt1Type()), maybe_ptr);
917 }
918
919 return cast_expr->tmp_ptr;
920 }
921 case CastOpNullToMaybe:
922 // handled by constant expression evaluator
923 zig_unreachable();
924 case CastOpErrorWrap:
925 {
926 assert(wanted_type->id == TypeTableEntryIdErrorUnion);
927 TypeTableEntry *child_type = wanted_type->data.error.child_type;
928 LLVMValueRef ok_err_val = LLVMConstNull(g->err_tag_type->type_ref);
929
930 if (!type_has_bits(child_type)) {
931 return ok_err_val;
932 } else {
933 assert(cast_expr->tmp_ptr);
934 assert(wanted_type->id == TypeTableEntryIdErrorUnion);
935 assert(actual_type);
936
937 set_debug_source_node(g, node);
938 LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, cast_expr->tmp_ptr, 0, "");
939 LLVMBuildStore(g->builder, ok_err_val, err_tag_ptr);
940
941 LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, cast_expr->tmp_ptr, 1, "");
942 gen_assign_raw(g, node, BinOpTypeAssign,
943 payload_ptr, expr_val, child_type, actual_type);
944
945 return cast_expr->tmp_ptr;
946 }
947 }
948 case CastOpPureErrorWrap:
949 assert(wanted_type->id == TypeTableEntryIdErrorUnion);
950
951 if (!type_has_bits(wanted_type->data.error.child_type)) {
952 return expr_val;
953 } else {
954 zig_panic("TODO");
955 }
956 case CastOpPtrToInt:
957 set_debug_source_node(g, node);
958 return LLVMBuildPtrToInt(g->builder, expr_val, wanted_type->type_ref, "");
959 case CastOpIntToPtr:
960 set_debug_source_node(g, node);
961 return LLVMBuildIntToPtr(g->builder, expr_val, wanted_type->type_ref, "");
962 case CastOpPointerReinterpret:
963 set_debug_source_node(g, node);
964 return LLVMBuildBitCast(g->builder, expr_val, wanted_type->type_ref, "");
965 case CastOpWidenOrShorten:
966 return gen_widen_or_shorten(g, node, actual_type, wanted_type, expr_val);
967 case CastOpToUnknownSizeArray:
968 {
969 assert(cast_expr->tmp_ptr);
970 assert(wanted_type->id == TypeTableEntryIdStruct);
971 assert(wanted_type->data.structure.is_slice);
972
973 TypeTableEntry *pointer_type = wanted_type->data.structure.fields[0].type_entry;
974
975 set_debug_source_node(g, node);
976
977 size_t ptr_index = wanted_type->data.structure.fields[0].gen_index;
978 if (ptr_index != SIZE_MAX) {
979 LLVMValueRef ptr_ptr = LLVMBuildStructGEP(g->builder, cast_expr->tmp_ptr, ptr_index, "");
980 LLVMValueRef expr_bitcast = LLVMBuildBitCast(g->builder, expr_val, pointer_type->type_ref, "");
981 LLVMBuildStore(g->builder, expr_bitcast, ptr_ptr);
982 }
983
984 size_t len_index = wanted_type->data.structure.fields[1].gen_index;
985 LLVMValueRef len_ptr = LLVMBuildStructGEP(g->builder, cast_expr->tmp_ptr, len_index, "");
986 LLVMValueRef len_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref,
987 actual_type->data.array.len, false);
988 LLVMBuildStore(g->builder, len_val, len_ptr);
989
990 return cast_expr->tmp_ptr;
991 }
992 case CastOpResizeSlice:
993 {
994 assert(cast_expr->tmp_ptr);
995 assert(wanted_type->id == TypeTableEntryIdStruct);
996 assert(wanted_type->data.structure.is_slice);
997 assert(actual_type->id == TypeTableEntryIdStruct);
998 assert(actual_type->data.structure.is_slice);
999
1000 TypeTableEntry *actual_pointer_type = actual_type->data.structure.fields[0].type_entry;
1001 TypeTableEntry *actual_child_type = actual_pointer_type->data.pointer.child_type;
1002 TypeTableEntry *wanted_pointer_type = wanted_type->data.structure.fields[0].type_entry;
1003 TypeTableEntry *wanted_child_type = wanted_pointer_type->data.pointer.child_type;
1004
1005 set_debug_source_node(g, node);
1006
1007 size_t actual_ptr_index = actual_type->data.structure.fields[0].gen_index;
1008 size_t actual_len_index = actual_type->data.structure.fields[1].gen_index;
1009 size_t wanted_ptr_index = wanted_type->data.structure.fields[0].gen_index;
1010 size_t wanted_len_index = wanted_type->data.structure.fields[1].gen_index;
1011
1012 LLVMValueRef src_ptr_ptr = LLVMBuildStructGEP(g->builder, expr_val, actual_ptr_index, "");
1013 LLVMValueRef src_ptr = LLVMBuildLoad(g->builder, src_ptr_ptr, "");
1014 LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, src_ptr,
1015 wanted_type->data.structure.fields[0].type_entry->type_ref, "");
1016 LLVMValueRef dest_ptr_ptr = LLVMBuildStructGEP(g->builder, cast_expr->tmp_ptr,
1017 wanted_ptr_index, "");
1018 LLVMBuildStore(g->builder, src_ptr_casted, dest_ptr_ptr);
1019
1020 LLVMValueRef src_len_ptr = LLVMBuildStructGEP(g->builder, expr_val, actual_len_index, "");
1021 LLVMValueRef src_len = LLVMBuildLoad(g->builder, src_len_ptr, "");
1022 uint64_t src_size = type_size(g, actual_child_type);
1023 uint64_t dest_size = type_size(g, wanted_child_type);
1024
1025 LLVMValueRef new_len;
1026 if (dest_size == 1) {
1027 LLVMValueRef src_size_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref, src_size, false);
1028 new_len = LLVMBuildMul(g->builder, src_len, src_size_val, "");
1029 } else if (src_size == 1) {
1030 LLVMValueRef dest_size_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref, dest_size, false);
1031 if (want_debug_safety(g, node)) {
1032 LLVMValueRef remainder_val = LLVMBuildURem(g->builder, src_len, dest_size_val, "");
1033 LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_usize->type_ref);
1034 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, remainder_val, zero, "");
1035 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "SliceWidenOk");
1036 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "SliceWidenFail");
1037 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
1038
1039 LLVMPositionBuilderAtEnd(g->builder, fail_block);
1040 gen_debug_safety_crash(g);
1041
1042 LLVMPositionBuilderAtEnd(g->builder, ok_block);
1043 }
1044 new_len = ZigLLVMBuildExactUDiv(g->builder, src_len, dest_size_val, "");
1045 } else {
1046 zig_unreachable();
1047 }
1048
1049 LLVMValueRef dest_len_ptr = LLVMBuildStructGEP(g->builder, cast_expr->tmp_ptr,
1050 wanted_len_index, "");
1051 LLVMBuildStore(g->builder, new_len, dest_len_ptr);
1052
1053
1054 return cast_expr->tmp_ptr;
1055 }
1056 case CastOpBytesToSlice:
1057 {
1058 assert(cast_expr->tmp_ptr);
1059 assert(wanted_type->id == TypeTableEntryIdStruct);
1060 assert(wanted_type->data.structure.is_slice);
1061 assert(actual_type->id == TypeTableEntryIdArray);
1062
1063 TypeTableEntry *wanted_pointer_type = wanted_type->data.structure.fields[0].type_entry;
1064 TypeTableEntry *wanted_child_type = wanted_pointer_type->data.pointer.child_type;
1065
1066 set_debug_source_node(g, node);
1067
1068 size_t wanted_ptr_index = wanted_type->data.structure.fields[0].gen_index;
1069 LLVMValueRef dest_ptr_ptr = LLVMBuildStructGEP(g->builder, cast_expr->tmp_ptr, wanted_ptr_index, "");
1070 LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, expr_val, wanted_pointer_type->type_ref, "");
1071 LLVMBuildStore(g->builder, src_ptr_casted, dest_ptr_ptr);
1072
1073 size_t wanted_len_index = wanted_type->data.structure.fields[1].gen_index;
1074 LLVMValueRef len_ptr = LLVMBuildStructGEP(g->builder, cast_expr->tmp_ptr, wanted_len_index, "");
1075 LLVMValueRef len_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref,
1076 actual_type->data.array.len / type_size(g, wanted_child_type), false);
1077 LLVMBuildStore(g->builder, len_val, len_ptr);
1078
1079 return cast_expr->tmp_ptr;
1080 }
1081 case CastOpIntToFloat:
1082 assert(actual_type->id == TypeTableEntryIdInt);
1083 if (actual_type->data.integral.is_signed) {
1084 set_debug_source_node(g, node);
1085 return LLVMBuildSIToFP(g->builder, expr_val, wanted_type->type_ref, "");
1086 } else {
1087 set_debug_source_node(g, node);
1088 return LLVMBuildUIToFP(g->builder, expr_val, wanted_type->type_ref, "");
1089 }
1090 case CastOpFloatToInt:
1091 assert(wanted_type->id == TypeTableEntryIdInt);
1092 if (wanted_type->data.integral.is_signed) {
1093 set_debug_source_node(g, node);
1094 return LLVMBuildFPToSI(g->builder, expr_val, wanted_type->type_ref, "");
1095 } else {
1096 set_debug_source_node(g, node);
1097 return LLVMBuildFPToUI(g->builder, expr_val, wanted_type->type_ref, "");
1098 }
1099
1100 case CastOpBoolToInt:
1101 assert(wanted_type->id == TypeTableEntryIdInt);
1102 assert(actual_type->id == TypeTableEntryIdBool);
1103 set_debug_source_node(g, node);
1104 return LLVMBuildZExt(g->builder, expr_val, wanted_type->type_ref, "");
1105
1106 case CastOpIntToEnum:
1107 return gen_widen_or_shorten(g, node, actual_type, wanted_type->data.enumeration.tag_type, expr_val);
1108 case CastOpEnumToInt:
1109 return gen_widen_or_shorten(g, node, actual_type->data.enumeration.tag_type, wanted_type, expr_val);
1110 }
1111 zig_unreachable();
1112}
1113
1114
1115851static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) {
1116852 assert(node->type == NodeTypeFnCallExpr);
1117853
1118854 if (node->data.fn_call_expr.is_builtin) {
1119855 return gen_builtin_fn_call_expr(g, node);
1120 } else if (node->data.fn_call_expr.cast_op != CastOpNoCast) {
1121 return gen_cast_expr(g, node);
1122856 }
1123857
1124858 FnTableEntry *fn_table_entry = node->data.fn_call_expr.fn_entry;
......@@ -1186,7 +920,6 @@ static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) {
1186920 }
1187921 }
1188922
1189 set_debug_source_node(g, node);
1190923 LLVMValueRef result = ZigLLVMBuildCall(g->builder, fn_val,
1191924 gen_param_values, gen_param_index, fn_type->data.fn.calling_convention, "");
1192925
......@@ -1209,7 +942,6 @@ static LLVMValueRef gen_array_base_ptr(CodeGen *g, AstNode *node) {
1209942 array_ptr = gen_field_access_expr(g, node, true);
1210943 if (type_entry->id == TypeTableEntryIdPointer) {
1211944 // we have a double pointer so we must dereference it once
1212 set_debug_source_node(g, node);
1213945 array_ptr = LLVMBuildLoad(g->builder, array_ptr, "");
1214946 }
1215947 } else {
......@@ -1234,20 +966,18 @@ static LLVMValueRef gen_array_elem_ptr(CodeGen *g, AstNode *source_node, LLVMVal
1234966 if (want_debug_safety(g, source_node)) {
1235967 LLVMValueRef end = LLVMConstInt(g->builtin_types.entry_usize->type_ref,
1236968 array_type->data.array.len, false);
1237 add_bounds_check(g, source_node, subscript_value, LLVMIntEQ, nullptr, LLVMIntULT, end);
969 add_bounds_check(g, subscript_value, LLVMIntEQ, nullptr, LLVMIntULT, end);
1238970 }
1239971 LLVMValueRef indices[] = {
1240972 LLVMConstNull(g->builtin_types.entry_usize->type_ref),
1241973 subscript_value
1242974 };
1243 set_debug_source_node(g, source_node);
1244975 return LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 2, "");
1245976 } else if (array_type->id == TypeTableEntryIdPointer) {
1246977 assert(LLVMGetTypeKind(LLVMTypeOf(array_ptr)) == LLVMPointerTypeKind);
1247978 LLVMValueRef indices[] = {
1248979 subscript_value
1249980 };
1250 set_debug_source_node(g, source_node);
1251981 return LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 1, "");
1252982 } else if (array_type->id == TypeTableEntryIdStruct) {
1253983 assert(array_type->data.structure.is_slice);
......@@ -1255,15 +985,13 @@ static LLVMValueRef gen_array_elem_ptr(CodeGen *g, AstNode *source_node, LLVMVal
1255985 assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(array_ptr))) == LLVMStructTypeKind);
1256986
1257987 if (want_debug_safety(g, source_node)) {
1258 set_debug_source_node(g, source_node);
1259988 size_t len_index = array_type->data.structure.fields[1].gen_index;
1260989 assert(len_index != SIZE_MAX);
1261990 LLVMValueRef len_ptr = LLVMBuildStructGEP(g->builder, array_ptr, len_index, "");
1262991 LLVMValueRef len = LLVMBuildLoad(g->builder, len_ptr, "");
1263 add_bounds_check(g, source_node, subscript_value, LLVMIntEQ, nullptr, LLVMIntULT, len);
992 add_bounds_check(g, subscript_value, LLVMIntEQ, nullptr, LLVMIntULT, len);
1264993 }
1265994
1266 set_debug_source_node(g, source_node);
1267995 size_t ptr_index = array_type->data.structure.fields[0].gen_index;
1268996 assert(ptr_index != SIZE_MAX);
1269997 LLVMValueRef ptr_ptr = LLVMBuildStructGEP(g->builder, array_ptr, ptr_index, "");
......@@ -1302,7 +1030,6 @@ static LLVMValueRef gen_field_ptr(CodeGen *g, AstNode *node, TypeTableEntry **ou
13021030 assert(var);
13031031
13041032 if (var->type->id == TypeTableEntryIdPointer) {
1305 set_debug_source_node(g, node);
13061033 struct_ptr = LLVMBuildLoad(g->builder, var->value_ref, "");
13071034 } else {
13081035 struct_ptr = var->value_ref;
......@@ -1312,7 +1039,6 @@ static LLVMValueRef gen_field_ptr(CodeGen *g, AstNode *node, TypeTableEntry **ou
13121039 TypeTableEntry *field_type = get_expr_type(struct_expr_node);
13131040 if (field_type->id == TypeTableEntryIdPointer) {
13141041 // we have a double pointer so we must dereference it once
1315 set_debug_source_node(g, node);
13161042 struct_ptr = LLVMBuildLoad(g->builder, struct_ptr, "");
13171043 }
13181044 } else {
......@@ -1325,7 +1051,6 @@ static LLVMValueRef gen_field_ptr(CodeGen *g, AstNode *node, TypeTableEntry **ou
13251051 size_t gen_field_index = node->data.field_access_expr.type_struct_field->gen_index;
13261052 assert(gen_field_index != SIZE_MAX);
13271053
1328 set_debug_source_node(g, node);
13291054 return LLVMBuildStructGEP(g->builder, struct_ptr, gen_field_index, "");
13301055}
13311056
......@@ -1348,15 +1073,14 @@ static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) {
13481073 }
13491074
13501075 if (want_debug_safety(g, node)) {
1351 add_bounds_check(g, node, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);
1076 add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);
13521077 if (node->data.slice_expr.end) {
13531078 LLVMValueRef array_end = LLVMConstInt(g->builtin_types.entry_usize->type_ref,
13541079 array_type->data.array.len, false);
1355 add_bounds_check(g, node, end_val, LLVMIntEQ, nullptr, LLVMIntULE, array_end);
1080 add_bounds_check(g, end_val, LLVMIntEQ, nullptr, LLVMIntULE, array_end);
13561081 }
13571082 }
13581083
1359 set_debug_source_node(g, node);
13601084 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, 0, "");
13611085 LLVMValueRef indices[] = {
13621086 LLVMConstNull(g->builtin_types.entry_usize->type_ref),
......@@ -1375,10 +1099,9 @@ static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) {
13751099 LLVMValueRef end_val = gen_expr(g, node->data.slice_expr.end);
13761100
13771101 if (want_debug_safety(g, node)) {
1378 add_bounds_check(g, node, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);
1102 add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);
13791103 }
13801104
1381 set_debug_source_node(g, node);
13821105 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, 0, "");
13831106 LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, &start_val, 1, "");
13841107 LLVMBuildStore(g->builder, slice_start_ptr, ptr_field_ptr);
......@@ -1400,7 +1123,6 @@ static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) {
14001123
14011124 LLVMValueRef prev_end = nullptr;
14021125 if (!node->data.slice_expr.end || want_debug_safety(g, node)) {
1403 set_debug_source_node(g, node);
14041126 LLVMValueRef src_len_ptr = LLVMBuildStructGEP(g->builder, array_ptr, len_index, "");
14051127 prev_end = LLVMBuildLoad(g->builder, src_len_ptr, "");
14061128 }
......@@ -1415,13 +1137,12 @@ static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) {
14151137
14161138 if (want_debug_safety(g, node)) {
14171139 assert(prev_end);
1418 add_bounds_check(g, node, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);
1140 add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);
14191141 if (node->data.slice_expr.end) {
1420 add_bounds_check(g, node, end_val, LLVMIntEQ, nullptr, LLVMIntULE, prev_end);
1142 add_bounds_check(g, end_val, LLVMIntEQ, nullptr, LLVMIntULE, prev_end);
14211143 }
14221144 }
14231145
1424 set_debug_source_node(g, node);
14251146 LLVMValueRef src_ptr_ptr = LLVMBuildStructGEP(g->builder, array_ptr, ptr_index, "");
14261147 LLVMValueRef src_ptr = LLVMBuildLoad(g->builder, src_ptr_ptr, "");
14271148 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, ptr_index, "");
......@@ -1461,7 +1182,6 @@ static LLVMValueRef gen_array_access_expr(CodeGen *g, AstNode *node, bool is_lva
14611182 if (is_lvalue || !ptr || handle_is_ptr(child_type)) {
14621183 return ptr;
14631184 } else {
1464 set_debug_source_node(g, node);
14651185 return LLVMBuildLoad(g->builder, ptr, "");
14661186 }
14671187}
......@@ -1471,7 +1191,7 @@ static LLVMValueRef gen_variable(CodeGen *g, AstNode *source_node, VariableTable
14711191 return nullptr;
14721192 } else {
14731193 assert(variable->value_ref);
1474 return get_handle_value(g, source_node, variable->value_ref, variable->type);
1194 return get_handle_value(g, variable->value_ref, variable->type);
14751195 }
14761196}
14771197
......@@ -1494,7 +1214,6 @@ static LLVMValueRef gen_field_access_expr(CodeGen *g, AstNode *node, bool is_lva
14941214 if (is_lvalue || handle_is_ptr(type_entry)) {
14951215 return ptr;
14961216 } else {
1497 set_debug_source_node(g, node);
14981217 return LLVMBuildLoad(g->builder, ptr, "");
14991218 }
15001219 } else if (struct_type->id == TypeTableEntryIdMetaType) {
......@@ -1631,7 +1350,6 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {
16311350 case PrefixOpNegationWrap:
16321351 {
16331352 LLVMValueRef expr = gen_expr(g, expr_node);
1634 set_debug_source_node(g, node);
16351353 if (expr_type->id == TypeTableEntryIdFloat) {
16361354 return LLVMBuildFNeg(g->builder, expr, "");
16371355 } else if (expr_type->id == TypeTableEntryIdInt) {
......@@ -1653,13 +1371,11 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {
16531371 {
16541372 LLVMValueRef expr = gen_expr(g, expr_node);
16551373 LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(expr));
1656 set_debug_source_node(g, node);
16571374 return LLVMBuildICmp(g->builder, LLVMIntEQ, expr, zero, "");
16581375 }
16591376 case PrefixOpBinNot:
16601377 {
16611378 LLVMValueRef expr = gen_expr(g, expr_node);
1662 set_debug_source_node(g, node);
16631379 return LLVMBuildNot(g->builder, expr, "");
16641380 }
16651381 case PrefixOpAddressOf:
......@@ -1677,7 +1393,7 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {
16771393 return nullptr;
16781394 } else {
16791395 TypeTableEntry *child_type = expr_type->data.pointer.child_type;
1680 return get_handle_value(g, node, expr, child_type);
1396 return get_handle_value(g, expr, child_type);
16811397 }
16821398 }
16831399 case PrefixOpMaybe:
......@@ -1698,13 +1414,11 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {
16981414 if (want_debug_safety(g, node)) {
16991415 LLVMValueRef err_val;
17001416 if (type_has_bits(child_type)) {
1701 set_debug_source_node(g, node);
17021417 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 0, "");
17031418 err_val = LLVMBuildLoad(g->builder, err_val_ptr, "");
17041419 } else {
17051420 err_val = expr_val;
17061421 }
1707 set_debug_source_node(g, node);
17081422 LLVMValueRef zero = LLVMConstNull(g->err_tag_type->type_ref);
17091423 LLVMValueRef cond_val = LLVMBuildICmp(g->builder, LLVMIntEQ, err_val, zero, "");
17101424 LLVMBasicBlockRef err_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "UnwrapErrError");
......@@ -1719,7 +1433,7 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {
17191433
17201434 if (type_has_bits(child_type)) {
17211435 LLVMValueRef child_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 1, "");
1722 return get_handle_value(g, expr_node, child_val_ptr, child_type);
1436 return get_handle_value(g, child_val_ptr, child_type);
17231437 } else {
17241438 return nullptr;
17251439 }
......@@ -1733,7 +1447,6 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {
17331447 TypeTableEntry *child_type = expr_type->data.maybe.child_type;
17341448
17351449 if (want_debug_safety(g, node)) {
1736 set_debug_source_node(g, node);
17371450 LLVMValueRef cond_val;
17381451 if (child_type->id == TypeTableEntryIdPointer ||
17391452 child_type->id == TypeTableEntryIdFn)
......@@ -1761,9 +1474,8 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {
17611474 {
17621475 return expr_val;
17631476 } else {
1764 set_debug_source_node(g, node);
17651477 LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP(g->builder, expr_val, 0, "");
1766 return get_handle_value(g, node, maybe_field_ptr, child_type);
1478 return get_handle_value(g, maybe_field_ptr, child_type);
17671479 }
17681480 }
17691481 }
......@@ -1773,7 +1485,6 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {
17731485static LLVMValueRef gen_div(CodeGen *g, AstNode *source_node, LLVMValueRef val1, LLVMValueRef val2,
17741486 TypeTableEntry *type_entry, bool exact)
17751487{
1776 set_debug_source_node(g, source_node);
17771488
17781489 if (want_debug_safety(g, source_node)) {
17791490 LLVMValueRef zero = LLVMConstNull(type_entry->type_ref);
......@@ -1846,22 +1557,18 @@ static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node,
18461557 switch (bin_op) {
18471558 case BinOpTypeBinOr:
18481559 case BinOpTypeAssignBitOr:
1849 set_debug_source_node(g, source_node);
18501560 return LLVMBuildOr(g->builder, val1, val2, "");
18511561 case BinOpTypeBinXor:
18521562 case BinOpTypeAssignBitXor:
1853 set_debug_source_node(g, source_node);
18541563 return LLVMBuildXor(g->builder, val1, val2, "");
18551564 case BinOpTypeBinAnd:
18561565 case BinOpTypeAssignBitAnd:
1857 set_debug_source_node(g, source_node);
18581566 return LLVMBuildAnd(g->builder, val1, val2, "");
18591567 case BinOpTypeBitShiftLeft:
18601568 case BinOpTypeBitShiftLeftWrap:
18611569 case BinOpTypeAssignBitShiftLeft:
18621570 case BinOpTypeAssignBitShiftLeftWrap:
18631571 {
1864 set_debug_source_node(g, source_node);
18651572 assert(op1_type->id == TypeTableEntryIdInt);
18661573 bool is_wrapping = (bin_op == BinOpTypeBitShiftLeftWrap) ||
18671574 (bin_op == BinOpTypeAssignBitShiftLeftWrap);
......@@ -1880,7 +1587,6 @@ static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node,
18801587 assert(op1_type->id == TypeTableEntryIdInt);
18811588 assert(op2_type->id == TypeTableEntryIdInt);
18821589
1883 set_debug_source_node(g, source_node);
18841590 if (op1_type->data.integral.is_signed) {
18851591 return LLVMBuildAShr(g->builder, val1, val2, "");
18861592 } else {
......@@ -1890,7 +1596,6 @@ static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node,
18901596 case BinOpTypeAddWrap:
18911597 case BinOpTypeAssignPlus:
18921598 case BinOpTypeAssignPlusWrap:
1893 set_debug_source_node(g, source_node);
18941599 if (op1_type->id == TypeTableEntryIdFloat) {
18951600 return LLVMBuildFAdd(g->builder, val1, val2, "");
18961601 } else if (op1_type->id == TypeTableEntryIdInt) {
......@@ -1911,7 +1616,6 @@ static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node,
19111616 case BinOpTypeSubWrap:
19121617 case BinOpTypeAssignMinus:
19131618 case BinOpTypeAssignMinusWrap:
1914 set_debug_source_node(g, source_node);
19151619 if (op1_type->id == TypeTableEntryIdFloat) {
19161620 return LLVMBuildFSub(g->builder, val1, val2, "");
19171621 } else if (op1_type->id == TypeTableEntryIdInt) {
......@@ -1932,7 +1636,6 @@ static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node,
19321636 case BinOpTypeMultWrap:
19331637 case BinOpTypeAssignTimes:
19341638 case BinOpTypeAssignTimesWrap:
1935 set_debug_source_node(g, source_node);
19361639 if (op1_type->id == TypeTableEntryIdFloat) {
19371640 return LLVMBuildFMul(g->builder, val1, val2, "");
19381641 } else if (op1_type->id == TypeTableEntryIdInt) {
......@@ -1954,7 +1657,6 @@ static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node,
19541657 return gen_div(g, source_node, val1, val2, op1_type, false);
19551658 case BinOpTypeMod:
19561659 case BinOpTypeAssignMod:
1957 set_debug_source_node(g, source_node);
19581660 if (op1_type->id == TypeTableEntryIdFloat) {
19591661 return LLVMBuildFRem(g->builder, val1, val2, "");
19601662 } else {
......@@ -2044,7 +1746,6 @@ static LLVMValueRef gen_cmp_expr(CodeGen *g, AstNode *node) {
20441746 TypeTableEntry *op2_type = get_expr_type(node->data.bin_op_expr.op2);
20451747 assert(op1_type == op2_type);
20461748
2047 set_debug_source_node(g, node);
20481749 if (op1_type->id == TypeTableEntryIdFloat) {
20491750 LLVMRealPredicate pred = cmp_op_to_real_predicate(node->data.bin_op_expr.bin_op);
20501751 return LLVMBuildFCmp(g->builder, pred, val1, val2, "");
......@@ -2081,18 +1782,15 @@ static LLVMValueRef gen_bool_and_expr(CodeGen *g, AstNode *node) {
20811782 // block for when val1 == false (don't even evaluate the second part)
20821783 LLVMBasicBlockRef false_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "BoolAndFalse");
20831784
2084 set_debug_source_node(g, node);
20851785 LLVMBuildCondBr(g->builder, val1, true_block, false_block);
20861786
20871787 LLVMPositionBuilderAtEnd(g->builder, true_block);
20881788 LLVMValueRef val2 = gen_expr(g, node->data.bin_op_expr.op2);
20891789 LLVMBasicBlockRef post_val2_block = LLVMGetInsertBlock(g->builder);
20901790
2091 set_debug_source_node(g, node);
20921791 LLVMBuildBr(g->builder, false_block);
20931792
20941793 LLVMPositionBuilderAtEnd(g->builder, false_block);
2095 set_debug_source_node(g, node);
20961794 LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMInt1Type(), "");
20971795 LLVMValueRef incoming_values[2] = {val1, val2};
20981796 LLVMBasicBlockRef incoming_blocks[2] = {post_val1_block, post_val2_block};
......@@ -2112,7 +1810,6 @@ static LLVMValueRef gen_bool_or_expr(CodeGen *g, AstNode *expr_node) {
21121810 // block for when val1 == true (don't even evaluate the second part)
21131811 LLVMBasicBlockRef true_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "BoolOrTrue");
21141812
2115 set_debug_source_node(g, expr_node);
21161813 LLVMBuildCondBr(g->builder, val1, true_block, false_block);
21171814
21181815 LLVMPositionBuilderAtEnd(g->builder, false_block);
......@@ -2120,11 +1817,9 @@ static LLVMValueRef gen_bool_or_expr(CodeGen *g, AstNode *expr_node) {
21201817
21211818 LLVMBasicBlockRef post_val2_block = LLVMGetInsertBlock(g->builder);
21221819
2123 set_debug_source_node(g, expr_node);
21241820 LLVMBuildBr(g->builder, true_block);
21251821
21261822 LLVMPositionBuilderAtEnd(g->builder, true_block);
2127 set_debug_source_node(g, expr_node);
21281823 LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMInt1Type(), "");
21291824 LLVMValueRef incoming_values[2] = {val1, val2};
21301825 LLVMBasicBlockRef incoming_blocks[2] = {post_val1_block, post_val2_block};
......@@ -2133,14 +1828,13 @@ static LLVMValueRef gen_bool_or_expr(CodeGen *g, AstNode *expr_node) {
21331828 return phi;
21341829}
21351830
2136static LLVMValueRef gen_struct_memcpy(CodeGen *g, AstNode *source_node, LLVMValueRef src, LLVMValueRef dest,
1831static LLVMValueRef gen_struct_memcpy(CodeGen *g, LLVMValueRef src, LLVMValueRef dest,
21371832 TypeTableEntry *type_entry)
21381833{
21391834 assert(handle_is_ptr(type_entry));
21401835
21411836 LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);
21421837
2143 set_debug_source_node(g, source_node);
21441838 LLVMValueRef src_ptr = LLVMBuildBitCast(g->builder, src, ptr_u8, "");
21451839 LLVMValueRef dest_ptr = LLVMBuildBitCast(g->builder, dest, ptr_u8, "");
21461840
......@@ -2172,18 +1866,16 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, AstNode *source_node, BinOpType b
21721866 assert(op1_type == op2_type);
21731867 assert(bin_op == BinOpTypeAssign);
21741868
2175 return gen_struct_memcpy(g, source_node, value, target_ref, op1_type);
1869 return gen_struct_memcpy(g, value, target_ref, op1_type);
21761870 }
21771871
21781872 if (bin_op != BinOpTypeAssign) {
21791873 assert(source_node->type == NodeTypeBinOpExpr);
2180 set_debug_source_node(g, source_node->data.bin_op_expr.op1);
21811874 LLVMValueRef left_value = LLVMBuildLoad(g->builder, target_ref, "");
21821875
21831876 value = gen_arithmetic_bin_op(g, source_node, left_value, value, op1_type, op2_type, bin_op);
21841877 }
21851878
2186 set_debug_source_node(g, source_node);
21871879 LLVMBuildStore(g->builder, value, target_ref);
21881880 return nullptr;
21891881}
......@@ -2214,9 +1906,8 @@ static LLVMValueRef gen_unwrap_maybe(CodeGen *g, AstNode *node, LLVMValueRef may
22141906 {
22151907 return maybe_struct_ref;
22161908 } else {
2217 set_debug_source_node(g, node);
22181909 LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP(g->builder, maybe_struct_ref, 0, "");
2219 return get_handle_value(g, node, maybe_field_ptr, child_type);
1910 return get_handle_value(g, maybe_field_ptr, child_type);
22201911 }
22211912}
22221913
......@@ -2240,7 +1931,6 @@ static LLVMValueRef gen_unwrap_maybe_expr(CodeGen *g, AstNode *node) {
22401931 cond_value = LLVMBuildICmp(g->builder, LLVMIntNE, maybe_struct_ref,
22411932 LLVMConstNull(child_type->type_ref), "");
22421933 } else {
2243 set_debug_source_node(g, node);
22441934 LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP(g->builder, maybe_struct_ref, 1, "");
22451935 cond_value = LLVMBuildLoad(g->builder, maybe_field_ptr, "");
22461936 }
......@@ -2255,21 +1945,18 @@ static LLVMValueRef gen_unwrap_maybe_expr(CodeGen *g, AstNode *node) {
22551945
22561946 LLVMPositionBuilderAtEnd(g->builder, non_null_block);
22571947 LLVMValueRef non_null_result = gen_unwrap_maybe(g, op1_node, maybe_struct_ref);
2258 set_debug_source_node(g, node);
22591948 LLVMBuildBr(g->builder, end_block);
22601949 LLVMBasicBlockRef post_non_null_result_block = LLVMGetInsertBlock(g->builder);
22611950
22621951 LLVMPositionBuilderAtEnd(g->builder, null_block);
22631952 LLVMValueRef null_result = gen_expr(g, op2_node);
22641953 if (null_reachable) {
2265 set_debug_source_node(g, node);
22661954 LLVMBuildBr(g->builder, end_block);
22671955 }
22681956 LLVMBasicBlockRef post_null_result_block = LLVMGetInsertBlock(g->builder);
22691957
22701958 LLVMPositionBuilderAtEnd(g->builder, end_block);
22711959 if (null_reachable) {
2272 set_debug_source_node(g, node);
22731960 LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMTypeOf(non_null_result), "");
22741961 LLVMValueRef incoming_values[2] = {non_null_result, null_result};
22751962 LLVMBasicBlockRef incoming_blocks[2] = {post_non_null_result_block, post_null_result_block};
......@@ -2351,7 +2038,6 @@ static LLVMValueRef gen_unwrap_err_expr(CodeGen *g, AstNode *node) {
23512038 assert(expr_type->id == TypeTableEntryIdErrorUnion);
23522039 TypeTableEntry *child_type = expr_type->data.error.child_type;
23532040 LLVMValueRef err_val;
2354 set_debug_source_node(g, node);
23552041 if (handle_is_ptr(expr_type)) {
23562042 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 0, "");
23572043 err_val = LLVMBuildLoad(g->builder, err_val_ptr, "");
......@@ -2377,7 +2063,6 @@ static LLVMValueRef gen_unwrap_err_expr(CodeGen *g, AstNode *node) {
23772063 LLVMBuildStore(g->builder, err_val, var->value_ref);
23782064 }
23792065 LLVMValueRef err_result = gen_expr(g, op2);
2380 set_debug_source_node(g, node);
23812066 if (have_end_block) {
23822067 LLVMBuildBr(g->builder, end_block);
23832068 } else if (err_reachable) {
......@@ -2389,7 +2074,7 @@ static LLVMValueRef gen_unwrap_err_expr(CodeGen *g, AstNode *node) {
23892074 return nullptr;
23902075 }
23912076 LLVMValueRef child_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 1, "");
2392 LLVMValueRef child_val = get_handle_value(g, node, child_val_ptr, child_type);
2077 LLVMValueRef child_val = get_handle_value(g, child_val_ptr, child_type);
23932078
23942079 if (!have_end_block) {
23952080 return child_val;
......@@ -2452,17 +2137,14 @@ static LLVMValueRef gen_return(CodeGen *g, AstNode *source_node, LLVMValueRef va
24522137 bool is_extern = g->cur_fn->type_entry->data.fn.fn_type_id.is_extern;
24532138 if (handle_is_ptr(return_type)) {
24542139 if (is_extern) {
2455 set_debug_source_node(g, source_node);
24562140 LLVMValueRef by_val_value = LLVMBuildLoad(g->builder, value, "");
24572141 LLVMBuildRet(g->builder, by_val_value);
24582142 } else {
24592143 assert(g->cur_ret_ptr);
24602144 gen_assign_raw(g, source_node, BinOpTypeAssign, g->cur_ret_ptr, value, return_type, return_type);
2461 set_debug_source_node(g, source_node);
24622145 LLVMBuildRetVoid(g->builder);
24632146 }
24642147 } else {
2465 set_debug_source_node(g, source_node);
24662148 LLVMBuildRet(g->builder, value);
24672149 }
24682150 return nullptr;
......@@ -2504,7 +2186,6 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) {
25042186 LLVMBasicBlockRef return_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "ErrRetReturn");
25052187 LLVMBasicBlockRef continue_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "ErrRetContinue");
25062188
2507 set_debug_source_node(g, node);
25082189 LLVMValueRef err_val;
25092190 if (type_has_bits(child_type)) {
25102191 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, value, 0, "");
......@@ -2524,7 +2205,6 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) {
25242205 if (type_has_bits(return_type->data.error.child_type)) {
25252206 assert(g->cur_ret_ptr);
25262207
2527 set_debug_source_node(g, node);
25282208 LLVMValueRef tag_ptr = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, 0, "");
25292209 LLVMBuildStore(g->builder, err_val, tag_ptr);
25302210 LLVMBuildRetVoid(g->builder);
......@@ -2537,9 +2217,8 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) {
25372217
25382218 LLVMPositionBuilderAtEnd(g->builder, continue_block);
25392219 if (type_has_bits(child_type)) {
2540 set_debug_source_node(g, node);
25412220 LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, value, 1, "");
2542 return get_handle_value(g, node, val_ptr, child_type);
2221 return get_handle_value(g, val_ptr, child_type);
25432222 } else {
25442223 return nullptr;
25452224 }
......@@ -2552,7 +2231,6 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) {
25522231 LLVMBasicBlockRef return_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "MaybeRetReturn");
25532232 LLVMBasicBlockRef continue_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "MaybeRetContinue");
25542233
2555 set_debug_source_node(g, node);
25562234 LLVMValueRef maybe_val_ptr = LLVMBuildStructGEP(g->builder, value, 1, "");
25572235 LLVMValueRef is_non_null = LLVMBuildLoad(g->builder, maybe_val_ptr, "");
25582236
......@@ -2566,7 +2244,6 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) {
25662244 if (handle_is_ptr(return_type)) {
25672245 assert(g->cur_ret_ptr);
25682246
2569 set_debug_source_node(g, node);
25702247 LLVMValueRef maybe_bit_ptr = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, 1, "");
25712248 LLVMBuildStore(g->builder, zero, maybe_bit_ptr);
25722249 LLVMBuildRetVoid(g->builder);
......@@ -2577,9 +2254,8 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) {
25772254
25782255 LLVMPositionBuilderAtEnd(g->builder, continue_block);
25792256 if (type_has_bits(child_type)) {
2580 set_debug_source_node(g, node);
25812257 LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, value, 0, "");
2582 return get_handle_value(g, node, val_ptr, child_type);
2258 return get_handle_value(g, val_ptr, child_type);
25832259 } else {
25842260 return nullptr;
25852261 }
......@@ -2610,7 +2286,6 @@ static LLVMValueRef gen_if_bool_expr_raw(CodeGen *g, AstNode *source_node, LLVMV
26102286 endif_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "EndIf");
26112287 }
26122288
2613 set_debug_source_node(g, source_node);
26142289 LLVMBuildCondBr(g->builder, cond_value, then_block, else_block);
26152290
26162291 LLVMPositionBuilderAtEnd(g->builder, then_block);
......@@ -2632,7 +2307,6 @@ static LLVMValueRef gen_if_bool_expr_raw(CodeGen *g, AstNode *source_node, LLVMV
26322307 if (then_endif_reachable || else_endif_reachable) {
26332308 LLVMPositionBuilderAtEnd(g->builder, endif_block);
26342309 if (use_then_value && use_else_value) {
2635 set_debug_source_node(g, source_node);
26362310 LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMTypeOf(then_expr_result), "");
26372311 LLVMValueRef incoming_values[2] = {then_expr_result, else_expr_result};
26382312 LLVMBasicBlockRef incoming_blocks[2] = {after_then_block, after_else_block};
......@@ -2697,7 +2371,7 @@ static LLVMValueRef gen_if_var_then_block(CodeGen *g, AstNode *node, VariableTab
26972371 payload_val = init_val;
26982372 } else {
26992373 LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, init_val, 0, "");
2700 payload_val = get_handle_value(g, node, payload_ptr, child_type);
2374 payload_val = get_handle_value(g, payload_ptr, child_type);
27012375 }
27022376 gen_assign_raw(g, node, BinOpTypeAssign, variable->value_ref, payload_val,
27032377 variable->type, child_type);
......@@ -2736,10 +2410,8 @@ static LLVMValueRef gen_if_var_expr(CodeGen *g, AstNode *node) {
27362410
27372411 LLVMValueRef cond_value;
27382412 if (maybe_is_ptr) {
2739 set_debug_source_node(g, node);
27402413 cond_value = LLVMBuildICmp(g->builder, LLVMIntNE, init_val, LLVMConstNull(child_type->type_ref), "");
27412414 } else {
2742 set_debug_source_node(g, node);
27432415 LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP(g->builder, init_val, 1, "");
27442416 cond_value = LLVMBuildLoad(g->builder, maybe_field_ptr, "");
27452417 }
......@@ -2760,7 +2432,6 @@ static LLVMValueRef gen_if_var_expr(CodeGen *g, AstNode *node) {
27602432 endif_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "MaybeEndIf");
27612433 }
27622434
2763 set_debug_source_node(g, node);
27642435 LLVMBuildCondBr(g->builder, cond_value, then_block, else_block);
27652436
27662437 LLVMPositionBuilderAtEnd(g->builder, then_block);
......@@ -2810,7 +2481,7 @@ static LLVMValueRef ir_render_load_var(CodeGen *g, IrExecutable *executable,
28102481 return nullptr;
28112482
28122483 assert(var->value_ref);
2813 return get_handle_value(g, load_var_instruction->base.source_node, var->value_ref, var->type);
2484 return get_handle_value(g, var->value_ref, var->type);
28142485}
28152486
28162487static LLVMValueRef ir_render_bin_op_bool(CodeGen *g, IrExecutable *executable,
......@@ -2894,6 +2565,233 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
28942565 zig_unreachable();
28952566}
28962567
2568static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
2569 IrInstructionCast *cast_instruction)
2570{
2571 TypeTableEntry *actual_type = cast_instruction->value->type_entry;
2572 TypeTableEntry *wanted_type = cast_instruction->base.type_entry;
2573 LLVMValueRef expr_val = cast_instruction->value->llvm_value;
2574 assert(expr_val);
2575
2576 switch (cast_instruction->cast_op) {
2577 case CastOpNoCast:
2578 zig_unreachable();
2579 case CastOpNoop:
2580 return expr_val;
2581 case CastOpErrToInt:
2582 assert(actual_type->id == TypeTableEntryIdErrorUnion);
2583 if (!type_has_bits(actual_type->data.error.child_type)) {
2584 return gen_widen_or_shorten(g, cast_instruction->base.source_node,
2585 g->err_tag_type, wanted_type, expr_val);
2586 } else {
2587 zig_panic("TODO");
2588 }
2589 case CastOpMaybeWrap:
2590 {
2591 assert(cast_instruction->tmp_ptr);
2592 assert(wanted_type->id == TypeTableEntryIdMaybe);
2593 assert(actual_type);
2594
2595 TypeTableEntry *child_type = wanted_type->data.maybe.child_type;
2596
2597 if (child_type->id == TypeTableEntryIdPointer ||
2598 child_type->id == TypeTableEntryIdFn)
2599 {
2600 return expr_val;
2601 } else {
2602 LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr, 0, "");
2603 gen_assign_raw(g, cast_instruction->base.source_node, BinOpTypeAssign,
2604 val_ptr, expr_val, child_type, actual_type);
2605
2606 LLVMValueRef maybe_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr, 1, "");
2607 LLVMBuildStore(g->builder, LLVMConstAllOnes(LLVMInt1Type()), maybe_ptr);
2608 }
2609
2610 return cast_instruction->tmp_ptr;
2611 }
2612 case CastOpNullToMaybe:
2613 // handled by constant expression evaluator
2614 zig_unreachable();
2615 case CastOpErrorWrap:
2616 {
2617 assert(wanted_type->id == TypeTableEntryIdErrorUnion);
2618 TypeTableEntry *child_type = wanted_type->data.error.child_type;
2619 LLVMValueRef ok_err_val = LLVMConstNull(g->err_tag_type->type_ref);
2620
2621 if (!type_has_bits(child_type)) {
2622 return ok_err_val;
2623 } else {
2624 assert(cast_instruction->tmp_ptr);
2625 assert(wanted_type->id == TypeTableEntryIdErrorUnion);
2626 assert(actual_type);
2627
2628 LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr, 0, "");
2629 LLVMBuildStore(g->builder, ok_err_val, err_tag_ptr);
2630
2631 LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr, 1, "");
2632 gen_assign_raw(g, cast_instruction->base.source_node, BinOpTypeAssign,
2633 payload_ptr, expr_val, child_type, actual_type);
2634
2635 return cast_instruction->tmp_ptr;
2636 }
2637 }
2638 case CastOpPureErrorWrap:
2639 assert(wanted_type->id == TypeTableEntryIdErrorUnion);
2640
2641 if (!type_has_bits(wanted_type->data.error.child_type)) {
2642 return expr_val;
2643 } else {
2644 zig_panic("TODO");
2645 }
2646 case CastOpPtrToInt:
2647 return LLVMBuildPtrToInt(g->builder, expr_val, wanted_type->type_ref, "");
2648 case CastOpIntToPtr:
2649 return LLVMBuildIntToPtr(g->builder, expr_val, wanted_type->type_ref, "");
2650 case CastOpPointerReinterpret:
2651 return LLVMBuildBitCast(g->builder, expr_val, wanted_type->type_ref, "");
2652 case CastOpWidenOrShorten:
2653 return gen_widen_or_shorten(g, cast_instruction->base.source_node, actual_type, wanted_type, expr_val);
2654 case CastOpToUnknownSizeArray:
2655 {
2656 assert(cast_instruction->tmp_ptr);
2657 assert(wanted_type->id == TypeTableEntryIdStruct);
2658 assert(wanted_type->data.structure.is_slice);
2659
2660 TypeTableEntry *pointer_type = wanted_type->data.structure.fields[0].type_entry;
2661
2662
2663 size_t ptr_index = wanted_type->data.structure.fields[0].gen_index;
2664 if (ptr_index != SIZE_MAX) {
2665 LLVMValueRef ptr_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr, ptr_index, "");
2666 LLVMValueRef expr_bitcast = LLVMBuildBitCast(g->builder, expr_val, pointer_type->type_ref, "");
2667 LLVMBuildStore(g->builder, expr_bitcast, ptr_ptr);
2668 }
2669
2670 size_t len_index = wanted_type->data.structure.fields[1].gen_index;
2671 LLVMValueRef len_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr, len_index, "");
2672 LLVMValueRef len_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref,
2673 actual_type->data.array.len, false);
2674 LLVMBuildStore(g->builder, len_val, len_ptr);
2675
2676 return cast_instruction->tmp_ptr;
2677 }
2678 case CastOpResizeSlice:
2679 {
2680 assert(cast_instruction->tmp_ptr);
2681 assert(wanted_type->id == TypeTableEntryIdStruct);
2682 assert(wanted_type->data.structure.is_slice);
2683 assert(actual_type->id == TypeTableEntryIdStruct);
2684 assert(actual_type->data.structure.is_slice);
2685
2686 TypeTableEntry *actual_pointer_type = actual_type->data.structure.fields[0].type_entry;
2687 TypeTableEntry *actual_child_type = actual_pointer_type->data.pointer.child_type;
2688 TypeTableEntry *wanted_pointer_type = wanted_type->data.structure.fields[0].type_entry;
2689 TypeTableEntry *wanted_child_type = wanted_pointer_type->data.pointer.child_type;
2690
2691
2692 size_t actual_ptr_index = actual_type->data.structure.fields[0].gen_index;
2693 size_t actual_len_index = actual_type->data.structure.fields[1].gen_index;
2694 size_t wanted_ptr_index = wanted_type->data.structure.fields[0].gen_index;
2695 size_t wanted_len_index = wanted_type->data.structure.fields[1].gen_index;
2696
2697 LLVMValueRef src_ptr_ptr = LLVMBuildStructGEP(g->builder, expr_val, actual_ptr_index, "");
2698 LLVMValueRef src_ptr = LLVMBuildLoad(g->builder, src_ptr_ptr, "");
2699 LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, src_ptr,
2700 wanted_type->data.structure.fields[0].type_entry->type_ref, "");
2701 LLVMValueRef dest_ptr_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr,
2702 wanted_ptr_index, "");
2703 LLVMBuildStore(g->builder, src_ptr_casted, dest_ptr_ptr);
2704
2705 LLVMValueRef src_len_ptr = LLVMBuildStructGEP(g->builder, expr_val, actual_len_index, "");
2706 LLVMValueRef src_len = LLVMBuildLoad(g->builder, src_len_ptr, "");
2707 uint64_t src_size = type_size(g, actual_child_type);
2708 uint64_t dest_size = type_size(g, wanted_child_type);
2709
2710 LLVMValueRef new_len;
2711 if (dest_size == 1) {
2712 LLVMValueRef src_size_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref, src_size, false);
2713 new_len = LLVMBuildMul(g->builder, src_len, src_size_val, "");
2714 } else if (src_size == 1) {
2715 LLVMValueRef dest_size_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref, dest_size, false);
2716 if (ir_want_debug_safety(g, &cast_instruction->base)) {
2717 LLVMValueRef remainder_val = LLVMBuildURem(g->builder, src_len, dest_size_val, "");
2718 LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_usize->type_ref);
2719 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, remainder_val, zero, "");
2720 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "SliceWidenOk");
2721 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "SliceWidenFail");
2722 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
2723
2724 LLVMPositionBuilderAtEnd(g->builder, fail_block);
2725 gen_debug_safety_crash(g);
2726
2727 LLVMPositionBuilderAtEnd(g->builder, ok_block);
2728 }
2729 new_len = ZigLLVMBuildExactUDiv(g->builder, src_len, dest_size_val, "");
2730 } else {
2731 zig_unreachable();
2732 }
2733
2734 LLVMValueRef dest_len_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr,
2735 wanted_len_index, "");
2736 LLVMBuildStore(g->builder, new_len, dest_len_ptr);
2737
2738
2739 return cast_instruction->tmp_ptr;
2740 }
2741 case CastOpBytesToSlice:
2742 {
2743 assert(cast_instruction->tmp_ptr);
2744 assert(wanted_type->id == TypeTableEntryIdStruct);
2745 assert(wanted_type->data.structure.is_slice);
2746 assert(actual_type->id == TypeTableEntryIdArray);
2747
2748 TypeTableEntry *wanted_pointer_type = wanted_type->data.structure.fields[0].type_entry;
2749 TypeTableEntry *wanted_child_type = wanted_pointer_type->data.pointer.child_type;
2750
2751
2752 size_t wanted_ptr_index = wanted_type->data.structure.fields[0].gen_index;
2753 LLVMValueRef dest_ptr_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr, wanted_ptr_index, "");
2754 LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, expr_val, wanted_pointer_type->type_ref, "");
2755 LLVMBuildStore(g->builder, src_ptr_casted, dest_ptr_ptr);
2756
2757 size_t wanted_len_index = wanted_type->data.structure.fields[1].gen_index;
2758 LLVMValueRef len_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr, wanted_len_index, "");
2759 LLVMValueRef len_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref,
2760 actual_type->data.array.len / type_size(g, wanted_child_type), false);
2761 LLVMBuildStore(g->builder, len_val, len_ptr);
2762
2763 return cast_instruction->tmp_ptr;
2764 }
2765 case CastOpIntToFloat:
2766 assert(actual_type->id == TypeTableEntryIdInt);
2767 if (actual_type->data.integral.is_signed) {
2768 return LLVMBuildSIToFP(g->builder, expr_val, wanted_type->type_ref, "");
2769 } else {
2770 return LLVMBuildUIToFP(g->builder, expr_val, wanted_type->type_ref, "");
2771 }
2772 case CastOpFloatToInt:
2773 assert(wanted_type->id == TypeTableEntryIdInt);
2774 if (wanted_type->data.integral.is_signed) {
2775 return LLVMBuildFPToSI(g->builder, expr_val, wanted_type->type_ref, "");
2776 } else {
2777 return LLVMBuildFPToUI(g->builder, expr_val, wanted_type->type_ref, "");
2778 }
2779
2780 case CastOpBoolToInt:
2781 assert(wanted_type->id == TypeTableEntryIdInt);
2782 assert(actual_type->id == TypeTableEntryIdBool);
2783 return LLVMBuildZExt(g->builder, expr_val, wanted_type->type_ref, "");
2784
2785 case CastOpIntToEnum:
2786 return gen_widen_or_shorten(g, cast_instruction->base.source_node,
2787 actual_type, wanted_type->data.enumeration.tag_type, expr_val);
2788 case CastOpEnumToInt:
2789 return gen_widen_or_shorten(g, cast_instruction->base.source_node,
2790 actual_type->data.enumeration.tag_type, wanted_type, expr_val);
2791 }
2792 zig_unreachable();
2793}
2794
28972795static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, IrInstruction *instruction) {
28982796 set_debug_source_node(g, instruction->source_node);
28992797 switch (instruction->id) {
......@@ -2907,13 +2805,14 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
29072805 return ir_render_load_var(g, executable, (IrInstructionLoadVar *)instruction);
29082806 case IrInstructionIdBinOp:
29092807 return ir_render_bin_op(g, executable, (IrInstructionBinOp *)instruction);
2808 case IrInstructionIdCast:
2809 return ir_render_cast(g, executable, (IrInstructionCast *)instruction);
29102810 case IrInstructionIdCondBr:
29112811 case IrInstructionIdSwitchBr:
29122812 case IrInstructionIdPhi:
29132813 case IrInstructionIdStoreVar:
29142814 case IrInstructionIdCall:
29152815 case IrInstructionIdBuiltinCall:
2916 case IrInstructionIdCast:
29172816 zig_panic("TODO render more IR instructions to LLVM");
29182817 }
29192818 zig_unreachable();
......@@ -3592,7 +3491,7 @@ static LLVMValueRef gen_switch_expr(CodeGen *g, AstNode *node) {
35923491 1, "");
35933492 LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr,
35943493 LLVMPointerType(enum_field->type_entry->type_ref, 0), "");
3595 LLVMValueRef handle_val = get_handle_value(g, var_node, bitcasted_union_field_ptr,
3494 LLVMValueRef handle_val = get_handle_value(g, bitcasted_union_field_ptr,
35963495 enum_field->type_entry);
35973496
35983497 gen_assign_raw(g, var_node, BinOpTypeAssign,
......@@ -3602,8 +3501,7 @@ static LLVMValueRef gen_switch_expr(CodeGen *g, AstNode *node) {
36023501 // variable is the payload
36033502 LLVMValueRef err_payload_ptr = LLVMBuildStructGEP(g->builder,
36043503 target_value_handle, 1, "");
3605 LLVMValueRef handle_val = get_handle_value(g, var_node,
3606 err_payload_ptr, prong_var->type);
3504 LLVMValueRef handle_val = get_handle_value(g, err_payload_ptr, prong_var->type);
36073505 gen_assign_raw(g, var_node, BinOpTypeAssign,
36083506 prong_var->value_ref, handle_val, prong_var->type, prong_var->type);
36093507 } else {
......@@ -4375,10 +4273,8 @@ static void do_code_gen(CodeGen *g) {
43754273
43764274 // allocate structs which are the result of casts
43774275 for (size_t cea_i = 0; cea_i < fn_table_entry->cast_alloca_list.length; cea_i += 1) {
4378 AstNode *fn_call_node = fn_table_entry->cast_alloca_list.at(cea_i);
4379 Expr *expr = &fn_call_node->data.fn_call_expr.resolved_expr;
4380 fn_call_node->data.fn_call_expr.tmp_ptr = LLVMBuildAlloca(g->builder,
4381 expr->type_entry->type_ref, "");
4276 IrInstructionCast *cast_instruction = fn_table_entry->cast_alloca_list.at(cea_i);
4277 cast_instruction->tmp_ptr = LLVMBuildAlloca(g->builder, cast_instruction->base.type_entry->type_ref, "");
43824278 }
43834279
43844280 // allocate structs which are struct value expressions
src/eval.cpp+1
......@@ -773,6 +773,7 @@ void eval_const_expr_implicit_cast(CastOp cast_op,
773773 case CastOpEnumToInt:
774774 bignum_init_unsigned(&const_val->data.x_bignum, other_val->data.x_enum.tag);
775775 const_val->ok = true;
776 break;
776777 }
777778}
778779
src/ir.cpp+530-15
......@@ -1,6 +1,7 @@
11#include "analyze.hpp"
2#include "ir.hpp"
32#include "error.hpp"
3#include "eval.hpp"
4#include "ir.hpp"
45
56struct IrVarSlot {
67 ConstExprValue value;
......@@ -100,12 +101,12 @@ static T *ir_build_instruction(IrBuilder *irb, AstNode *source_node) {
100101}
101102
102103static IrInstruction *ir_build_cast(IrBuilder *irb, AstNode *source_node, IrInstruction *dest_type,
103 IrInstruction *value, bool is_implicit)
104 IrInstruction *value, CastOp cast_op)
104105{
105106 IrInstructionCast *cast_instruction = ir_build_instruction<IrInstructionCast>(irb, source_node);
106107 cast_instruction->dest_type = dest_type;
107108 cast_instruction->value = value;
108 cast_instruction->is_implicit = is_implicit;
109 cast_instruction->cast_op = cast_op;
109110 return &cast_instruction->base;
110111}
111112
......@@ -117,6 +118,13 @@ static IrInstruction *ir_build_return(IrBuilder *irb, AstNode *source_node, IrIn
117118 return &return_instruction->base;
118119}
119120
121static IrInstruction *ir_build_const(IrBuilder *irb, AstNode *source_node, TypeTableEntry *type_entry) {
122 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);
123 const_instruction->base.type_entry = type_entry;
124 const_instruction->base.static_value.ok = true;
125 return &const_instruction->base;
126}
127
120128static IrInstruction *ir_build_const_void(IrBuilder *irb, AstNode *source_node) {
121129 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);
122130 const_instruction->base.type_entry = irb->codegen->builtin_types.entry_void;
......@@ -133,14 +141,20 @@ static IrInstruction *ir_build_const_bignum(IrBuilder *irb, AstNode *source_node
133141 return &const_instruction->base;
134142}
135143
136static IrInstruction *ir_build_const_type(IrBuilder *irb, AstNode *source_node, TypeTableEntry *type_entry) {
137 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);
144static IrInstruction *ir_create_const_type(IrBuilder *irb, AstNode *source_node, TypeTableEntry *type_entry) {
145 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb->exec, source_node);
138146 const_instruction->base.type_entry = irb->codegen->builtin_types.entry_type;
139147 const_instruction->base.static_value.ok = true;
140148 const_instruction->base.static_value.data.x_type = type_entry;
141149 return &const_instruction->base;
142150}
143151
152static IrInstruction *ir_build_const_type(IrBuilder *irb, AstNode *source_node, TypeTableEntry *type_entry) {
153 IrInstruction *instruction = ir_create_const_type(irb, source_node, type_entry);
154 ir_instruction_append(irb->current_basic_block, instruction);
155 return instruction;
156}
157
144158static IrInstruction *ir_build_const_fn(IrBuilder *irb, AstNode *source_node, FnTableEntry *fn_entry) {
145159 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);
146160 const_instruction->base.type_entry = fn_entry->type_entry;
......@@ -174,6 +188,16 @@ static IrInstruction *ir_build_load_var(IrBuilder *irb, AstNode *source_node, Va
174188 return &load_var_instruction->base;
175189}
176190
191static IrInstruction *ir_build_call(IrBuilder *irb, AstNode *source_node,
192 IrInstruction *fn, size_t arg_count, IrInstruction **args)
193{
194 IrInstructionCall *call_instruction = ir_build_instruction<IrInstructionCall>(irb, source_node);
195 call_instruction->fn = fn;
196 call_instruction->arg_count = arg_count;
197 call_instruction->args = args;
198 return &call_instruction->base;
199}
200
177201
178202//static size_t get_conditional_defer_count(BlockContext *inner_block, BlockContext *outer_block) {
179203// size_t result = 0;
......@@ -409,6 +433,26 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, AstNode *node, bool pointer_
409433 return irb->codegen->invalid_instruction;
410434}
411435
436static IrInstruction *ir_gen_fn_call(IrBuilder *irb, AstNode *node) {
437 assert(node->type == NodeTypeFnCallExpr);
438
439 if (node->data.fn_call_expr.is_builtin) {
440 zig_panic("TODO ir gen builtin fn");
441 }
442
443 AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;
444 IrInstruction *fn = ir_gen_node(irb, fn_ref_node, node->block_context);
445
446 size_t arg_count = node->data.fn_call_expr.params.length;
447 IrInstruction **args = allocate<IrInstruction*>(arg_count);
448 for (size_t i = 0; i < arg_count; i += 1) {
449 AstNode *arg_node = node->data.fn_call_expr.params.at(i);
450 args[i] = ir_gen_node(irb, arg_node, node->block_context);
451 }
452
453 return ir_build_call(irb, node, fn, arg_count, args);
454}
455
412456static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockContext *block_context,
413457 bool pointer_only)
414458{
......@@ -423,12 +467,13 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockCont
423467 return ir_gen_num_lit(irb, node);
424468 case NodeTypeSymbol:
425469 return ir_gen_symbol(irb, node, pointer_only);
470 case NodeTypeFnCallExpr:
471 return ir_gen_fn_call(irb, node);
426472 case NodeTypeUnwrapErrorExpr:
427473 case NodeTypeReturnExpr:
428474 case NodeTypeDefer:
429475 case NodeTypeVariableDeclaration:
430476 case NodeTypePrefixOpExpr:
431 case NodeTypeFnCallExpr:
432477 case NodeTypeArrayAccessExpr:
433478 case NodeTypeSliceExpr:
434479 case NodeTypeFieldAccessExpr:
......@@ -782,6 +827,296 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, IrInstruction *pare
782827 return ir_determine_peer_types(ira, parent_instruction, instructions, instruction_count);
783828}
784829
830static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,
831 IrInstruction *dest_type, CastOp cast_op, bool need_alloca)
832{
833 assert(dest_type->type_entry->id == TypeTableEntryIdMetaType);
834 assert(dest_type->static_value.ok);
835 TypeTableEntry *wanted_type = dest_type->static_value.data.x_type;
836
837 if (value->static_value.ok) {
838 IrInstruction *result = ir_build_const(&ira->new_irb, source_instr->source_node, wanted_type);
839 eval_const_expr_implicit_cast(cast_op, &value->static_value, value->type_entry,
840 &result->static_value, wanted_type);
841 return result;
842 } else {
843 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->source_node,
844 dest_type->other, value->other, cast_op);
845 result->type_entry = wanted_type;
846 if (need_alloca && source_instr->source_node->block_context->fn_entry) {
847 IrInstructionCast *cast_instruction = (IrInstructionCast *)result;
848 source_instr->source_node->block_context->fn_entry->cast_alloca_list.append(cast_instruction);
849 }
850 return result;
851 }
852}
853
854static bool is_slice(TypeTableEntry *type) {
855 return type->id == TypeTableEntryIdStruct && type->data.structure.is_slice;
856}
857
858static bool is_u8(TypeTableEntry *type) {
859 return type->id == TypeTableEntryIdInt &&
860 !type->data.integral.is_signed && type->data.integral.bit_count == 8;
861}
862
863static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,
864 IrInstruction *dest_type, IrInstruction *value)
865{
866 assert(dest_type->type_entry->id == TypeTableEntryIdMetaType);
867 assert(dest_type->static_value.ok);
868
869 TypeTableEntry *wanted_type = dest_type->static_value.data.x_type;
870 TypeTableEntry *actual_type = value->type_entry;
871 TypeTableEntry *wanted_type_canon = get_underlying_type(wanted_type);
872 TypeTableEntry *actual_type_canon = get_underlying_type(actual_type);
873
874 TypeTableEntry *isize_type = ira->codegen->builtin_types.entry_isize;
875 TypeTableEntry *usize_type = ira->codegen->builtin_types.entry_usize;
876
877 if (wanted_type_canon->id == TypeTableEntryIdInvalid ||
878 actual_type_canon->id == TypeTableEntryIdInvalid)
879 {
880 return ira->codegen->invalid_instruction;
881 }
882
883 // explicit match or non-const to const
884 if (types_match_const_cast_only(wanted_type, actual_type)) {
885 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpNoop, false);
886 }
887
888 // explicit cast from bool to int
889 if (wanted_type_canon->id == TypeTableEntryIdInt &&
890 actual_type_canon->id == TypeTableEntryIdBool)
891 {
892 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpBoolToInt, false);
893 }
894
895 // explicit cast from pointer to isize or usize
896 if ((wanted_type_canon == isize_type || wanted_type_canon == usize_type) &&
897 type_is_codegen_pointer(actual_type_canon))
898 {
899 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpPtrToInt, false);
900 }
901
902
903 // explicit cast from isize or usize to pointer
904 if (wanted_type_canon->id == TypeTableEntryIdPointer &&
905 (actual_type_canon == isize_type || actual_type_canon == usize_type))
906 {
907 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpIntToPtr, false);
908 }
909
910 // explicit widening or shortening cast
911 if ((wanted_type_canon->id == TypeTableEntryIdInt &&
912 actual_type_canon->id == TypeTableEntryIdInt) ||
913 (wanted_type_canon->id == TypeTableEntryIdFloat &&
914 actual_type_canon->id == TypeTableEntryIdFloat))
915 {
916 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpWidenOrShorten, false);
917 }
918
919 // explicit cast from int to float
920 if (wanted_type_canon->id == TypeTableEntryIdFloat &&
921 actual_type_canon->id == TypeTableEntryIdInt)
922 {
923 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpIntToFloat, false);
924 }
925
926 // explicit cast from float to int
927 if (wanted_type_canon->id == TypeTableEntryIdInt &&
928 actual_type_canon->id == TypeTableEntryIdFloat)
929 {
930 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpFloatToInt, false);
931 }
932
933 // explicit cast from array to slice
934 if (is_slice(wanted_type) &&
935 actual_type->id == TypeTableEntryIdArray &&
936 types_match_const_cast_only(
937 wanted_type->data.structure.fields[0].type_entry->data.pointer.child_type,
938 actual_type->data.array.child_type))
939 {
940 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpToUnknownSizeArray, true);
941 }
942
943 // explicit cast from []T to []u8 or []u8 to []T
944 if (is_slice(wanted_type) && is_slice(actual_type) &&
945 (is_u8(wanted_type->data.structure.fields[0].type_entry->data.pointer.child_type) ||
946 is_u8(actual_type->data.structure.fields[0].type_entry->data.pointer.child_type)) &&
947 (wanted_type->data.structure.fields[0].type_entry->data.pointer.is_const ||
948 !actual_type->data.structure.fields[0].type_entry->data.pointer.is_const))
949 {
950 mark_impure_fn(ira->codegen, source_instr->source_node->block_context, source_instr->source_node);
951 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpResizeSlice, true);
952 }
953
954 // explicit cast from [N]u8 to []T
955 if (is_slice(wanted_type) &&
956 actual_type->id == TypeTableEntryIdArray &&
957 is_u8(actual_type->data.array.child_type))
958 {
959 mark_impure_fn(ira->codegen, source_instr->source_node->block_context, source_instr->source_node);
960 uint64_t child_type_size = type_size(ira->codegen,
961 wanted_type->data.structure.fields[0].type_entry->data.pointer.child_type);
962 if (actual_type->data.array.len % child_type_size == 0) {
963 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpBytesToSlice, true);
964 } else {
965 add_node_error(ira->codegen, source_instr->source_node,
966 buf_sprintf("unable to convert %s to %s: size mismatch",
967 buf_ptr(&actual_type->name), buf_ptr(&wanted_type->name)));
968 return ira->codegen->invalid_instruction;
969 }
970 }
971
972 // explicit cast from pointer to another pointer
973 if ((actual_type->id == TypeTableEntryIdPointer || actual_type->id == TypeTableEntryIdFn) &&
974 (wanted_type->id == TypeTableEntryIdPointer || wanted_type->id == TypeTableEntryIdFn))
975 {
976 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpPointerReinterpret, false);
977 }
978
979 // explicit cast from maybe pointer to another maybe pointer
980 if (actual_type->id == TypeTableEntryIdMaybe &&
981 (actual_type->data.maybe.child_type->id == TypeTableEntryIdPointer ||
982 actual_type->data.maybe.child_type->id == TypeTableEntryIdFn) &&
983 wanted_type->id == TypeTableEntryIdMaybe &&
984 (wanted_type->data.maybe.child_type->id == TypeTableEntryIdPointer ||
985 wanted_type->data.maybe.child_type->id == TypeTableEntryIdFn))
986 {
987 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpPointerReinterpret, false);
988 }
989
990 // explicit cast from child type of maybe type to maybe type
991 if (wanted_type->id == TypeTableEntryIdMaybe) {
992 if (types_match_const_cast_only(wanted_type->data.maybe.child_type, actual_type)) {
993 IrInstruction *cast_instruction = ir_resolve_cast(ira, source_instr, value, dest_type,
994 CastOpMaybeWrap, true);
995 cast_instruction->return_knowledge = ReturnKnowledgeKnownNonNull;
996 return cast_instruction;
997 } else if (actual_type->id == TypeTableEntryIdNumLitInt ||
998 actual_type->id == TypeTableEntryIdNumLitFloat)
999 {
1000 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.maybe.child_type)) {
1001 IrInstruction *cast_instruction = ir_resolve_cast(ira, source_instr, value, dest_type,
1002 CastOpMaybeWrap, true);
1003 cast_instruction->return_knowledge = ReturnKnowledgeKnownNonNull;
1004 return cast_instruction;
1005 } else {
1006 return ira->codegen->invalid_instruction;
1007 }
1008 }
1009 }
1010
1011 // explicit cast from null literal to maybe type
1012 if (wanted_type->id == TypeTableEntryIdMaybe &&
1013 actual_type->id == TypeTableEntryIdNullLit)
1014 {
1015 IrInstruction *cast_instruction = ir_resolve_cast(ira, source_instr, value, dest_type,
1016 CastOpNullToMaybe, true);
1017 cast_instruction->return_knowledge = ReturnKnowledgeKnownNull;
1018 return cast_instruction;
1019 }
1020
1021 // explicit cast from child type of error type to error type
1022 if (wanted_type->id == TypeTableEntryIdErrorUnion) {
1023 if (types_match_const_cast_only(wanted_type->data.error.child_type, actual_type)) {
1024 IrInstruction *cast_instruction = ir_resolve_cast(ira, source_instr, value, dest_type,
1025 CastOpErrorWrap, true);
1026 cast_instruction->return_knowledge = ReturnKnowledgeKnownNonError;
1027 return cast_instruction;
1028 } else if (actual_type->id == TypeTableEntryIdNumLitInt ||
1029 actual_type->id == TypeTableEntryIdNumLitFloat)
1030 {
1031 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error.child_type)) {
1032 IrInstruction *cast_instruction = ir_resolve_cast(ira, source_instr, value, dest_type,
1033 CastOpErrorWrap, true);
1034 cast_instruction->return_knowledge = ReturnKnowledgeKnownNonError;
1035 return cast_instruction;
1036 } else {
1037 return ira->codegen->invalid_instruction;
1038 }
1039 }
1040 }
1041
1042 // explicit cast from pure error to error union type
1043 if (wanted_type->id == TypeTableEntryIdErrorUnion &&
1044 actual_type->id == TypeTableEntryIdPureError)
1045 {
1046 IrInstruction *cast_instruction = ir_resolve_cast(ira, source_instr, value, dest_type,
1047 CastOpPureErrorWrap, false);
1048 cast_instruction->return_knowledge = ReturnKnowledgeKnownError;
1049 return cast_instruction;
1050 }
1051
1052 // explicit cast from number literal to another type
1053 if (actual_type->id == TypeTableEntryIdNumLitFloat ||
1054 actual_type->id == TypeTableEntryIdNumLitInt)
1055 {
1056 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type_canon)) {
1057 CastOp op;
1058 if ((actual_type->id == TypeTableEntryIdNumLitFloat &&
1059 wanted_type_canon->id == TypeTableEntryIdFloat) ||
1060 (actual_type->id == TypeTableEntryIdNumLitInt &&
1061 wanted_type_canon->id == TypeTableEntryIdInt))
1062 {
1063 op = CastOpNoop;
1064 } else if (wanted_type_canon->id == TypeTableEntryIdInt) {
1065 op = CastOpFloatToInt;
1066 } else if (wanted_type_canon->id == TypeTableEntryIdFloat) {
1067 op = CastOpIntToFloat;
1068 } else {
1069 zig_unreachable();
1070 }
1071 return ir_resolve_cast(ira, source_instr, value, dest_type, op, false);
1072 } else {
1073 return ira->codegen->invalid_instruction;
1074 }
1075 }
1076
1077 // explicit cast from %void to integer type which can fit it
1078 bool actual_type_is_void_err = actual_type->id == TypeTableEntryIdErrorUnion &&
1079 !type_has_bits(actual_type->data.error.child_type);
1080 bool actual_type_is_pure_err = actual_type->id == TypeTableEntryIdPureError;
1081 if ((actual_type_is_void_err || actual_type_is_pure_err) &&
1082 wanted_type->id == TypeTableEntryIdInt)
1083 {
1084 BigNum bn;
1085 bignum_init_unsigned(&bn, ira->codegen->error_decls.length);
1086 if (bignum_fits_in_bits(&bn, wanted_type->data.integral.bit_count,
1087 wanted_type->data.integral.is_signed))
1088 {
1089 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpErrToInt, false);
1090 } else {
1091 add_node_error(ira->codegen, source_instr->source_node,
1092 buf_sprintf("too many error values to fit in '%s'", buf_ptr(&wanted_type->name)));
1093 return ira->codegen->invalid_instruction;
1094 }
1095 }
1096
1097 // explicit cast from integer to enum type with no payload
1098 if (actual_type->id == TypeTableEntryIdInt &&
1099 wanted_type->id == TypeTableEntryIdEnum &&
1100 wanted_type->data.enumeration.gen_field_count == 0)
1101 {
1102 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpIntToEnum, false);
1103 }
1104
1105 // explicit cast from enum type with no payload to integer
1106 if (wanted_type->id == TypeTableEntryIdInt &&
1107 actual_type->id == TypeTableEntryIdEnum &&
1108 actual_type->data.enumeration.gen_field_count == 0)
1109 {
1110 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpEnumToInt, false);
1111 }
1112
1113 add_node_error(ira->codegen, source_instr->source_node,
1114 buf_sprintf("invalid cast from type '%s' to '%s'",
1115 buf_ptr(&actual_type->name),
1116 buf_ptr(&wanted_type->name)));
1117 return ira->codegen->invalid_instruction;
1118}
1119
7851120static IrInstruction *ir_get_casted_value(IrAnalyze *ira, IrInstruction *value, TypeTableEntry *expected_type) {
7861121 assert(value);
7871122 assert(value != ira->old_irb.codegen->invalid_instruction);
......@@ -806,10 +1141,8 @@ static IrInstruction *ir_get_casted_value(IrAnalyze *ira, IrInstruction *value,
8061141
8071142 case ImplicitCastMatchResultYes:
8081143 {
809 IrInstruction *dest_type = ir_build_const_type(&ira->new_irb, value->source_node, expected_type);
810 bool is_implicit = true;
811 IrInstruction *cast_instruction = ir_build_cast(&ira->new_irb, value->source_node, dest_type,
812 value, is_implicit);
1144 IrInstruction *dest_type = ir_create_const_type(&ira->new_irb, value->source_node, expected_type);
1145 IrInstruction *cast_instruction = ir_analyze_cast(ira, value, dest_type, value);
8131146 return cast_instruction;
8141147 }
8151148 case ImplicitCastMatchResultReportedError:
......@@ -849,18 +1182,41 @@ static TypeTableEntry *ir_analyze_bin_op_bool(IrAnalyze *ira, IrInstructionBinOp
8491182 IrInstruction *op1 = bin_op_instruction->op1;
8501183 IrInstruction *op2 = bin_op_instruction->op2;
8511184
852 IrInstruction *casted_op1 = ir_get_casted_value(ira, op1->other, ira->old_irb.codegen->builtin_types.entry_bool);
1185 TypeTableEntry *bool_type = ira->old_irb.codegen->builtin_types.entry_bool;
1186
1187 IrInstruction *casted_op1 = ir_get_casted_value(ira, op1->other, bool_type);
8531188 if (casted_op1 == ira->old_irb.codegen->invalid_instruction)
8541189 return ira->old_irb.codegen->builtin_types.entry_invalid;
8551190
856 IrInstruction *casted_op2 = ir_get_casted_value(ira, op2->other, ira->old_irb.codegen->builtin_types.entry_bool);
1191 IrInstruction *casted_op2 = ir_get_casted_value(ira, op2->other, bool_type);
8571192 if (casted_op2 == ira->old_irb.codegen->invalid_instruction)
8581193 return ira->old_irb.codegen->builtin_types.entry_invalid;
8591194
1195 ConstExprValue *op1_val = &casted_op1->static_value;
1196 ConstExprValue *op2_val = &casted_op2->static_value;
1197 if (op1_val->ok && op2_val->ok) {
1198 ConstExprValue *out_val = &bin_op_instruction->base.static_value;
1199 bin_op_instruction->base.other = &bin_op_instruction->base;
1200
1201 assert(op1->type_entry->id == TypeTableEntryIdBool);
1202 assert(op2->type_entry->id == TypeTableEntryIdBool);
1203 if (bin_op_instruction->op_id == IrBinOpBoolOr) {
1204 out_val->data.x_bool = op1_val->data.x_bool || op2_val->data.x_bool;
1205 } else if (bin_op_instruction->op_id == IrBinOpBoolAnd) {
1206 out_val->data.x_bool = op1_val->data.x_bool && op2_val->data.x_bool;
1207 } else {
1208 zig_unreachable();
1209 }
1210 out_val->ok = true;
1211 out_val->depends_on_compile_var = op1_val->depends_on_compile_var ||
1212 op2_val->depends_on_compile_var;
1213 return bool_type;
1214 }
1215
8601216 ir_link_new(ir_build_bin_op(&ira->new_irb, bin_op_instruction->base.source_node,
8611217 bin_op_instruction->op_id, op1->other, op2->other), &bin_op_instruction->base);
8621218
863 return ira->old_irb.codegen->builtin_types.entry_bool;
1219 return bool_type;
8641220}
8651221
8661222static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) {
......@@ -925,12 +1281,109 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
9251281 zig_unreachable();
9261282 }
9271283
1284 zig_panic("TODO interpret bin_op_cmp");
1285
9281286 ir_link_new(ir_build_bin_op(&ira->new_irb, bin_op_instruction->base.source_node,
9291287 op_id, op1->other, op2->other), &bin_op_instruction->base);
9301288
9311289 return ira->old_irb.codegen->builtin_types.entry_bool;
9321290}
9331291
1292static uint64_t max_unsigned_val(TypeTableEntry *type_entry) {
1293 assert(type_entry->id == TypeTableEntryIdInt);
1294 if (type_entry->data.integral.bit_count == 64) {
1295 return UINT64_MAX;
1296 } else if (type_entry->data.integral.bit_count == 32) {
1297 return UINT32_MAX;
1298 } else if (type_entry->data.integral.bit_count == 16) {
1299 return UINT16_MAX;
1300 } else if (type_entry->data.integral.bit_count == 8) {
1301 return UINT8_MAX;
1302 } else {
1303 zig_unreachable();
1304 }
1305}
1306
1307static int ir_eval_bignum(ConstExprValue *op1_val, ConstExprValue *op2_val,
1308 ConstExprValue *out_val, bool (*bignum_fn)(BigNum *, BigNum *, BigNum *),
1309 TypeTableEntry *type, bool wrapping_op)
1310{
1311 bool overflow = bignum_fn(&out_val->data.x_bignum, &op1_val->data.x_bignum, &op2_val->data.x_bignum);
1312 if (overflow) {
1313 return ErrorOverflow;
1314 }
1315
1316 if (type->id == TypeTableEntryIdInt && !bignum_fits_in_bits(&out_val->data.x_bignum,
1317 type->data.integral.bit_count, type->data.integral.is_signed))
1318 {
1319 if (wrapping_op) {
1320 if (type->data.integral.is_signed) {
1321 out_val->data.x_bignum.data.x_uint = max_unsigned_val(type) - out_val->data.x_bignum.data.x_uint + 1;
1322 out_val->data.x_bignum.is_negative = !out_val->data.x_bignum.is_negative;
1323 } else if (out_val->data.x_bignum.is_negative) {
1324 out_val->data.x_bignum.data.x_uint = max_unsigned_val(type) - out_val->data.x_bignum.data.x_uint + 1;
1325 out_val->data.x_bignum.is_negative = false;
1326 } else {
1327 bignum_truncate(&out_val->data.x_bignum, type->data.integral.bit_count);
1328 }
1329 } else {
1330 return ErrorOverflow;
1331 }
1332 }
1333
1334 out_val->ok = true;
1335 out_val->depends_on_compile_var = op1_val->depends_on_compile_var || op2_val->depends_on_compile_var;
1336 return 0;
1337}
1338
1339static int ir_eval_math_op(ConstExprValue *op1_val, TypeTableEntry *op1_type,
1340 IrBinOp op_id, ConstExprValue *op2_val, TypeTableEntry *op2_type, ConstExprValue *out_val)
1341{
1342 switch (op_id) {
1343 case IrBinOpInvalid:
1344 case IrBinOpBoolOr:
1345 case IrBinOpBoolAnd:
1346 case IrBinOpCmpEq:
1347 case IrBinOpCmpNotEq:
1348 case IrBinOpCmpLessThan:
1349 case IrBinOpCmpGreaterThan:
1350 case IrBinOpCmpLessOrEq:
1351 case IrBinOpCmpGreaterOrEq:
1352 case IrBinOpArrayCat:
1353 case IrBinOpArrayMult:
1354 zig_unreachable();
1355 case IrBinOpBinOr:
1356 return ir_eval_bignum(op1_val, op2_val, out_val, bignum_or, op1_type, false);
1357 case IrBinOpBinXor:
1358 return ir_eval_bignum(op1_val, op2_val, out_val, bignum_xor, op1_type, false);
1359 case IrBinOpBinAnd:
1360 return ir_eval_bignum(op1_val, op2_val, out_val, bignum_and, op1_type, false);
1361 case IrBinOpBitShiftLeft:
1362 return ir_eval_bignum(op1_val, op2_val, out_val, bignum_shl, op1_type, false);
1363 case IrBinOpBitShiftLeftWrap:
1364 return ir_eval_bignum(op1_val, op2_val, out_val, bignum_shl, op1_type, true);
1365 case IrBinOpBitShiftRight:
1366 return ir_eval_bignum(op1_val, op2_val, out_val, bignum_shr, op1_type, false);
1367 case IrBinOpAdd:
1368 return ir_eval_bignum(op1_val, op2_val, out_val, bignum_add, op1_type, false);
1369 case IrBinOpAddWrap:
1370 return ir_eval_bignum(op1_val, op2_val, out_val, bignum_add, op1_type, true);
1371 case IrBinOpSub:
1372 return ir_eval_bignum(op1_val, op2_val, out_val, bignum_sub, op1_type, false);
1373 case IrBinOpSubWrap:
1374 return ir_eval_bignum(op1_val, op2_val, out_val, bignum_sub, op1_type, true);
1375 case IrBinOpMult:
1376 return ir_eval_bignum(op1_val, op2_val, out_val, bignum_mul, op1_type, false);
1377 case IrBinOpMultWrap:
1378 return ir_eval_bignum(op1_val, op2_val, out_val, bignum_mul, op1_type, true);
1379 case IrBinOpDiv:
1380 return ir_eval_bignum(op1_val, op2_val, out_val, bignum_div, op1_type, false);
1381 case IrBinOpMod:
1382 return ir_eval_bignum(op1_val, op2_val, out_val, bignum_mod, op1_type, false);
1383 }
1384 zig_unreachable();
1385}
1386
9341387static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) {
9351388 IrInstruction *op1 = bin_op_instruction->op1;
9361389 IrInstruction *op2 = bin_op_instruction->op2;
......@@ -955,12 +1408,39 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp
9551408 // float
9561409 } else {
9571410 AstNode *source_node = bin_op_instruction->base.source_node;
958 add_node_error(ira->old_irb.codegen, source_node, buf_sprintf("invalid operands to binary expression: '%s' and '%s'",
1411 add_node_error(ira->old_irb.codegen, source_node,
1412 buf_sprintf("invalid operands to binary expression: '%s' and '%s'",
9591413 buf_ptr(&op1->type_entry->name),
9601414 buf_ptr(&op2->type_entry->name)));
9611415 return ira->old_irb.codegen->builtin_types.entry_invalid;
9621416 }
9631417
1418 if (op1->static_value.ok && op2->static_value.ok) {
1419 ConstExprValue *op1_val = &op1->static_value;
1420 ConstExprValue *op2_val = &op2->static_value;
1421 ConstExprValue *out_val = &bin_op_instruction->base.static_value;
1422
1423 bin_op_instruction->base.other = &bin_op_instruction->base;
1424
1425 int err;
1426 if ((err = ir_eval_math_op(op1_val, resolved_type, op_id, op2_val, resolved_type, out_val))) {
1427 if (err == ErrorDivByZero) {
1428 add_node_error(ira->codegen, bin_op_instruction->base.source_node,
1429 buf_sprintf("division by zero is undefined"));
1430 return ira->codegen->builtin_types.entry_invalid;
1431 } else if (err == ErrorOverflow) {
1432 add_node_error(ira->codegen, bin_op_instruction->base.source_node,
1433 buf_sprintf("value cannot be represented in any integer type"));
1434 return ira->codegen->builtin_types.entry_invalid;
1435 }
1436 return ira->codegen->builtin_types.entry_invalid;
1437 }
1438
1439 ir_num_lit_fits_in_other_type(ira, &bin_op_instruction->base, resolved_type);
1440 return resolved_type;
1441
1442 }
1443
9641444 ir_link_new(ir_build_bin_op(&ira->new_irb, bin_op_instruction->base.source_node,
9651445 op_id, op1->other, op2->other), &bin_op_instruction->base);
9661446
......@@ -1011,6 +1491,40 @@ static TypeTableEntry *ir_analyze_instruction_load_var(IrAnalyze *ira, IrInstruc
10111491 return load_var_instruction->var->type;
10121492}
10131493
1494static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCall *call_instruction) {
1495 IrInstruction *fn_ref = call_instruction->fn->other;
1496 if (fn_ref->type_entry->id == TypeTableEntryIdInvalid)
1497 return ira->codegen->builtin_types.entry_invalid;
1498
1499 if (fn_ref->static_value.ok) {
1500 if (fn_ref->type_entry->id == TypeTableEntryIdMetaType) {
1501 size_t actual_param_count = call_instruction->arg_count;
1502
1503 if (actual_param_count != 1) {
1504 add_node_error(ira->codegen, call_instruction->base.source_node,
1505 buf_sprintf("cast expression expects exactly one parameter"));
1506 return ira->codegen->builtin_types.entry_invalid;
1507 }
1508
1509 IrInstruction *arg = call_instruction->args[0];
1510 IrInstruction *cast_instruction = ir_analyze_cast(ira, &call_instruction->base, fn_ref, arg);
1511 if (cast_instruction == ira->codegen->invalid_instruction)
1512 return ira->codegen->builtin_types.entry_invalid;
1513
1514 ir_link_new(cast_instruction, &call_instruction->base);
1515 return cast_instruction->type_entry;
1516 } else {
1517 zig_panic("TODO analyze more fn call types");
1518 }
1519 } else {
1520 //ir_link_new(ir_build_call(&ira->new_irb, call_instruction->base.source_node,
1521 // call_instruction->fn, call_instruction->arg_count, call_instruction->args),
1522 // &call_instruction->base);
1523
1524 zig_panic("TODO analyze fn call");
1525 }
1526}
1527
10141528static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {
10151529 switch (instruction->id) {
10161530 case IrInstructionIdInvalid:
......@@ -1023,11 +1537,12 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
10231537 return ir_analyze_instruction_bin_op(ira, (IrInstructionBinOp *)instruction);
10241538 case IrInstructionIdLoadVar:
10251539 return ir_analyze_instruction_load_var(ira, (IrInstructionLoadVar *)instruction);
1540 case IrInstructionIdCall:
1541 return ir_analyze_instruction_call(ira, (IrInstructionCall *)instruction);
10261542 case IrInstructionIdCondBr:
10271543 case IrInstructionIdSwitchBr:
10281544 case IrInstructionIdPhi:
10291545 case IrInstructionIdStoreVar:
1030 case IrInstructionIdCall:
10311546 case IrInstructionIdBuiltinCall:
10321547 case IrInstructionIdCast:
10331548 zig_panic("TODO analyze more instructions");
src/ir_print.cpp+29-4
......@@ -20,7 +20,7 @@ static void ir_print_prefix(IrPrint *irp, IrInstruction *instruction) {
2020static void ir_print_return(IrPrint *irp, IrInstructionReturn *return_instruction) {
2121 ir_print_prefix(irp, &return_instruction->base);
2222 assert(return_instruction->value);
23 fprintf(irp->f, "return #%zu;\n", return_instruction->value->debug_id);
23 fprintf(irp->f, "return #%zu\n", return_instruction->value->debug_id);
2424}
2525
2626static void ir_print_const(IrPrint *irp, IrInstructionConst *const_instruction) {
......@@ -43,8 +43,10 @@ static void ir_print_const(IrPrint *irp, IrInstructionConst *const_instruction)
4343 fprintf(irp->f, "%s%llu\n", negative_str, bignum->data.x_uint);
4444 break;
4545 }
46 case TypeTableEntryIdVar:
4746 case TypeTableEntryIdMetaType:
47 fprintf(irp->f, "%s\n", buf_ptr(&const_instruction->base.static_value.data.x_type->name));
48 break;
49 case TypeTableEntryIdVar:
4850 case TypeTableEntryIdBool:
4951 case TypeTableEntryIdUnreachable:
5052 case TypeTableEntryIdInt:
......@@ -139,6 +141,25 @@ static void ir_print_load_var(IrPrint *irp, IrInstructionLoadVar *load_var_instr
139141 buf_ptr(&load_var_instruction->var->name));
140142}
141143
144static void ir_print_cast(IrPrint *irp, IrInstructionCast *cast_instruction) {
145 ir_print_prefix(irp, &cast_instruction->base);
146 fprintf(irp->f, "cast #%zu to #%zu\n",
147 cast_instruction->value->debug_id,
148 cast_instruction->dest_type->debug_id);
149}
150
151static void ir_print_call(IrPrint *irp, IrInstructionCall *call_instruction) {
152 ir_print_prefix(irp, &call_instruction->base);
153 fprintf(irp->f, "#%zu(", call_instruction->fn->debug_id);
154 for (size_t i = 0; i < call_instruction->arg_count; i += 1) {
155 IrInstruction *arg = call_instruction->args[i];
156 if (i != 0)
157 fprintf(irp->f, ", ");
158 fprintf(irp->f, "#%zu", arg->debug_id);
159 }
160 fprintf(irp->f, ")\n");
161}
162
142163static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
143164 switch (instruction->id) {
144165 case IrInstructionIdInvalid:
......@@ -155,13 +176,17 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
155176 case IrInstructionIdLoadVar:
156177 ir_print_load_var(irp, (IrInstructionLoadVar *)instruction);
157178 break;
179 case IrInstructionIdCast:
180 ir_print_cast(irp, (IrInstructionCast *)instruction);
181 break;
182 case IrInstructionIdCall:
183 ir_print_call(irp, (IrInstructionCall *)instruction);
184 break;
158185 case IrInstructionIdCondBr:
159186 case IrInstructionIdSwitchBr:
160187 case IrInstructionIdPhi:
161188 case IrInstructionIdStoreVar:
162 case IrInstructionIdCall:
163189 case IrInstructionIdBuiltinCall:
164 case IrInstructionIdCast:
165190 zig_panic("TODO print more IR instructions");
166191 }
167192}