| ... | ... | @@ -23,7 +23,7 @@ const libcFloatSuffix = target_util.libcFloatSuffix; |
| 23 | 23 | const compilerRtFloatAbbrev = target_util.compilerRtFloatAbbrev; |
| 24 | 24 | const compilerRtIntAbbrev = target_util.compilerRtIntAbbrev; |
| 25 | 25 | |
| 26 | | const Mutability = enum { Const, ConstArgument, Mut }; |
| 26 | const Mutability = enum { @"const", mut }; |
| 27 | 27 | const BigIntLimb = std.math.big.Limb; |
| 28 | 28 | const BigInt = std.math.big.int; |
| 29 | 29 | |
| ... | ... | @@ -63,12 +63,17 @@ const TypedefKind = enum { |
| 63 | 63 | }; |
| 64 | 64 | |
| 65 | 65 | pub const CValueMap = std.AutoHashMap(Air.Inst.Ref, CValue); |
| 66 | | pub const TypedefMap = std.ArrayHashMap( |
| 67 | | Type, |
| 68 | | struct { name: []const u8, rendered: []u8 }, |
| 69 | | Type.HashContext32, |
| 70 | | true, |
| 71 | | ); |
| 66 | |
| 67 | pub const LazyFnKey = union(enum) { |
| 68 | tag_name: Decl.Index, |
| 69 | }; |
| 70 | pub const LazyFnValue = struct { |
| 71 | fn_name: []const u8, |
| 72 | data: union { |
| 73 | tag_name: Type, |
| 74 | }, |
| 75 | }; |
| 76 | pub const LazyFnMap = std.AutoArrayHashMapUnmanaged(LazyFnKey, LazyFnValue); |
| 72 | 77 | |
| 73 | 78 | const LoopDepth = u16; |
| 74 | 79 | const Local = struct { |
| ... | ... | @@ -83,11 +88,6 @@ const LocalsList = std.ArrayListUnmanaged(LocalIndex); |
| 83 | 88 | const LocalsMap = std.ArrayHashMapUnmanaged(Type, LocalsList, Type.HashContext32, true); |
| 84 | 89 | const LocalsStack = std.ArrayListUnmanaged(LocalsMap); |
| 85 | 90 | |
| 86 | | const FormatTypeAsCIdentContext = struct { |
| 87 | | ty: Type, |
| 88 | | mod: *Module, |
| 89 | | }; |
| 90 | | |
| 91 | 91 | const ValueRenderLocation = enum { |
| 92 | 92 | FunctionArgument, |
| 93 | 93 | Initializer, |
| ... | ... | @@ -108,26 +108,6 @@ const BuiltinInfo = enum { |
| 108 | 108 | Bits, |
| 109 | 109 | }; |
| 110 | 110 | |
| 111 | | fn formatTypeAsCIdentifier( |
| 112 | | data: FormatTypeAsCIdentContext, |
| 113 | | comptime fmt: []const u8, |
| 114 | | options: std.fmt.FormatOptions, |
| 115 | | writer: anytype, |
| 116 | | ) !void { |
| 117 | | var stack = std.heap.stackFallback(128, data.mod.gpa); |
| 118 | | const allocator = stack.get(); |
| 119 | | const str = std.fmt.allocPrint(allocator, "{}", .{data.ty.fmt(data.mod)}) catch ""; |
| 120 | | defer allocator.free(str); |
| 121 | | return formatIdent(str, fmt, options, writer); |
| 122 | | } |
| 123 | | |
| 124 | | pub fn typeToCIdentifier(ty: Type, mod: *Module) std.fmt.Formatter(formatTypeAsCIdentifier) { |
| 125 | | return .{ .data = .{ |
| 126 | | .ty = ty, |
| 127 | | .mod = mod, |
| 128 | | } }; |
| 129 | | } |
| 130 | | |
| 131 | 111 | const reserved_idents = std.ComptimeStringMap(void, .{ |
| 132 | 112 | // C language |
| 133 | 113 | .{ "alignas", { |
| ... | ... | @@ -283,6 +263,7 @@ pub const Function = struct { |
| 283 | 263 | next_arg_index: usize = 0, |
| 284 | 264 | next_block_index: usize = 0, |
| 285 | 265 | object: Object, |
| 266 | lazy_fns: LazyFnMap, |
| 286 | 267 | func: *Module.Fn, |
| 287 | 268 | /// All the locals, to be emitted at the top of the function. |
| 288 | 269 | locals: std.ArrayListUnmanaged(Local) = .{}, |
| ... | ... | @@ -319,7 +300,7 @@ pub const Function = struct { |
| 319 | 300 | const gpa = f.object.dg.gpa; |
| 320 | 301 | try f.allocs.put(gpa, decl_c_value.local, true); |
| 321 | 302 | try writer.writeAll("static "); |
| 322 | | try f.object.dg.renderTypeAndName(writer, ty, decl_c_value, .Const, alignment, .Complete); |
| 303 | try f.object.dg.renderTypeAndName(writer, ty, decl_c_value, .@"const", alignment, .Complete); |
| 323 | 304 | try writer.writeAll(" = "); |
| 324 | 305 | try f.object.dg.renderValue(writer, ty, val, .StaticInitializer); |
| 325 | 306 | try writer.writeAll(";\n "); |
| ... | ... | @@ -353,7 +334,7 @@ pub const Function = struct { |
| 353 | 334 | } |
| 354 | 335 | |
| 355 | 336 | fn allocLocal(f: *Function, inst: Air.Inst.Index, ty: Type) !CValue { |
| 356 | | const result = try f.allocAlignedLocal(ty, .Mut, 0); |
| 337 | const result = try f.allocAlignedLocal(ty, .mut, 0); |
| 357 | 338 | log.debug("%{d}: allocating t{d}", .{ inst, result.local }); |
| 358 | 339 | return result; |
| 359 | 340 | } |
| ... | ... | @@ -448,6 +429,29 @@ pub const Function = struct { |
| 448 | 429 | return f.object.dg.fmtIntLiteral(ty, val); |
| 449 | 430 | } |
| 450 | 431 | |
| 432 | fn getTagNameFn(f: *Function, enum_ty: Type) ![]const u8 { |
| 433 | const gpa = f.object.dg.gpa; |
| 434 | const owner_decl = enum_ty.getOwnerDecl(); |
| 435 | |
| 436 | const gop = try f.lazy_fns.getOrPut(gpa, .{ .tag_name = owner_decl }); |
| 437 | if (!gop.found_existing) { |
| 438 | errdefer _ = f.lazy_fns.pop(); |
| 439 | |
| 440 | var promoted = f.object.dg.ctypes.promote(gpa); |
| 441 | defer f.object.dg.ctypes.demote(promoted); |
| 442 | const arena = promoted.arena.allocator(); |
| 443 | |
| 444 | gop.value_ptr.* = .{ |
| 445 | .fn_name = try std.fmt.allocPrint(arena, "zig_tagName_{}__{d}", .{ |
| 446 | fmtIdent(mem.span(f.object.dg.module.declPtr(owner_decl).name)), |
| 447 | @enumToInt(owner_decl), |
| 448 | }), |
| 449 | .data = .{ .tag_name = try enum_ty.copy(arena) }, |
| 450 | }; |
| 451 | } |
| 452 | return gop.value_ptr.fn_name; |
| 453 | } |
| 454 | |
| 451 | 455 | pub fn deinit(f: *Function) void { |
| 452 | 456 | const gpa = f.object.dg.gpa; |
| 453 | 457 | f.allocs.deinit(gpa); |
| ... | ... | @@ -458,11 +462,8 @@ pub const Function = struct { |
| 458 | 462 | f.free_locals_stack.deinit(gpa); |
| 459 | 463 | f.blocks.deinit(gpa); |
| 460 | 464 | f.value_map.deinit(); |
| 465 | f.lazy_fns.deinit(gpa); |
| 461 | 466 | f.object.code.deinit(); |
| 462 | | for (f.object.dg.typedefs.values()) |typedef| { |
| 463 | | gpa.free(typedef.rendered); |
| 464 | | } |
| 465 | | f.object.dg.typedefs.deinit(); |
| 466 | 467 | f.object.dg.ctypes.deinit(gpa); |
| 467 | 468 | f.object.dg.fwd_decl.deinit(); |
| 468 | 469 | f.arena.deinit(); |
| ... | ... | @@ -492,9 +493,6 @@ pub const DeclGen = struct { |
| 492 | 493 | fwd_decl: std.ArrayList(u8), |
| 493 | 494 | error_msg: ?*Module.ErrorMsg, |
| 494 | 495 | ctypes: CType.Store, |
| 495 | | /// The key of this map is Type which has references to typedefs_arena. |
| 496 | | typedefs: TypedefMap, |
| 497 | | typedefs_arena: std.mem.Allocator, |
| 498 | 496 | |
| 499 | 497 | fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } { |
| 500 | 498 | @setCold(true); |
| ... | ... | @@ -504,14 +502,6 @@ pub const DeclGen = struct { |
| 504 | 502 | return error.AnalysisFail; |
| 505 | 503 | } |
| 506 | 504 | |
| 507 | | fn getTypedefName(dg: *DeclGen, t: Type) ?[]const u8 { |
| 508 | | if (dg.typedefs.get(t)) |typedef| { |
| 509 | | return typedef.name; |
| 510 | | } else { |
| 511 | | return null; |
| 512 | | } |
| 513 | | } |
| 514 | | |
| 515 | 505 | fn renderDeclValue( |
| 516 | 506 | dg: *DeclGen, |
| 517 | 507 | writer: anytype, |
| ... | ... | @@ -1493,7 +1483,7 @@ pub const DeclGen = struct { |
| 1493 | 1483 | if (!param_type.hasRuntimeBitsIgnoreComptime()) continue; |
| 1494 | 1484 | if (index > 0) try w.writeAll(", "); |
| 1495 | 1485 | const name = CValue{ .arg = index }; |
| 1496 | | try dg.renderTypeAndName(w, param_type, name, .ConstArgument, 0, kind); |
| 1486 | try dg.renderTypeAndName(w, param_type, name, .@"const", 0, kind); |
| 1497 | 1487 | index += 1; |
| 1498 | 1488 | } |
| 1499 | 1489 | |
| ... | ... | @@ -1507,453 +1497,6 @@ pub const DeclGen = struct { |
| 1507 | 1497 | if (fn_info.alignment > 0 and kind == .Forward) try w.print(" zig_align_fn({})", .{fn_info.alignment}); |
| 1508 | 1498 | } |
| 1509 | 1499 | |
| 1510 | | fn renderPtrToFnTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { |
| 1511 | | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); |
| 1512 | | defer buffer.deinit(); |
| 1513 | | const bw = buffer.writer(); |
| 1514 | | |
| 1515 | | const fn_info = t.fnInfo(); |
| 1516 | | |
| 1517 | | const target = dg.module.getTarget(); |
| 1518 | | var ret_buf: LowerFnRetTyBuffer = undefined; |
| 1519 | | const ret_ty = lowerFnRetTy(fn_info.return_type, &ret_buf, target); |
| 1520 | | |
| 1521 | | try bw.writeAll("typedef "); |
| 1522 | | try dg.renderType(bw, ret_ty, .Forward); |
| 1523 | | try bw.writeAll(" (*"); |
| 1524 | | const name_begin = buffer.items.len; |
| 1525 | | try bw.print("zig_F_{}", .{typeToCIdentifier(t, dg.module)}); |
| 1526 | | const name_end = buffer.items.len; |
| 1527 | | try bw.writeAll(")("); |
| 1528 | | |
| 1529 | | const param_len = fn_info.param_types.len; |
| 1530 | | |
| 1531 | | var params_written: usize = 0; |
| 1532 | | var index: usize = 0; |
| 1533 | | while (index < param_len) : (index += 1) { |
| 1534 | | const param_ty = fn_info.param_types[index]; |
| 1535 | | if (!param_ty.hasRuntimeBitsIgnoreComptime()) continue; |
| 1536 | | if (params_written > 0) { |
| 1537 | | try bw.writeAll(", "); |
| 1538 | | } |
| 1539 | | try dg.renderTypeAndName(bw, param_ty, .{ .bytes = "" }, .Mut, 0, .Forward); |
| 1540 | | params_written += 1; |
| 1541 | | } |
| 1542 | | |
| 1543 | | if (fn_info.is_var_args) { |
| 1544 | | if (params_written != 0) try bw.writeAll(", "); |
| 1545 | | try bw.writeAll("..."); |
| 1546 | | } else if (params_written == 0) { |
| 1547 | | try dg.renderType(bw, Type.void, .Forward); |
| 1548 | | } |
| 1549 | | try bw.writeAll(");\n"); |
| 1550 | | |
| 1551 | | const rendered = try buffer.toOwnedSlice(); |
| 1552 | | errdefer dg.typedefs.allocator.free(rendered); |
| 1553 | | const name = rendered[name_begin..name_end]; |
| 1554 | | |
| 1555 | | try dg.typedefs.ensureUnusedCapacity(1); |
| 1556 | | dg.typedefs.putAssumeCapacityNoClobber( |
| 1557 | | try t.copy(dg.typedefs_arena), |
| 1558 | | .{ .name = name, .rendered = rendered }, |
| 1559 | | ); |
| 1560 | | |
| 1561 | | return name; |
| 1562 | | } |
| 1563 | | |
| 1564 | | fn renderSliceTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { |
| 1565 | | std.debug.assert(t.sentinel() == null); // expected canonical type |
| 1566 | | |
| 1567 | | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); |
| 1568 | | defer buffer.deinit(); |
| 1569 | | const bw = buffer.writer(); |
| 1570 | | |
| 1571 | | var ptr_ty_buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| 1572 | | const ptr_ty = t.slicePtrFieldType(&ptr_ty_buf); |
| 1573 | | const ptr_name = CValue{ .identifier = "ptr" }; |
| 1574 | | const len_ty = Type.usize; |
| 1575 | | const len_name = CValue{ .identifier = "len" }; |
| 1576 | | |
| 1577 | | try bw.writeAll("typedef struct {\n "); |
| 1578 | | try dg.renderTypeAndName(bw, ptr_ty, ptr_name, .Mut, 0, .Complete); |
| 1579 | | try bw.writeAll(";\n "); |
| 1580 | | try dg.renderTypeAndName(bw, len_ty, len_name, .Mut, 0, .Complete); |
| 1581 | | |
| 1582 | | try bw.writeAll(";\n} "); |
| 1583 | | const name_begin = buffer.items.len; |
| 1584 | | try bw.print("zig_{c}_{}", .{ |
| 1585 | | @as(u8, if (t.isConstPtr()) 'L' else 'M'), |
| 1586 | | typeToCIdentifier(t.childType(), dg.module), |
| 1587 | | }); |
| 1588 | | const name_end = buffer.items.len; |
| 1589 | | try bw.writeAll(";\n"); |
| 1590 | | |
| 1591 | | const rendered = try buffer.toOwnedSlice(); |
| 1592 | | errdefer dg.typedefs.allocator.free(rendered); |
| 1593 | | const name = rendered[name_begin..name_end]; |
| 1594 | | |
| 1595 | | try dg.typedefs.ensureUnusedCapacity(1); |
| 1596 | | dg.typedefs.putAssumeCapacityNoClobber( |
| 1597 | | try t.copy(dg.typedefs_arena), |
| 1598 | | .{ .name = name, .rendered = rendered }, |
| 1599 | | ); |
| 1600 | | |
| 1601 | | return name; |
| 1602 | | } |
| 1603 | | |
| 1604 | | fn renderFwdTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { |
| 1605 | | // The forward declaration for T is stored with a key of *const T. |
| 1606 | | const child_ty = t.childType(); |
| 1607 | | |
| 1608 | | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); |
| 1609 | | defer buffer.deinit(); |
| 1610 | | const bw = buffer.writer(); |
| 1611 | | |
| 1612 | | const tag = switch (child_ty.zigTypeTag()) { |
| 1613 | | .Struct, .ErrorUnion, .Optional => "struct", |
| 1614 | | .Union => if (child_ty.unionTagTypeSafety()) |_| "struct" else "union", |
| 1615 | | else => unreachable, |
| 1616 | | }; |
| 1617 | | try bw.writeAll("typedef "); |
| 1618 | | try bw.writeAll(tag); |
| 1619 | | const name_begin = buffer.items.len + " ".len; |
| 1620 | | try bw.writeAll(" zig_"); |
| 1621 | | switch (child_ty.zigTypeTag()) { |
| 1622 | | .Struct, .Union => { |
| 1623 | | var fqn_buf = std.ArrayList(u8).init(dg.typedefs.allocator); |
| 1624 | | defer fqn_buf.deinit(); |
| 1625 | | |
| 1626 | | const owner_decl_index = child_ty.getOwnerDecl(); |
| 1627 | | const owner_decl = dg.module.declPtr(owner_decl_index); |
| 1628 | | try owner_decl.renderFullyQualifiedName(dg.module, fqn_buf.writer()); |
| 1629 | | |
| 1630 | | try bw.print("S_{}__{d}", .{ fmtIdent(fqn_buf.items), @enumToInt(owner_decl_index) }); |
| 1631 | | }, |
| 1632 | | .ErrorUnion => { |
| 1633 | | try bw.print("E_{}", .{typeToCIdentifier(child_ty.errorUnionPayload(), dg.module)}); |
| 1634 | | }, |
| 1635 | | .Optional => { |
| 1636 | | var opt_buf: Type.Payload.ElemType = undefined; |
| 1637 | | try bw.print("Q_{}", .{typeToCIdentifier(child_ty.optionalChild(&opt_buf), dg.module)}); |
| 1638 | | }, |
| 1639 | | else => unreachable, |
| 1640 | | } |
| 1641 | | const name_end = buffer.items.len; |
| 1642 | | try buffer.ensureUnusedCapacity(" ".len + (name_end - name_begin) + ";\n".len); |
| 1643 | | buffer.appendAssumeCapacity(' '); |
| 1644 | | buffer.appendSliceAssumeCapacity(buffer.items[name_begin..name_end]); |
| 1645 | | buffer.appendSliceAssumeCapacity(";\n"); |
| 1646 | | |
| 1647 | | const rendered = try buffer.toOwnedSlice(); |
| 1648 | | errdefer dg.typedefs.allocator.free(rendered); |
| 1649 | | const name = rendered[name_begin..name_end]; |
| 1650 | | |
| 1651 | | try dg.typedefs.ensureUnusedCapacity(1); |
| 1652 | | dg.typedefs.putAssumeCapacityNoClobber( |
| 1653 | | try t.copy(dg.typedefs_arena), |
| 1654 | | .{ .name = name, .rendered = rendered }, |
| 1655 | | ); |
| 1656 | | |
| 1657 | | return name; |
| 1658 | | } |
| 1659 | | |
| 1660 | | fn renderStructTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { |
| 1661 | | var ptr_pl = Type.Payload.ElemType{ .base = .{ .tag = .single_const_pointer }, .data = t }; |
| 1662 | | const ptr_ty = Type.initPayload(&ptr_pl.base); |
| 1663 | | const name = dg.getTypedefName(ptr_ty) orelse |
| 1664 | | try dg.renderFwdTypedef(ptr_ty); |
| 1665 | | |
| 1666 | | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); |
| 1667 | | defer buffer.deinit(); |
| 1668 | | |
| 1669 | | try buffer.appendSlice("struct "); |
| 1670 | | |
| 1671 | | var needs_pack_attr = false; |
| 1672 | | { |
| 1673 | | var it = t.structFields().iterator(); |
| 1674 | | while (it.next()) |field| { |
| 1675 | | const field_ty = field.value_ptr.ty; |
| 1676 | | if (!field_ty.hasRuntimeBits()) continue; |
| 1677 | | const alignment = field.value_ptr.abi_align; |
| 1678 | | if (alignment != 0 and alignment < field_ty.abiAlignment(dg.module.getTarget())) { |
| 1679 | | needs_pack_attr = true; |
| 1680 | | try buffer.appendSlice("zig_packed("); |
| 1681 | | break; |
| 1682 | | } |
| 1683 | | } |
| 1684 | | } |
| 1685 | | |
| 1686 | | try buffer.appendSlice(name); |
| 1687 | | try buffer.appendSlice(" {\n"); |
| 1688 | | { |
| 1689 | | var it = t.structFields().iterator(); |
| 1690 | | var empty = true; |
| 1691 | | while (it.next()) |field| { |
| 1692 | | const field_ty = field.value_ptr.ty; |
| 1693 | | if (!field_ty.hasRuntimeBits()) continue; |
| 1694 | | |
| 1695 | | const alignment = field.value_ptr.alignment(dg.module.getTarget(), t.containerLayout()); |
| 1696 | | const field_name = CValue{ .identifier = field.key_ptr.* }; |
| 1697 | | try buffer.append(' '); |
| 1698 | | try dg.renderTypeAndName(buffer.writer(), field_ty, field_name, .Mut, alignment, .Complete); |
| 1699 | | try buffer.appendSlice(";\n"); |
| 1700 | | |
| 1701 | | empty = false; |
| 1702 | | } |
| 1703 | | if (empty) try buffer.appendSlice(" char empty_struct;\n"); |
| 1704 | | } |
| 1705 | | if (needs_pack_attr) try buffer.appendSlice("});\n") else try buffer.appendSlice("};\n"); |
| 1706 | | |
| 1707 | | const rendered = try buffer.toOwnedSlice(); |
| 1708 | | errdefer dg.typedefs.allocator.free(rendered); |
| 1709 | | |
| 1710 | | try dg.typedefs.ensureUnusedCapacity(1); |
| 1711 | | dg.typedefs.putAssumeCapacityNoClobber( |
| 1712 | | try t.copy(dg.typedefs_arena), |
| 1713 | | .{ .name = name, .rendered = rendered }, |
| 1714 | | ); |
| 1715 | | |
| 1716 | | return name; |
| 1717 | | } |
| 1718 | | |
| 1719 | | fn renderTupleTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { |
| 1720 | | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); |
| 1721 | | defer buffer.deinit(); |
| 1722 | | |
| 1723 | | try buffer.appendSlice("typedef struct {\n"); |
| 1724 | | { |
| 1725 | | const fields = t.tupleFields(); |
| 1726 | | var field_id: usize = 0; |
| 1727 | | for (fields.types, 0..) |field_ty, i| { |
| 1728 | | if (!field_ty.hasRuntimeBits() or fields.values[i].tag() != .unreachable_value) continue; |
| 1729 | | |
| 1730 | | try buffer.append(' '); |
| 1731 | | try dg.renderTypeAndName(buffer.writer(), field_ty, .{ .field = field_id }, .Mut, 0, .Complete); |
| 1732 | | try buffer.appendSlice(";\n"); |
| 1733 | | |
| 1734 | | field_id += 1; |
| 1735 | | } |
| 1736 | | if (field_id == 0) try buffer.appendSlice(" char empty_tuple;\n"); |
| 1737 | | } |
| 1738 | | const name_begin = buffer.items.len + "} ".len; |
| 1739 | | try buffer.writer().print("}} zig_T_{}_{d};\n", .{ typeToCIdentifier(t, dg.module), @truncate(u16, t.hash(dg.module)) }); |
| 1740 | | const name_end = buffer.items.len - ";\n".len; |
| 1741 | | |
| 1742 | | const rendered = try buffer.toOwnedSlice(); |
| 1743 | | errdefer dg.typedefs.allocator.free(rendered); |
| 1744 | | const name = rendered[name_begin..name_end]; |
| 1745 | | |
| 1746 | | try dg.typedefs.ensureUnusedCapacity(1); |
| 1747 | | dg.typedefs.putAssumeCapacityNoClobber( |
| 1748 | | try t.copy(dg.typedefs_arena), |
| 1749 | | .{ .name = name, .rendered = rendered }, |
| 1750 | | ); |
| 1751 | | |
| 1752 | | return name; |
| 1753 | | } |
| 1754 | | |
| 1755 | | fn renderUnionTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { |
| 1756 | | var ptr_pl = Type.Payload.ElemType{ .base = .{ .tag = .single_const_pointer }, .data = t }; |
| 1757 | | const ptr_ty = Type.initPayload(&ptr_pl.base); |
| 1758 | | const name = dg.getTypedefName(ptr_ty) orelse |
| 1759 | | try dg.renderFwdTypedef(ptr_ty); |
| 1760 | | |
| 1761 | | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); |
| 1762 | | defer buffer.deinit(); |
| 1763 | | |
| 1764 | | try buffer.appendSlice(if (t.unionTagTypeSafety()) |_| "struct " else "union "); |
| 1765 | | try buffer.appendSlice(name); |
| 1766 | | try buffer.appendSlice(" {\n"); |
| 1767 | | |
| 1768 | | const indent = if (t.unionTagTypeSafety()) |tag_ty| indent: { |
| 1769 | | const target = dg.module.getTarget(); |
| 1770 | | const layout = t.unionGetLayout(target); |
| 1771 | | if (layout.tag_size != 0) { |
| 1772 | | try buffer.append(' '); |
| 1773 | | try dg.renderTypeAndName(buffer.writer(), tag_ty, .{ .identifier = "tag" }, .Mut, 0, .Complete); |
| 1774 | | try buffer.appendSlice(";\n"); |
| 1775 | | } |
| 1776 | | try buffer.appendSlice(" union {\n"); |
| 1777 | | break :indent " "; |
| 1778 | | } else " "; |
| 1779 | | |
| 1780 | | { |
| 1781 | | var it = t.unionFields().iterator(); |
| 1782 | | var empty = true; |
| 1783 | | while (it.next()) |field| { |
| 1784 | | const field_ty = field.value_ptr.ty; |
| 1785 | | if (!field_ty.hasRuntimeBits()) continue; |
| 1786 | | |
| 1787 | | const alignment = field.value_ptr.abi_align; |
| 1788 | | const field_name = CValue{ .identifier = field.key_ptr.* }; |
| 1789 | | try buffer.appendSlice(indent); |
| 1790 | | try dg.renderTypeAndName(buffer.writer(), field_ty, field_name, .Mut, alignment, .Complete); |
| 1791 | | try buffer.appendSlice(";\n"); |
| 1792 | | |
| 1793 | | empty = false; |
| 1794 | | } |
| 1795 | | if (empty) { |
| 1796 | | try buffer.appendSlice(indent); |
| 1797 | | try buffer.appendSlice("char empty_union;\n"); |
| 1798 | | } |
| 1799 | | } |
| 1800 | | |
| 1801 | | if (t.unionTagTypeSafety()) |_| try buffer.appendSlice(" } payload;\n"); |
| 1802 | | try buffer.appendSlice("};\n"); |
| 1803 | | |
| 1804 | | const rendered = try buffer.toOwnedSlice(); |
| 1805 | | errdefer dg.typedefs.allocator.free(rendered); |
| 1806 | | |
| 1807 | | try dg.typedefs.ensureUnusedCapacity(1); |
| 1808 | | dg.typedefs.putAssumeCapacityNoClobber( |
| 1809 | | try t.copy(dg.typedefs_arena), |
| 1810 | | .{ .name = name, .rendered = rendered }, |
| 1811 | | ); |
| 1812 | | |
| 1813 | | return name; |
| 1814 | | } |
| 1815 | | |
| 1816 | | fn renderErrorUnionTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { |
| 1817 | | assert(t.errorUnionSet().tag() == .anyerror); |
| 1818 | | |
| 1819 | | var ptr_pl = Type.Payload.ElemType{ .base = .{ .tag = .single_const_pointer }, .data = t }; |
| 1820 | | const ptr_ty = Type.initPayload(&ptr_pl.base); |
| 1821 | | const name = dg.getTypedefName(ptr_ty) orelse |
| 1822 | | try dg.renderFwdTypedef(ptr_ty); |
| 1823 | | |
| 1824 | | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); |
| 1825 | | defer buffer.deinit(); |
| 1826 | | const bw = buffer.writer(); |
| 1827 | | |
| 1828 | | const payload_ty = t.errorUnionPayload(); |
| 1829 | | const payload_name = CValue{ .identifier = "payload" }; |
| 1830 | | const error_ty = t.errorUnionSet(); |
| 1831 | | const error_name = CValue{ .identifier = "error" }; |
| 1832 | | |
| 1833 | | const target = dg.module.getTarget(); |
| 1834 | | const payload_align = payload_ty.abiAlignment(target); |
| 1835 | | const error_align = error_ty.abiAlignment(target); |
| 1836 | | try bw.writeAll("struct "); |
| 1837 | | try bw.writeAll(name); |
| 1838 | | try bw.writeAll(" {\n "); |
| 1839 | | if (error_align > payload_align) { |
| 1840 | | try dg.renderTypeAndName(bw, payload_ty, payload_name, .Mut, 0, .Complete); |
| 1841 | | try bw.writeAll(";\n "); |
| 1842 | | try dg.renderTypeAndName(bw, error_ty, error_name, .Mut, 0, .Complete); |
| 1843 | | } else { |
| 1844 | | try dg.renderTypeAndName(bw, error_ty, error_name, .Mut, 0, .Complete); |
| 1845 | | try bw.writeAll(";\n "); |
| 1846 | | try dg.renderTypeAndName(bw, payload_ty, payload_name, .Mut, 0, .Complete); |
| 1847 | | } |
| 1848 | | try bw.writeAll(";\n};\n"); |
| 1849 | | |
| 1850 | | const rendered = try buffer.toOwnedSlice(); |
| 1851 | | errdefer dg.typedefs.allocator.free(rendered); |
| 1852 | | |
| 1853 | | try dg.typedefs.ensureUnusedCapacity(1); |
| 1854 | | dg.typedefs.putAssumeCapacityNoClobber( |
| 1855 | | try t.copy(dg.typedefs_arena), |
| 1856 | | .{ .name = name, .rendered = rendered }, |
| 1857 | | ); |
| 1858 | | |
| 1859 | | return name; |
| 1860 | | } |
| 1861 | | |
| 1862 | | fn renderArrayTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { |
| 1863 | | const info = t.arrayInfo(); |
| 1864 | | std.debug.assert(info.sentinel == null); // expected canonical type |
| 1865 | | |
| 1866 | | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); |
| 1867 | | defer buffer.deinit(); |
| 1868 | | const bw = buffer.writer(); |
| 1869 | | |
| 1870 | | try bw.writeAll("typedef "); |
| 1871 | | try dg.renderType(bw, info.elem_type, .Complete); |
| 1872 | | |
| 1873 | | const name_begin = buffer.items.len + " ".len; |
| 1874 | | try bw.print(" zig_A_{}_{d}", .{ typeToCIdentifier(info.elem_type, dg.module), info.len }); |
| 1875 | | const name_end = buffer.items.len; |
| 1876 | | |
| 1877 | | const c_len = if (info.len > 0) info.len else 1; |
| 1878 | | var c_len_pl: Value.Payload.U64 = .{ .base = .{ .tag = .int_u64 }, .data = c_len }; |
| 1879 | | const c_len_val = Value.initPayload(&c_len_pl.base); |
| 1880 | | try bw.print("[{}];\n", .{try dg.fmtIntLiteral(Type.usize, c_len_val)}); |
| 1881 | | |
| 1882 | | const rendered = try buffer.toOwnedSlice(); |
| 1883 | | errdefer dg.typedefs.allocator.free(rendered); |
| 1884 | | const name = rendered[name_begin..name_end]; |
| 1885 | | |
| 1886 | | try dg.typedefs.ensureUnusedCapacity(1); |
| 1887 | | dg.typedefs.putAssumeCapacityNoClobber( |
| 1888 | | try t.copy(dg.typedefs_arena), |
| 1889 | | .{ .name = name, .rendered = rendered }, |
| 1890 | | ); |
| 1891 | | |
| 1892 | | return name; |
| 1893 | | } |
| 1894 | | |
| 1895 | | fn renderOptionalTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { |
| 1896 | | var ptr_pl = Type.Payload.ElemType{ .base = .{ .tag = .single_const_pointer }, .data = t }; |
| 1897 | | const ptr_ty = Type.initPayload(&ptr_pl.base); |
| 1898 | | const name = dg.getTypedefName(ptr_ty) orelse |
| 1899 | | try dg.renderFwdTypedef(ptr_ty); |
| 1900 | | |
| 1901 | | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); |
| 1902 | | defer buffer.deinit(); |
| 1903 | | const bw = buffer.writer(); |
| 1904 | | |
| 1905 | | var opt_buf: Type.Payload.ElemType = undefined; |
| 1906 | | const child_ty = t.optionalChild(&opt_buf); |
| 1907 | | |
| 1908 | | try bw.writeAll("struct "); |
| 1909 | | try bw.writeAll(name); |
| 1910 | | try bw.writeAll(" {\n"); |
| 1911 | | try dg.renderTypeAndName(bw, child_ty, .{ .identifier = "payload" }, .Mut, 0, .Complete); |
| 1912 | | try bw.writeAll(";\n "); |
| 1913 | | try dg.renderTypeAndName(bw, Type.bool, .{ .identifier = "is_null" }, .Mut, 0, .Complete); |
| 1914 | | try bw.writeAll(";\n};\n"); |
| 1915 | | |
| 1916 | | const rendered = try buffer.toOwnedSlice(); |
| 1917 | | errdefer dg.typedefs.allocator.free(rendered); |
| 1918 | | |
| 1919 | | try dg.typedefs.ensureUnusedCapacity(1); |
| 1920 | | dg.typedefs.putAssumeCapacityNoClobber( |
| 1921 | | try t.copy(dg.typedefs_arena), |
| 1922 | | .{ .name = name, .rendered = rendered }, |
| 1923 | | ); |
| 1924 | | |
| 1925 | | return name; |
| 1926 | | } |
| 1927 | | |
| 1928 | | fn renderOpaqueTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { |
| 1929 | | const opaque_ty = t.cast(Type.Payload.Opaque).?.data; |
| 1930 | | const unqualified_name = dg.module.declPtr(opaque_ty.owner_decl).name; |
| 1931 | | const fqn = try opaque_ty.getFullyQualifiedName(dg.module); |
| 1932 | | defer dg.typedefs.allocator.free(fqn); |
| 1933 | | |
| 1934 | | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); |
| 1935 | | defer buffer.deinit(); |
| 1936 | | |
| 1937 | | try buffer.writer().print("typedef struct { } ", .{fmtIdent(std.mem.span(unqualified_name))}); |
| 1938 | | |
| 1939 | | const name_begin = buffer.items.len; |
| 1940 | | try buffer.writer().print("zig_O_{}", .{fmtIdent(fqn)}); |
| 1941 | | const name_end = buffer.items.len; |
| 1942 | | try buffer.appendSlice(";\n"); |
| 1943 | | |
| 1944 | | const rendered = try buffer.toOwnedSlice(); |
| 1945 | | errdefer dg.typedefs.allocator.free(rendered); |
| 1946 | | const name = rendered[name_begin..name_end]; |
| 1947 | | |
| 1948 | | try dg.typedefs.ensureUnusedCapacity(1); |
| 1949 | | dg.typedefs.putAssumeCapacityNoClobber( |
| 1950 | | try t.copy(dg.typedefs_arena), |
| 1951 | | .{ .name = name, .rendered = rendered }, |
| 1952 | | ); |
| 1953 | | |
| 1954 | | return name; |
| 1955 | | } |
| 1956 | | |
| 1957 | 1500 | fn indexToCType(dg: *DeclGen, idx: CType.Index) CType { |
| 1958 | 1501 | return dg.ctypes.indexToCType(idx); |
| 1959 | 1502 | } |
| ... | ... | @@ -2408,31 +1951,27 @@ pub const DeclGen = struct { |
| 2408 | 1951 | const idx = try dg.typeToIndex(ty); |
| 2409 | 1952 | try w.print("{}", .{try dg.renderTypePrefix(w, idx, .suffix, CQualifiers.init(.{ |
| 2410 | 1953 | .@"const" = switch (mutability) { |
| 2411 | | .Const, .ConstArgument => true, |
| 2412 | | .Mut => false, |
| 1954 | .mut => false, |
| 1955 | .@"const" => true, |
| 2413 | 1956 | }, |
| 2414 | 1957 | }))}); |
| 2415 | 1958 | try dg.writeCValue(w, name); |
| 2416 | 1959 | try dg.renderTypeSuffix(w, idx, .suffix); |
| 2417 | 1960 | } |
| 2418 | 1961 | |
| 2419 | | fn renderTagNameFn(dg: *DeclGen, enum_ty: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { |
| 2420 | | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); |
| 2421 | | defer buffer.deinit(); |
| 2422 | | const bw = buffer.writer(); |
| 2423 | | |
| 1962 | fn renderTagNameFn(dg: *DeclGen, w: anytype, fn_name: []const u8, enum_ty: Type) !void { |
| 2424 | 1963 | const name_slice_ty = Type.initTag(.const_slice_u8_sentinel_0); |
| 2425 | 1964 | |
| 2426 | | try buffer.appendSlice("static "); |
| 2427 | | try dg.renderType(bw, name_slice_ty, .Complete); |
| 2428 | | const name_begin = buffer.items.len + " ".len; |
| 2429 | | try bw.print(" zig_tagName_{}_{d}(", .{ typeToCIdentifier(enum_ty, dg.module), @enumToInt(enum_ty.getOwnerDecl()) }); |
| 2430 | | const name_end = buffer.items.len - "(".len; |
| 2431 | | try dg.renderTypeAndName(bw, enum_ty, .{ .identifier = "tag" }, .Const, 0, .Complete); |
| 2432 | | try buffer.appendSlice(") {\n switch (tag) {\n"); |
| 1965 | try w.writeAll("static "); |
| 1966 | try dg.renderType(w, name_slice_ty, .Complete); |
| 1967 | try w.writeByte(' '); |
| 1968 | try w.writeAll(fn_name); |
| 1969 | try w.writeByte('('); |
| 1970 | try dg.renderTypeAndName(w, enum_ty, .{ .identifier = "tag" }, .@"const", 0, .Complete); |
| 1971 | try w.writeAll(") {\n switch (tag) {\n"); |
| 2433 | 1972 | for (enum_ty.enumFields().keys(), 0..) |name, index| { |
| 2434 | | const name_z = try dg.typedefs.allocator.dupeZ(u8, name); |
| 2435 | | defer dg.typedefs.allocator.free(name_z); |
| 1973 | const name_z = try dg.gpa.dupeZ(u8, name); |
| 1974 | defer dg.gpa.free(name_z); |
| 2436 | 1975 | const name_bytes = name_z[0 .. name_z.len + 1]; |
| 2437 | 1976 | |
| 2438 | 1977 | var tag_pl: Value.Payload.U32 = .{ |
| ... | ... | @@ -2453,40 +1992,23 @@ pub const DeclGen = struct { |
| 2453 | 1992 | var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = name.len }; |
| 2454 | 1993 | const len_val = Value.initPayload(&len_pl.base); |
| 2455 | 1994 | |
| 2456 | | try bw.print(" case {}: {{\n static ", .{try dg.fmtIntLiteral(enum_ty, int_val)}); |
| 2457 | | try dg.renderTypeAndName(bw, name_ty, .{ .identifier = "name" }, .Const, 0, .Complete); |
| 2458 | | try buffer.appendSlice(" = "); |
| 2459 | | try dg.renderValue(bw, name_ty, name_val, .Initializer); |
| 2460 | | try buffer.appendSlice(";\n return ("); |
| 2461 | | try dg.renderTypecast(bw, name_slice_ty); |
| 2462 | | try bw.print("){{{}, {}}};\n", .{ |
| 1995 | try w.print(" case {}: {{\n static ", .{try dg.fmtIntLiteral(enum_ty, int_val)}); |
| 1996 | try dg.renderTypeAndName(w, name_ty, .{ .identifier = "name" }, .@"const", 0, .Complete); |
| 1997 | try w.writeAll(" = "); |
| 1998 | try dg.renderValue(w, name_ty, name_val, .Initializer); |
| 1999 | try w.writeAll(";\n return ("); |
| 2000 | try dg.renderTypecast(w, name_slice_ty); |
| 2001 | try w.print("){{{}, {}}};\n", .{ |
| 2463 | 2002 | fmtIdent("name"), try dg.fmtIntLiteral(Type.usize, len_val), |
| 2464 | 2003 | }); |
| 2465 | 2004 | |
| 2466 | | try buffer.appendSlice(" }\n"); |
| 2005 | try w.writeAll(" }\n"); |
| 2467 | 2006 | } |
| 2468 | | try buffer.appendSlice(" }\n while ("); |
| 2469 | | try dg.renderValue(bw, Type.bool, Value.true, .Other); |
| 2470 | | try buffer.appendSlice(") "); |
| 2471 | | _ = try airBreakpoint(bw); |
| 2472 | | try buffer.appendSlice("}\n"); |
| 2473 | | |
| 2474 | | const rendered = try buffer.toOwnedSlice(); |
| 2475 | | errdefer dg.typedefs.allocator.free(rendered); |
| 2476 | | const name = rendered[name_begin..name_end]; |
| 2477 | | |
| 2478 | | try dg.typedefs.ensureUnusedCapacity(1); |
| 2479 | | dg.typedefs.putAssumeCapacityNoClobber( |
| 2480 | | try enum_ty.copy(dg.typedefs_arena), |
| 2481 | | .{ .name = name, .rendered = rendered }, |
| 2482 | | ); |
| 2483 | | |
| 2484 | | return name; |
| 2485 | | } |
| 2486 | | |
| 2487 | | fn getTagNameFn(dg: *DeclGen, enum_ty: Type) ![]const u8 { |
| 2488 | | return dg.getTypedefName(enum_ty) orelse |
| 2489 | | try dg.renderTagNameFn(enum_ty); |
| 2007 | try w.writeAll(" }\n while ("); |
| 2008 | try dg.renderValue(w, Type.bool, Value.true, .Other); |
| 2009 | try w.writeAll(") "); |
| 2010 | _ = try airBreakpoint(w); |
| 2011 | try w.writeAll("}\n"); |
| 2490 | 2012 | } |
| 2491 | 2013 | |
| 2492 | 2014 | fn declIsGlobal(dg: *DeclGen, tv: TypedValue) bool { |
| ... | ... | @@ -2724,7 +2246,7 @@ pub fn genErrDecls(o: *Object) !void { |
| 2724 | 2246 | const name_val = Value.initPayload(&name_pl.base); |
| 2725 | 2247 | |
| 2726 | 2248 | try writer.writeAll("static "); |
| 2727 | | try o.dg.renderTypeAndName(writer, name_ty, .{ .identifier = identifier }, .Const, 0, .Complete); |
| 2249 | try o.dg.renderTypeAndName(writer, name_ty, .{ .identifier = identifier }, .@"const", 0, .Complete); |
| 2728 | 2250 | try writer.writeAll(" = "); |
| 2729 | 2251 | try o.dg.renderValue(writer, name_ty, name_val, .StaticInitializer); |
| 2730 | 2252 | try writer.writeAll(";\n"); |
| ... | ... | @@ -2737,7 +2259,7 @@ pub fn genErrDecls(o: *Object) !void { |
| 2737 | 2259 | const name_array_ty = Type.initPayload(&name_array_ty_pl.base); |
| 2738 | 2260 | |
| 2739 | 2261 | try writer.writeAll("static "); |
| 2740 | | try o.dg.renderTypeAndName(writer, name_array_ty, .{ .identifier = name_prefix }, .Const, 0, .Complete); |
| 2262 | try o.dg.renderTypeAndName(writer, name_array_ty, .{ .identifier = name_prefix }, .@"const", 0, .Complete); |
| 2741 | 2263 | try writer.writeAll(" = {"); |
| 2742 | 2264 | for (o.dg.module.error_name_list.items, 0..) |name, value| { |
| 2743 | 2265 | if (value != 0) try writer.writeByte(','); |
| ... | ... | @@ -2767,6 +2289,17 @@ fn genExports(o: *Object) !void { |
| 2767 | 2289 | }; |
| 2768 | 2290 | } |
| 2769 | 2291 | |
| 2292 | pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void { |
| 2293 | const writer = o.writer(); |
| 2294 | switch (lazy_fn.key_ptr.*) { |
| 2295 | .tag_name => _ = try o.dg.renderTagNameFn( |
| 2296 | writer, |
| 2297 | lazy_fn.value_ptr.fn_name, |
| 2298 | lazy_fn.value_ptr.data.tag_name, |
| 2299 | ), |
| 2300 | } |
| 2301 | } |
| 2302 | |
| 2770 | 2303 | pub fn genFunc(f: *Function) !void { |
| 2771 | 2304 | const tracy = trace(@src()); |
| 2772 | 2305 | defer tracy.end(); |
| ... | ... | @@ -2845,7 +2378,7 @@ pub fn genFunc(f: *Function) !void { |
| 2845 | 2378 | w, |
| 2846 | 2379 | local.ty, |
| 2847 | 2380 | .{ .local = local_index }, |
| 2848 | | .Mut, |
| 2381 | .mut, |
| 2849 | 2382 | local.alignment, |
| 2850 | 2383 | .Complete, |
| 2851 | 2384 | ); |
| ... | ... | @@ -2886,7 +2419,7 @@ pub fn genDecl(o: *Object) !void { |
| 2886 | 2419 | |
| 2887 | 2420 | try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static "); |
| 2888 | 2421 | if (variable.is_threadlocal) try fwd_decl_writer.writeAll("zig_threadlocal "); |
| 2889 | | try o.dg.renderTypeAndName(fwd_decl_writer, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align", .Complete); |
| 2422 | try o.dg.renderTypeAndName(fwd_decl_writer, o.dg.decl.ty, decl_c_value, .mut, o.dg.decl.@"align", .Complete); |
| 2890 | 2423 | try fwd_decl_writer.writeAll(";\n"); |
| 2891 | 2424 | try genExports(o); |
| 2892 | 2425 | |
| ... | ... | @@ -2896,7 +2429,7 @@ pub fn genDecl(o: *Object) !void { |
| 2896 | 2429 | if (!is_global) try w.writeAll("static "); |
| 2897 | 2430 | if (variable.is_threadlocal) try w.writeAll("zig_threadlocal "); |
| 2898 | 2431 | if (o.dg.decl.@"linksection") |section| try w.print("zig_linksection(\"{s}\", ", .{section}); |
| 2899 | | try o.dg.renderTypeAndName(w, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align", .Complete); |
| 2432 | try o.dg.renderTypeAndName(w, o.dg.decl.ty, decl_c_value, .mut, o.dg.decl.@"align", .Complete); |
| 2900 | 2433 | if (o.dg.decl.@"linksection" != null) try w.writeAll(", read, write)"); |
| 2901 | 2434 | try w.writeAll(" = "); |
| 2902 | 2435 | try o.dg.renderValue(w, tv.ty, variable.init, .StaticInitializer); |
| ... | ... | @@ -2908,13 +2441,13 @@ pub fn genDecl(o: *Object) !void { |
| 2908 | 2441 | const decl_c_value: CValue = .{ .decl = o.dg.decl_index }; |
| 2909 | 2442 | |
| 2910 | 2443 | try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static "); |
| 2911 | | try o.dg.renderTypeAndName(fwd_decl_writer, tv.ty, decl_c_value, .Const, o.dg.decl.@"align", .Complete); |
| 2444 | try o.dg.renderTypeAndName(fwd_decl_writer, tv.ty, decl_c_value, .@"const", o.dg.decl.@"align", .Complete); |
| 2912 | 2445 | try fwd_decl_writer.writeAll(";\n"); |
| 2913 | 2446 | |
| 2914 | 2447 | const w = o.writer(); |
| 2915 | 2448 | if (!is_global) try w.writeAll("static "); |
| 2916 | 2449 | if (o.dg.decl.@"linksection") |section| try w.print("zig_linksection(\"{s}\", ", .{section}); |
| 2917 | | try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, .Const, o.dg.decl.@"align", .Complete); |
| 2450 | try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, .@"const", o.dg.decl.@"align", .Complete); |
| 2918 | 2451 | if (o.dg.decl.@"linksection" != null) try w.writeAll(", read)"); |
| 2919 | 2452 | try w.writeAll(" = "); |
| 2920 | 2453 | try o.dg.renderValue(w, tv.ty, tv.val, .StaticInitializer); |
| ... | ... | @@ -3443,7 +2976,7 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3443 | 2976 | return CValue{ .undef = inst_ty }; |
| 3444 | 2977 | } |
| 3445 | 2978 | |
| 3446 | | const mutability: Mutability = if (inst_ty.isConstPtr()) .Const else .Mut; |
| 2979 | const mutability: Mutability = if (inst_ty.isConstPtr()) .@"const" else .mut; |
| 3447 | 2980 | const target = f.object.dg.module.getTarget(); |
| 3448 | 2981 | const local = try f.allocAlignedLocal(elem_type, mutability, inst_ty.ptrAlignment(target)); |
| 3449 | 2982 | log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.local }); |
| ... | ... | @@ -3460,7 +2993,7 @@ fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3460 | 2993 | return CValue{ .undef = inst_ty }; |
| 3461 | 2994 | } |
| 3462 | 2995 | |
| 3463 | | const mutability: Mutability = if (inst_ty.isConstPtr()) .Const else .Mut; |
| 2996 | const mutability: Mutability = if (inst_ty.isConstPtr()) .@"const" else .mut; |
| 3464 | 2997 | const target = f.object.dg.module.getTarget(); |
| 3465 | 2998 | const local = try f.allocAlignedLocal(elem_ty, mutability, inst_ty.ptrAlignment(target)); |
| 3466 | 2999 | log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.local }); |
| ... | ... | @@ -4937,7 +4470,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4937 | 4470 | writer, |
| 4938 | 4471 | output_ty, |
| 4939 | 4472 | local_value, |
| 4940 | | .Mut, |
| 4473 | .mut, |
| 4941 | 4474 | alignment, |
| 4942 | 4475 | .Complete, |
| 4943 | 4476 | ); |
| ... | ... | @@ -4976,7 +4509,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4976 | 4509 | writer, |
| 4977 | 4510 | input_ty, |
| 4978 | 4511 | local_value, |
| 4979 | | .Const, |
| 4512 | .@"const", |
| 4980 | 4513 | alignment, |
| 4981 | 4514 | .Complete, |
| 4982 | 4515 | ); |
| ... | ... | @@ -6474,7 +6007,7 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6474 | 6007 | const writer = f.object.writer(); |
| 6475 | 6008 | const local = try f.allocLocal(inst, inst_ty); |
| 6476 | 6009 | try f.writeCValue(writer, local, .Other); |
| 6477 | | try writer.print(" = {s}(", .{try f.object.dg.getTagNameFn(enum_ty)}); |
| 6010 | try writer.print(" = {s}(", .{try f.getTagNameFn(enum_ty)}); |
| 6478 | 6011 | try f.writeCValue(writer, operand, .Other); |
| 6479 | 6012 | try writer.writeAll(");\n"); |
| 6480 | 6013 | |