| ... | @@ -338,6 +338,11 @@ static bool want_debug_safety(CodeGen *g, AstNode *node) { | ... | @@ -338,6 +338,11 @@ static bool want_debug_safety(CodeGen *g, AstNode *node) { |
| 338 | return !g->is_release_build && !node->block_context->safety_off; | 338 | return !g->is_release_build && !node->block_context->safety_off; |
| 339 | } | 339 | } |
| 340 | | 340 | |
| | 341 | static void gen_debug_safety_crash(CodeGen *g) { |
| | 342 | LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, ""); |
| | 343 | LLVMBuildUnreachable(g->builder); |
| | 344 | } |
| | 345 | |
| 341 | static void add_bounds_check(CodeGen *g, AstNode *source_node, LLVMValueRef target_val, | 346 | static void add_bounds_check(CodeGen *g, AstNode *source_node, LLVMValueRef target_val, |
| 342 | LLVMIntPredicate lower_pred, LLVMValueRef lower_value, | 347 | LLVMIntPredicate lower_pred, LLVMValueRef lower_value, |
| 343 | LLVMIntPredicate upper_pred, LLVMValueRef upper_value) | 348 | LLVMIntPredicate upper_pred, LLVMValueRef upper_value) |
| ... | @@ -362,8 +367,7 @@ static void add_bounds_check(CodeGen *g, AstNode *source_node, LLVMValueRef targ | ... | @@ -362,8 +367,7 @@ static void add_bounds_check(CodeGen *g, AstNode *source_node, LLVMValueRef targ |
| 362 | LLVMBuildCondBr(g->builder, lower_ok_val, lower_ok_block, bounds_check_fail_block); | 367 | LLVMBuildCondBr(g->builder, lower_ok_val, lower_ok_block, bounds_check_fail_block); |
| 363 | | 368 | |
| 364 | LLVMPositionBuilderAtEnd(g->builder, bounds_check_fail_block); | 369 | LLVMPositionBuilderAtEnd(g->builder, bounds_check_fail_block); |
| 365 | LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, ""); | 370 | gen_debug_safety_crash(g); |
| 366 | LLVMBuildUnreachable(g->builder); | | |
| 367 | | 371 | |
| 368 | if (upper_value) { | 372 | if (upper_value) { |
| 369 | LLVMPositionBuilderAtEnd(g->builder, lower_ok_block); | 373 | LLVMPositionBuilderAtEnd(g->builder, lower_ok_block); |
| ... | @@ -1369,8 +1373,7 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { | ... | @@ -1369,8 +1373,7 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { |
| 1369 | LLVMBuildCondBr(g->builder, cond_val, ok_block, err_block); | 1373 | LLVMBuildCondBr(g->builder, cond_val, ok_block, err_block); |
| 1370 | | 1374 | |
| 1371 | LLVMPositionBuilderAtEnd(g->builder, err_block); | 1375 | LLVMPositionBuilderAtEnd(g->builder, err_block); |
| 1372 | LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, ""); | 1376 | gen_debug_safety_crash(g); |
| 1373 | LLVMBuildUnreachable(g->builder); | | |
| 1374 | | 1377 | |
| 1375 | LLVMPositionBuilderAtEnd(g->builder, ok_block); | 1378 | LLVMPositionBuilderAtEnd(g->builder, ok_block); |
| 1376 | } | 1379 | } |
| ... | @@ -1408,8 +1411,7 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { | ... | @@ -1408,8 +1411,7 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { |
| 1408 | LLVMBuildCondBr(g->builder, cond_val, ok_block, null_block); | 1411 | LLVMBuildCondBr(g->builder, cond_val, ok_block, null_block); |
| 1409 | | 1412 | |
| 1410 | LLVMPositionBuilderAtEnd(g->builder, null_block); | 1413 | LLVMPositionBuilderAtEnd(g->builder, null_block); |
| 1411 | LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, ""); | 1414 | gen_debug_safety_crash(g); |
| 1412 | LLVMBuildUnreachable(g->builder); | | |
| 1413 | | 1415 | |
| 1414 | LLVMPositionBuilderAtEnd(g->builder, ok_block); | 1416 | LLVMPositionBuilderAtEnd(g->builder, ok_block); |
| 1415 | } | 1417 | } |
| ... | @@ -1429,6 +1431,28 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { | ... | @@ -1429,6 +1431,28 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { |
| 1429 | zig_unreachable(); | 1431 | zig_unreachable(); |
| 1430 | } | 1432 | } |
| 1431 | | 1433 | |
| | 1434 | static LLVMValueRef gen_overflow_op(CodeGen *g, TypeTableEntry *type_entry, AddSubMul op, |
| | 1435 | LLVMValueRef val1, LLVMValueRef val2) |
| | 1436 | { |
| | 1437 | LLVMValueRef fn_val = get_int_overflow_fn(g, type_entry, op); |
| | 1438 | LLVMValueRef params[] = { |
| | 1439 | val1, |
| | 1440 | val2, |
| | 1441 | }; |
| | 1442 | LLVMValueRef result_struct = LLVMBuildCall(g->builder, fn_val, params, 2, ""); |
| | 1443 | LLVMValueRef result = LLVMBuildExtractValue(g->builder, result_struct, 0, ""); |
| | 1444 | LLVMValueRef overflow_bit = LLVMBuildExtractValue(g->builder, result_struct, 1, ""); |
| | 1445 | LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "OverflowFail"); |
| | 1446 | LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "OverflowOk"); |
| | 1447 | LLVMBuildCondBr(g->builder, overflow_bit, fail_block, ok_block); |
| | 1448 | |
| | 1449 | LLVMPositionBuilderAtEnd(g->builder, fail_block); |
| | 1450 | gen_debug_safety_crash(g); |
| | 1451 | |
| | 1452 | LLVMPositionBuilderAtEnd(g->builder, ok_block); |
| | 1453 | return result; |
| | 1454 | } |
| | 1455 | |
| 1432 | static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node, | 1456 | static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node, |
| 1433 | LLVMValueRef val1, LLVMValueRef val2, | 1457 | LLVMValueRef val1, LLVMValueRef val2, |
| 1434 | TypeTableEntry *op1_type, TypeTableEntry *op2_type, | 1458 | TypeTableEntry *op1_type, TypeTableEntry *op2_type, |
| ... | @@ -1469,24 +1493,54 @@ static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node, | ... | @@ -1469,24 +1493,54 @@ static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node, |
| 1469 | set_debug_source_node(g, source_node); | 1493 | set_debug_source_node(g, source_node); |
| 1470 | if (op1_type->id == TypeTableEntryIdFloat) { | 1494 | if (op1_type->id == TypeTableEntryIdFloat) { |
| 1471 | return LLVMBuildFAdd(g->builder, val1, val2, ""); | 1495 | return LLVMBuildFAdd(g->builder, val1, val2, ""); |
| | 1496 | } else if (op1_type->id == TypeTableEntryIdInt) { |
| | 1497 | if (op1_type->data.integral.is_wrapping) { |
| | 1498 | return LLVMBuildAdd(g->builder, val1, val2, ""); |
| | 1499 | } else if (want_debug_safety(g, source_node)) { |
| | 1500 | return gen_overflow_op(g, op1_type, AddSubMulAdd, val1, val2); |
| | 1501 | } else if (op1_type->data.integral.is_signed) { |
| | 1502 | return LLVMBuildNSWAdd(g->builder, val1, val2, ""); |
| | 1503 | } else { |
| | 1504 | return LLVMBuildNUWAdd(g->builder, val1, val2, ""); |
| | 1505 | } |
| 1472 | } else { | 1506 | } else { |
| 1473 | return LLVMBuildAdd(g->builder, val1, val2, ""); | 1507 | zig_unreachable(); |
| 1474 | } | 1508 | } |
| 1475 | case BinOpTypeSub: | 1509 | case BinOpTypeSub: |
| 1476 | case BinOpTypeAssignMinus: | 1510 | case BinOpTypeAssignMinus: |
| 1477 | set_debug_source_node(g, source_node); | 1511 | set_debug_source_node(g, source_node); |
| 1478 | if (op1_type->id == TypeTableEntryIdFloat) { | 1512 | if (op1_type->id == TypeTableEntryIdFloat) { |
| 1479 | return LLVMBuildFSub(g->builder, val1, val2, ""); | 1513 | return LLVMBuildFSub(g->builder, val1, val2, ""); |
| | 1514 | } else if (op1_type->id == TypeTableEntryIdInt) { |
| | 1515 | if (op1_type->data.integral.is_wrapping) { |
| | 1516 | return LLVMBuildSub(g->builder, val1, val2, ""); |
| | 1517 | } else if (want_debug_safety(g, source_node)) { |
| | 1518 | return gen_overflow_op(g, op1_type, AddSubMulSub, val1, val2); |
| | 1519 | } else if (op1_type->data.integral.is_signed) { |
| | 1520 | return LLVMBuildNSWSub(g->builder, val1, val2, ""); |
| | 1521 | } else { |
| | 1522 | return LLVMBuildNUWSub(g->builder, val1, val2, ""); |
| | 1523 | } |
| 1480 | } else { | 1524 | } else { |
| 1481 | return LLVMBuildSub(g->builder, val1, val2, ""); | 1525 | zig_unreachable(); |
| 1482 | } | 1526 | } |
| 1483 | case BinOpTypeMult: | 1527 | case BinOpTypeMult: |
| 1484 | case BinOpTypeAssignTimes: | 1528 | case BinOpTypeAssignTimes: |
| 1485 | set_debug_source_node(g, source_node); | 1529 | set_debug_source_node(g, source_node); |
| 1486 | if (op1_type->id == TypeTableEntryIdFloat) { | 1530 | if (op1_type->id == TypeTableEntryIdFloat) { |
| 1487 | return LLVMBuildFMul(g->builder, val1, val2, ""); | 1531 | return LLVMBuildFMul(g->builder, val1, val2, ""); |
| | 1532 | } else if (op1_type->id == TypeTableEntryIdInt) { |
| | 1533 | if (op1_type->data.integral.is_wrapping) { |
| | 1534 | return LLVMBuildMul(g->builder, val1, val2, ""); |
| | 1535 | } else if (want_debug_safety(g, source_node)) { |
| | 1536 | return gen_overflow_op(g, op1_type, AddSubMulMul, val1, val2); |
| | 1537 | } else if (op1_type->data.integral.is_signed) { |
| | 1538 | return LLVMBuildNSWMul(g->builder, val1, val2, ""); |
| | 1539 | } else { |
| | 1540 | return LLVMBuildNUWMul(g->builder, val1, val2, ""); |
| | 1541 | } |
| 1488 | } else { | 1542 | } else { |
| 1489 | return LLVMBuildMul(g->builder, val1, val2, ""); | 1543 | zig_unreachable(); |
| 1490 | } | 1544 | } |
| 1491 | case BinOpTypeDiv: | 1545 | case BinOpTypeDiv: |
| 1492 | case BinOpTypeAssignDiv: | 1546 | case BinOpTypeAssignDiv: |
| ... | @@ -2472,9 +2526,10 @@ static LLVMValueRef gen_container_init_expr(CodeGen *g, AstNode *node) { | ... | @@ -2472,9 +2526,10 @@ static LLVMValueRef gen_container_init_expr(CodeGen *g, AstNode *node) { |
| 2472 | assert(node->data.container_init_expr.entries.length == 0); | 2526 | assert(node->data.container_init_expr.entries.length == 0); |
| 2473 | set_debug_source_node(g, node); | 2527 | set_debug_source_node(g, node); |
| 2474 | if (want_debug_safety(g, node)) { | 2528 | if (want_debug_safety(g, node)) { |
| 2475 | LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, ""); | 2529 | gen_debug_safety_crash(g); |
| | 2530 | } else { |
| | 2531 | LLVMBuildUnreachable(g->builder); |
| 2476 | } | 2532 | } |
| 2477 | LLVMBuildUnreachable(g->builder); | | |
| 2478 | return nullptr; | 2533 | return nullptr; |
| 2479 | } else if (type_entry->id == TypeTableEntryIdVoid) { | 2534 | } else if (type_entry->id == TypeTableEntryIdVoid) { |
| 2480 | assert(node->data.container_init_expr.entries.length == 0); | 2535 | assert(node->data.container_init_expr.entries.length == 0); |
| ... | @@ -2983,7 +3038,7 @@ static LLVMValueRef gen_switch_expr(CodeGen *g, AstNode *node) { | ... | @@ -2983,7 +3038,7 @@ static LLVMValueRef gen_switch_expr(CodeGen *g, AstNode *node) { |
| 2983 | set_debug_source_node(g, prong_expr); | 3038 | set_debug_source_node(g, prong_expr); |
| 2984 | LLVMBuildBr(g->builder, end_block); | 3039 | LLVMBuildBr(g->builder, end_block); |
| 2985 | incoming_values.append(prong_val); | 3040 | incoming_values.append(prong_val); |
| 2986 | incoming_blocks.append(prong_block); | 3041 | incoming_blocks.append(LLVMGetInsertBlock(g->builder)); |
| 2987 | } | 3042 | } |
| 2988 | } | 3043 | } |
| 2989 | | 3044 | |
| ... | @@ -2991,9 +3046,10 @@ static LLVMValueRef gen_switch_expr(CodeGen *g, AstNode *node) { | ... | @@ -2991,9 +3046,10 @@ static LLVMValueRef gen_switch_expr(CodeGen *g, AstNode *node) { |
| 2991 | LLVMPositionBuilderAtEnd(g->builder, else_block); | 3046 | LLVMPositionBuilderAtEnd(g->builder, else_block); |
| 2992 | set_debug_source_node(g, node); | 3047 | set_debug_source_node(g, node); |
| 2993 | if (want_debug_safety(g, node)) { | 3048 | if (want_debug_safety(g, node)) { |
| 2994 | LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, ""); | 3049 | gen_debug_safety_crash(g); |
| | 3050 | } else { |
| | 3051 | LLVMBuildUnreachable(g->builder); |
| 2995 | } | 3052 | } |
| 2996 | LLVMBuildUnreachable(g->builder); | | |
| 2997 | } | 3053 | } |
| 2998 | | 3054 | |
| 2999 | if (end_unreachable) { | 3055 | if (end_unreachable) { |
| ... | @@ -3776,6 +3832,18 @@ static const CIntTypeInfo c_int_type_infos[] = { | ... | @@ -3776,6 +3832,18 @@ static const CIntTypeInfo c_int_type_infos[] = { |
| 3776 | {CIntTypeULongLong, "c_ulonglong", false}, | 3832 | {CIntTypeULongLong, "c_ulonglong", false}, |
| 3777 | }; | 3833 | }; |
| 3778 | | 3834 | |
| | 3835 | struct SignWrap { |
| | 3836 | bool is_signed; |
| | 3837 | bool is_wrapping; |
| | 3838 | }; |
| | 3839 | |
| | 3840 | static const SignWrap sign_wrap_list[] = { |
| | 3841 | {false, false}, |
| | 3842 | {false, true}, |
| | 3843 | {true, false}, |
| | 3844 | {true, true}, |
| | 3845 | }; |
| | 3846 | |
| 3779 | static void define_builtin_types(CodeGen *g) { | 3847 | static void define_builtin_types(CodeGen *g) { |
| 3780 | { | 3848 | { |
| 3781 | // if this type is anywhere in the AST, we should never hit codegen. | 3849 | // if this type is anywhere in the AST, we should never hit codegen. |
| ... | @@ -3812,17 +3880,20 @@ static void define_builtin_types(CodeGen *g) { | ... | @@ -3812,17 +3880,20 @@ static void define_builtin_types(CodeGen *g) { |
| 3812 | g->builtin_types.entry_undef = entry; | 3880 | g->builtin_types.entry_undef = entry; |
| 3813 | } | 3881 | } |
| 3814 | | 3882 | |
| 3815 | for (int i = 0; i < array_length(int_sizes_in_bits); i += 1) { | 3883 | for (int int_size_i = 0; int_size_i < array_length(int_sizes_in_bits); int_size_i += 1) { |
| 3816 | int size_in_bits = int_sizes_in_bits[i]; | 3884 | int size_in_bits = int_sizes_in_bits[int_size_i]; |
| 3817 | bool is_signed = true; | 3885 | for (int sign_wrap_i = 0; sign_wrap_i < array_length(sign_wrap_list); sign_wrap_i += 1) { |
| 3818 | for (;;) { | 3886 | bool is_signed = sign_wrap_list[sign_wrap_i].is_signed; |
| | 3887 | bool is_wrapping = sign_wrap_list[sign_wrap_i].is_wrapping; |
| | 3888 | |
| 3819 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt); | 3889 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt); |
| 3820 | entry->type_ref = LLVMIntType(size_in_bits); | 3890 | entry->type_ref = LLVMIntType(size_in_bits); |
| 3821 | entry->deep_const = true; | 3891 | entry->deep_const = true; |
| 3822 | | 3892 | |
| 3823 | const char u_or_i = is_signed ? 'i' : 'u'; | 3893 | const char u_or_i = is_signed ? 'i' : 'u'; |
| | 3894 | const char *w_or_none = is_wrapping ? "w" : ""; |
| 3824 | buf_resize(&entry->name, 0); | 3895 | buf_resize(&entry->name, 0); |
| 3825 | buf_appendf(&entry->name, "%c%d", u_or_i, size_in_bits); | 3896 | buf_appendf(&entry->name, "%c%d%s", u_or_i, size_in_bits, w_or_none); |
| 3826 | | 3897 | |
| 3827 | unsigned dwarf_tag; | 3898 | unsigned dwarf_tag; |
| 3828 | if (is_signed) { | 3899 | if (is_signed) { |
| ... | @@ -3844,16 +3915,11 @@ static void define_builtin_types(CodeGen *g) { | ... | @@ -3844,16 +3915,11 @@ static void define_builtin_types(CodeGen *g) { |
| 3844 | entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), | 3915 | entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), |
| 3845 | debug_size_in_bits, debug_align_in_bits, dwarf_tag); | 3916 | debug_size_in_bits, debug_align_in_bits, dwarf_tag); |
| 3846 | entry->data.integral.is_signed = is_signed; | 3917 | entry->data.integral.is_signed = is_signed; |
| | 3918 | entry->data.integral.is_wrapping = is_wrapping; |
| 3847 | entry->data.integral.bit_count = size_in_bits; | 3919 | entry->data.integral.bit_count = size_in_bits; |
| 3848 | g->primitive_type_table.put(&entry->name, entry); | 3920 | g->primitive_type_table.put(&entry->name, entry); |
| 3849 | | 3921 | |
| 3850 | get_int_type_ptr(g, is_signed, size_in_bits)[0] = entry; | 3922 | get_int_type_ptr(g, is_signed, is_wrapping, size_in_bits)[0] = entry; |
| 3851 | | | |
| 3852 | if (!is_signed) { | | |
| 3853 | break; | | |
| 3854 | } else { | | |
| 3855 | is_signed = false; | | |
| 3856 | } | | |
| 3857 | } | 3923 | } |
| 3858 | } | 3924 | } |
| 3859 | | 3925 | |
| ... | @@ -3875,6 +3941,7 @@ static void define_builtin_types(CodeGen *g) { | ... | @@ -3875,6 +3941,7 @@ static void define_builtin_types(CodeGen *g) { |
| 3875 | debug_align_in_bits, | 3941 | debug_align_in_bits, |
| 3876 | is_signed ? LLVMZigEncoding_DW_ATE_signed() : LLVMZigEncoding_DW_ATE_unsigned()); | 3942 | is_signed ? LLVMZigEncoding_DW_ATE_signed() : LLVMZigEncoding_DW_ATE_unsigned()); |
| 3877 | entry->data.integral.is_signed = is_signed; | 3943 | entry->data.integral.is_signed = is_signed; |
| | 3944 | entry->data.integral.is_wrapping = !is_signed; |
| 3878 | entry->data.integral.bit_count = size_in_bits; | 3945 | entry->data.integral.bit_count = size_in_bits; |
| 3879 | g->primitive_type_table.put(&entry->name, entry); | 3946 | g->primitive_type_table.put(&entry->name, entry); |
| 3880 | | 3947 | |
| ... | @@ -3895,29 +3962,22 @@ static void define_builtin_types(CodeGen *g) { | ... | @@ -3895,29 +3962,22 @@ static void define_builtin_types(CodeGen *g) { |
| 3895 | g->builtin_types.entry_bool = entry; | 3962 | g->builtin_types.entry_bool = entry; |
| 3896 | g->primitive_type_table.put(&entry->name, entry); | 3963 | g->primitive_type_table.put(&entry->name, entry); |
| 3897 | } | 3964 | } |
| 3898 | { | | |
| 3899 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt); | | |
| 3900 | entry->deep_const = true; | | |
| 3901 | entry->type_ref = LLVMIntType(g->pointer_size_bytes * 8); | | |
| 3902 | buf_init_from_str(&entry->name, "isize"); | | |
| 3903 | entry->data.integral.is_signed = true; | | |
| 3904 | entry->data.integral.bit_count = g->pointer_size_bytes * 8; | | |
| 3905 | | 3965 | |
| 3906 | uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref); | 3966 | for (int sign_wrap_i = 0; sign_wrap_i < array_length(sign_wrap_list); sign_wrap_i += 1) { |
| 3907 | uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref); | 3967 | bool is_signed = sign_wrap_list[sign_wrap_i].is_signed; |
| 3908 | entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), | 3968 | bool is_wrapping = sign_wrap_list[sign_wrap_i].is_wrapping; |
| 3909 | debug_size_in_bits, | 3969 | |
| 3910 | debug_align_in_bits, | | |
| 3911 | LLVMZigEncoding_DW_ATE_signed()); | | |
| 3912 | g->builtin_types.entry_isize = entry; | | |
| 3913 | g->primitive_type_table.put(&entry->name, entry); | | |
| 3914 | } | | |
| 3915 | { | | |
| 3916 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt); | 3970 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt); |
| 3917 | entry->deep_const = true; | 3971 | entry->deep_const = true; |
| 3918 | entry->type_ref = LLVMIntType(g->pointer_size_bytes * 8); | 3972 | entry->type_ref = LLVMIntType(g->pointer_size_bytes * 8); |
| 3919 | buf_init_from_str(&entry->name, "usize"); | 3973 | |
| 3920 | entry->data.integral.is_signed = false; | 3974 | const char u_or_i = is_signed ? 'i' : 'u'; |
| | 3975 | const char *w_or_none = is_wrapping ? "w" : ""; |
| | 3976 | buf_resize(&entry->name, 0); |
| | 3977 | buf_appendf(&entry->name, "%csize%s", u_or_i, w_or_none); |
| | 3978 | |
| | 3979 | entry->data.integral.is_signed = is_signed; |
| | 3980 | entry->data.integral.is_wrapping = is_wrapping; |
| 3921 | entry->data.integral.bit_count = g->pointer_size_bytes * 8; | 3981 | entry->data.integral.bit_count = g->pointer_size_bytes * 8; |
| 3922 | | 3982 | |
| 3923 | uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref); | 3983 | uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref); |
| ... | @@ -3925,9 +3985,14 @@ static void define_builtin_types(CodeGen *g) { | ... | @@ -3925,9 +3985,14 @@ static void define_builtin_types(CodeGen *g) { |
| 3925 | entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), | 3985 | entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), |
| 3926 | debug_size_in_bits, | 3986 | debug_size_in_bits, |
| 3927 | debug_align_in_bits, | 3987 | debug_align_in_bits, |
| 3928 | LLVMZigEncoding_DW_ATE_unsigned()); | 3988 | is_signed ? LLVMZigEncoding_DW_ATE_signed() : LLVMZigEncoding_DW_ATE_unsigned()); |
| 3929 | g->builtin_types.entry_usize = entry; | | |
| 3930 | g->primitive_type_table.put(&entry->name, entry); | 3989 | g->primitive_type_table.put(&entry->name, entry); |
| | 3990 | |
| | 3991 | if (is_signed && !is_wrapping) { |
| | 3992 | g->builtin_types.entry_isize = entry; |
| | 3993 | } else if (!is_signed && !is_wrapping) { |
| | 3994 | g->builtin_types.entry_usize = entry; |
| | 3995 | } |
| 3931 | } | 3996 | } |
| 3932 | { | 3997 | { |
| 3933 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat); | 3998 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat); |
| ... | @@ -4009,14 +4074,14 @@ static void define_builtin_types(CodeGen *g) { | ... | @@ -4009,14 +4074,14 @@ static void define_builtin_types(CodeGen *g) { |
| 4009 | g->primitive_type_table.put(&entry->name, entry); | 4074 | g->primitive_type_table.put(&entry->name, entry); |
| 4010 | } | 4075 | } |
| 4011 | | 4076 | |
| 4012 | g->builtin_types.entry_u8 = get_int_type(g, false, 8); | 4077 | g->builtin_types.entry_u8 = get_int_type(g, false, false, 8); |
| 4013 | g->builtin_types.entry_u16 = get_int_type(g, false, 16); | 4078 | g->builtin_types.entry_u16 = get_int_type(g, false, false, 16); |
| 4014 | g->builtin_types.entry_u32 = get_int_type(g, false, 32); | 4079 | g->builtin_types.entry_u32 = get_int_type(g, false, false, 32); |
| 4015 | g->builtin_types.entry_u64 = get_int_type(g, false, 64); | 4080 | g->builtin_types.entry_u64 = get_int_type(g, false, false, 64); |
| 4016 | g->builtin_types.entry_i8 = get_int_type(g, true, 8); | 4081 | g->builtin_types.entry_i8 = get_int_type(g, true, false, 8); |
| 4017 | g->builtin_types.entry_i16 = get_int_type(g, true, 16); | 4082 | g->builtin_types.entry_i16 = get_int_type(g, true, false, 16); |
| 4018 | g->builtin_types.entry_i32 = get_int_type(g, true, 32); | 4083 | g->builtin_types.entry_i32 = get_int_type(g, true, false, 32); |
| 4019 | g->builtin_types.entry_i64 = get_int_type(g, true, 64); | 4084 | g->builtin_types.entry_i64 = get_int_type(g, true, false, 64); |
| 4020 | | 4085 | |
| 4021 | { | 4086 | { |
| 4022 | g->builtin_types.entry_c_void = get_typedecl_type(g, "c_void", g->builtin_types.entry_u8); | 4087 | g->builtin_types.entry_c_void = get_typedecl_type(g, "c_void", g->builtin_types.entry_u8); |