| ... | @@ -1470,16 +1470,25 @@ pub const Object = struct { | ... | @@ -1470,16 +1470,25 @@ pub const Object = struct { |
| 1470 | return full_di_ty; | 1470 | return full_di_ty; |
| 1471 | }, | 1471 | }, |
| 1472 | .ErrorUnion => { | 1472 | .ErrorUnion => { |
| 1473 | const err_set_ty = ty.errorUnionSet(); | | |
| 1474 | const payload_ty = ty.errorUnionPayload(); | 1473 | const payload_ty = ty.errorUnionPayload(); |
| 1475 | if (err_set_ty.errorSetCardinality() == .zero) { | 1474 | switch (ty.errorUnionSet().errorSetCardinality()) { |
| 1476 | const payload_di_ty = try o.lowerDebugType(payload_ty, .full); | 1475 | .zero => { |
| 1477 | // The recursive call to `lowerDebugType` means we can't use `gop` anymore. | 1476 | const payload_di_ty = try o.lowerDebugType(payload_ty, .full); |
| 1478 | try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(payload_di_ty), .{ .mod = o.module }); | 1477 | // The recursive call to `lowerDebugType` means we can't use `gop` anymore. |
| 1479 | return payload_di_ty; | 1478 | try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(payload_di_ty), .{ .mod = o.module }); |
| | 1479 | return payload_di_ty; |
| | 1480 | }, |
| | 1481 | .one => { |
| | 1482 | if (payload_ty.isNoReturn()) { |
| | 1483 | const di_type = dib.createBasicType("void", 0, DW.ATE.signed); |
| | 1484 | gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type); |
| | 1485 | return di_type; |
| | 1486 | } |
| | 1487 | }, |
| | 1488 | .many => {}, |
| 1480 | } | 1489 | } |
| 1481 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { | 1490 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 1482 | const err_set_di_ty = try o.lowerDebugType(err_set_ty, .full); | 1491 | const err_set_di_ty = try o.lowerDebugType(Type.anyerror, .full); |
| 1483 | // The recursive call to `lowerDebugType` means we can't use `gop` anymore. | 1492 | // The recursive call to `lowerDebugType` means we can't use `gop` anymore. |
| 1484 | try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(err_set_di_ty), .{ .mod = o.module }); | 1493 | try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(err_set_di_ty), .{ .mod = o.module }); |
| 1485 | return err_set_di_ty; | 1494 | return err_set_di_ty; |
| ... | @@ -1502,56 +1511,51 @@ pub const Object = struct { | ... | @@ -1502,56 +1511,51 @@ pub const Object = struct { |
| 1502 | break :blk fwd_decl; | 1511 | break :blk fwd_decl; |
| 1503 | }; | 1512 | }; |
| 1504 | | 1513 | |
| 1505 | const err_set_size = err_set_ty.abiSize(target); | 1514 | const error_size = Type.anyerror.abiSize(target); |
| 1506 | const err_set_align = err_set_ty.abiAlignment(target); | 1515 | const error_align = Type.anyerror.abiAlignment(target); |
| 1507 | const payload_size = payload_ty.abiSize(target); | 1516 | const payload_size = payload_ty.abiSize(target); |
| 1508 | const payload_align = payload_ty.abiAlignment(target); | 1517 | const payload_align = payload_ty.abiAlignment(target); |
| 1509 | | 1518 | |
| 1510 | var offset: u64 = 0; | 1519 | var error_index: u32 = undefined; |
| 1511 | offset += err_set_size; | 1520 | var payload_index: u32 = undefined; |
| 1512 | offset = std.mem.alignForwardGeneric(u64, offset, payload_align); | 1521 | var error_offset: u64 = undefined; |
| 1513 | const payload_offset = offset; | 1522 | var payload_offset: u64 = undefined; |
| 1514 | | 1523 | if (error_align > payload_align) { |
| 1515 | var len: u8 = 2; | 1524 | error_index = 0; |
| 1516 | var fields: [3]*llvm.DIType = .{ | 1525 | payload_index = 1; |
| 1517 | dib.createMemberType( | 1526 | error_offset = 0; |
| 1518 | fwd_decl.toScope(), | 1527 | payload_offset = std.mem.alignForwardGeneric(u64, error_size, payload_align); |
| 1519 | "tag", | 1528 | } else { |
| 1520 | di_file, | 1529 | payload_index = 0; |
| 1521 | line, | 1530 | error_index = 1; |
| 1522 | err_set_size * 8, // size in bits | 1531 | payload_offset = 0; |
| 1523 | err_set_align * 8, // align in bits | 1532 | error_offset = std.mem.alignForwardGeneric(u64, payload_size, error_align); |
| 1524 | 0, // offset in bits | | |
| 1525 | 0, // flags | | |
| 1526 | try o.lowerDebugType(err_set_ty, .full), | | |
| 1527 | ), | | |
| 1528 | dib.createMemberType( | | |
| 1529 | fwd_decl.toScope(), | | |
| 1530 | "value", | | |
| 1531 | di_file, | | |
| 1532 | line, | | |
| 1533 | payload_size * 8, // size in bits | | |
| 1534 | payload_align * 8, // align in bits | | |
| 1535 | payload_offset * 8, // offset in bits | | |
| 1536 | 0, // flags | | |
| 1537 | try o.lowerDebugType(payload_ty, .full), | | |
| 1538 | ), | | |
| 1539 | undefined, | | |
| 1540 | }; | | |
| 1541 | | | |
| 1542 | const error_size = Type.anyerror.abiSize(target); | | |
| 1543 | if (payload_align > error_size) { | | |
| 1544 | fields[2] = fields[1]; | | |
| 1545 | const pad_len = @intCast(u32, payload_align - error_size); | | |
| 1546 | fields[1] = dib.createArrayType( | | |
| 1547 | pad_len * 8, | | |
| 1548 | 8, | | |
| 1549 | try o.lowerDebugType(Type.u8, .full), | | |
| 1550 | @intCast(c_int, pad_len), | | |
| 1551 | ); | | |
| 1552 | len += 1; | | |
| 1553 | } | 1533 | } |
| 1554 | | 1534 | |
| | 1535 | var fields: [2]*llvm.DIType = undefined; |
| | 1536 | fields[error_index] = dib.createMemberType( |
| | 1537 | fwd_decl.toScope(), |
| | 1538 | "tag", |
| | 1539 | di_file, |
| | 1540 | line, |
| | 1541 | error_size * 8, // size in bits |
| | 1542 | error_align * 8, // align in bits |
| | 1543 | error_offset * 8, // offset in bits |
| | 1544 | 0, // flags |
| | 1545 | try o.lowerDebugType(Type.anyerror, .full), |
| | 1546 | ); |
| | 1547 | fields[payload_index] = dib.createMemberType( |
| | 1548 | fwd_decl.toScope(), |
| | 1549 | "value", |
| | 1550 | di_file, |
| | 1551 | line, |
| | 1552 | payload_size * 8, // size in bits |
| | 1553 | payload_align * 8, // align in bits |
| | 1554 | payload_offset * 8, // offset in bits |
| | 1555 | 0, // flags |
| | 1556 | try o.lowerDebugType(payload_ty, .full), |
| | 1557 | ); |
| | 1558 | |
| 1555 | const full_di_ty = dib.createStructType( | 1559 | const full_di_ty = dib.createStructType( |
| 1556 | compile_unit_scope, | 1560 | compile_unit_scope, |
| 1557 | name.ptr, | 1561 | name.ptr, |
| ... | @@ -1562,7 +1566,7 @@ pub const Object = struct { | ... | @@ -1562,7 +1566,7 @@ pub const Object = struct { |
| 1562 | 0, // flags | 1566 | 0, // flags |
| 1563 | null, // derived from | 1567 | null, // derived from |
| 1564 | &fields, | 1568 | &fields, |
| 1565 | len, | 1569 | fields.len, |
| 1566 | 0, // run time lang | 1570 | 0, // run time lang |
| 1567 | null, // vtable holder | 1571 | null, // vtable holder |
| 1568 | "", // unique id | 1572 | "", // unique id |
| ... | @@ -2455,18 +2459,23 @@ pub const DeclGen = struct { | ... | @@ -2455,18 +2459,23 @@ pub const DeclGen = struct { |
| 2455 | return dg.context.structType(&fields, fields.len, .False); | 2459 | return dg.context.structType(&fields, fields.len, .False); |
| 2456 | }, | 2460 | }, |
| 2457 | .ErrorUnion => { | 2461 | .ErrorUnion => { |
| 2458 | const error_type = t.errorUnionSet(); | 2462 | const payload_ty = t.errorUnionPayload(); |
| 2459 | const payload_type = t.errorUnionPayload(); | 2463 | switch (t.errorUnionSet().errorSetCardinality()) { |
| 2460 | if (error_type.errorSetCardinality() == .zero) { | 2464 | .zero => return dg.lowerType(payload_ty), |
| 2461 | return dg.lowerType(payload_type); | 2465 | .one => { |
| | 2466 | if (payload_ty.isNoReturn()) { |
| | 2467 | return dg.context.voidType(); |
| | 2468 | } |
| | 2469 | }, |
| | 2470 | .many => {}, |
| 2462 | } | 2471 | } |
| 2463 | if (!payload_type.hasRuntimeBitsIgnoreComptime()) { | 2472 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 2464 | return try dg.lowerType(Type.anyerror); | 2473 | return try dg.lowerType(Type.anyerror); |
| 2465 | } | 2474 | } |
| 2466 | const llvm_error_type = try dg.lowerType(error_type); | 2475 | const llvm_error_type = try dg.lowerType(Type.anyerror); |
| 2467 | const llvm_payload_type = try dg.lowerType(payload_type); | 2476 | const llvm_payload_type = try dg.lowerType(payload_ty); |
| 2468 | | 2477 | |
| 2469 | const payload_align = payload_type.abiAlignment(target); | 2478 | const payload_align = payload_ty.abiAlignment(target); |
| 2470 | const error_align = Type.anyerror.abiAlignment(target); | 2479 | const error_align = Type.anyerror.abiAlignment(target); |
| 2471 | if (error_align > payload_align) { | 2480 | if (error_align > payload_align) { |
| 2472 | const fields: [2]*const llvm.Type = .{ llvm_error_type, llvm_payload_type }; | 2481 | const fields: [2]*const llvm.Type = .{ llvm_error_type, llvm_payload_type }; |
| ... | @@ -2476,9 +2485,7 @@ pub const DeclGen = struct { | ... | @@ -2476,9 +2485,7 @@ pub const DeclGen = struct { |
| 2476 | return dg.context.structType(&fields, fields.len, .False); | 2485 | return dg.context.structType(&fields, fields.len, .False); |
| 2477 | } | 2486 | } |
| 2478 | }, | 2487 | }, |
| 2479 | .ErrorSet => { | 2488 | .ErrorSet => return dg.context.intType(16), |
| 2480 | return dg.context.intType(16); | | |
| 2481 | }, | | |
| 2482 | .Struct => { | 2489 | .Struct => { |
| 2483 | const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .mod = dg.module }); | 2490 | const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .mod = dg.module }); |
| 2484 | if (gop.found_existing) return gop.value_ptr.*; | 2491 | if (gop.found_existing) return gop.value_ptr.*; |
| ... | @@ -3095,7 +3102,7 @@ pub const DeclGen = struct { | ... | @@ -3095,7 +3102,7 @@ pub const DeclGen = struct { |
| 3095 | return dg.resolveLlvmFunction(fn_decl_index); | 3102 | return dg.resolveLlvmFunction(fn_decl_index); |
| 3096 | }, | 3103 | }, |
| 3097 | .ErrorSet => { | 3104 | .ErrorSet => { |
| 3098 | const llvm_ty = try dg.lowerType(tv.ty); | 3105 | const llvm_ty = try dg.lowerType(Type.anyerror); |
| 3099 | switch (tv.val.tag()) { | 3106 | switch (tv.val.tag()) { |
| 3100 | .@"error" => { | 3107 | .@"error" => { |
| 3101 | const err_name = tv.val.castTag(.@"error").?.data.name; | 3108 | const err_name = tv.val.castTag(.@"error").?.data.name; |
| ... | @@ -3109,9 +3116,8 @@ pub const DeclGen = struct { | ... | @@ -3109,9 +3116,8 @@ pub const DeclGen = struct { |
| 3109 | } | 3116 | } |
| 3110 | }, | 3117 | }, |
| 3111 | .ErrorUnion => { | 3118 | .ErrorUnion => { |
| 3112 | const error_type = tv.ty.errorUnionSet(); | | |
| 3113 | const payload_type = tv.ty.errorUnionPayload(); | 3119 | const payload_type = tv.ty.errorUnionPayload(); |
| 3114 | if (error_type.errorSetCardinality() == .zero) { | 3120 | if (tv.ty.errorUnionSet().errorSetCardinality() == .zero) { |
| 3115 | const payload_val = tv.val.castTag(.eu_payload).?.data; | 3121 | const payload_val = tv.val.castTag(.eu_payload).?.data; |
| 3116 | return dg.lowerValue(.{ .ty = payload_type, .val = payload_val }); | 3122 | return dg.lowerValue(.{ .ty = payload_type, .val = payload_val }); |
| 3117 | } | 3123 | } |
| ... | @@ -3120,13 +3126,13 @@ pub const DeclGen = struct { | ... | @@ -3120,13 +3126,13 @@ pub const DeclGen = struct { |
| 3120 | if (!payload_type.hasRuntimeBitsIgnoreComptime()) { | 3126 | if (!payload_type.hasRuntimeBitsIgnoreComptime()) { |
| 3121 | // We use the error type directly as the type. | 3127 | // We use the error type directly as the type. |
| 3122 | const err_val = if (!is_pl) tv.val else Value.initTag(.zero); | 3128 | const err_val = if (!is_pl) tv.val else Value.initTag(.zero); |
| 3123 | return dg.lowerValue(.{ .ty = error_type, .val = err_val }); | 3129 | return dg.lowerValue(.{ .ty = Type.anyerror, .val = err_val }); |
| 3124 | } | 3130 | } |
| 3125 | | 3131 | |
| 3126 | const payload_align = payload_type.abiAlignment(target); | 3132 | const payload_align = payload_type.abiAlignment(target); |
| 3127 | const error_align = Type.anyerror.abiAlignment(target); | 3133 | const error_align = Type.anyerror.abiAlignment(target); |
| 3128 | const llvm_error_value = try dg.lowerValue(.{ | 3134 | const llvm_error_value = try dg.lowerValue(.{ |
| 3129 | .ty = error_type, | 3135 | .ty = Type.anyerror, |
| 3130 | .val = if (is_pl) Value.initTag(.zero) else tv.val, | 3136 | .val = if (is_pl) Value.initTag(.zero) else tv.val, |
| 3131 | }); | 3137 | }); |
| 3132 | const llvm_payload_value = try dg.lowerValue(.{ | 3138 | const llvm_payload_value = try dg.lowerValue(.{ |
| ... | @@ -5656,13 +5662,12 @@ pub const FuncGen = struct { | ... | @@ -5656,13 +5662,12 @@ pub const FuncGen = struct { |
| 5656 | const operand = try self.resolveInst(ty_op.operand); | 5662 | const operand = try self.resolveInst(ty_op.operand); |
| 5657 | const error_union_ty = self.air.typeOf(ty_op.operand).childType(); | 5663 | const error_union_ty = self.air.typeOf(ty_op.operand).childType(); |
| 5658 | | 5664 | |
| 5659 | const error_ty = error_union_ty.errorUnionSet(); | 5665 | if (error_union_ty.errorUnionSet().errorSetCardinality() == .zero) { |
| 5660 | if (error_ty.errorSetCardinality() == .zero) { | | |
| 5661 | // TODO: write undefined bytes through the pointer here | 5666 | // TODO: write undefined bytes through the pointer here |
| 5662 | return operand; | 5667 | return operand; |
| 5663 | } | 5668 | } |
| 5664 | const payload_ty = error_union_ty.errorUnionPayload(); | 5669 | const payload_ty = error_union_ty.errorUnionPayload(); |
| 5665 | const non_error_val = try self.dg.lowerValue(.{ .ty = error_ty, .val = Value.zero }); | 5670 | const non_error_val = try self.dg.lowerValue(.{ .ty = Type.anyerror, .val = Value.zero }); |
| 5666 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { | 5671 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 5667 | _ = self.builder.buildStore(non_error_val, operand); | 5672 | _ = self.builder.buildStore(non_error_val, operand); |
| 5668 | return operand; | 5673 | return operand; |
| ... | @@ -6715,9 +6720,9 @@ pub const FuncGen = struct { | ... | @@ -6715,9 +6720,9 @@ pub const FuncGen = struct { |
| 6715 | if (self.liveness.isUnused(inst)) return null; | 6720 | if (self.liveness.isUnused(inst)) return null; |
| 6716 | | 6721 | |
| 6717 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 6722 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 6718 | const operand = try self.resolveInst(ty_op.operand); | | |
| 6719 | const operand_ty = self.air.typeOf(ty_op.operand); | 6723 | const operand_ty = self.air.typeOf(ty_op.operand); |
| 6720 | const inst_ty = self.air.typeOfIndex(inst); | 6724 | const inst_ty = self.air.typeOfIndex(inst); |
| | 6725 | const operand = try self.resolveInst(ty_op.operand); |
| 6721 | const operand_is_ref = isByRef(operand_ty); | 6726 | const operand_is_ref = isByRef(operand_ty); |
| 6722 | const result_is_ref = isByRef(inst_ty); | 6727 | const result_is_ref = isByRef(inst_ty); |
| 6723 | const llvm_dest_ty = try self.dg.lowerType(inst_ty); | 6728 | const llvm_dest_ty = try self.dg.lowerType(inst_ty); |