| ... | @@ -23,7 +23,7 @@ const libcFloatSuffix = target_util.libcFloatSuffix; | ... | @@ -23,7 +23,7 @@ const libcFloatSuffix = target_util.libcFloatSuffix; |
| 23 | const compilerRtFloatAbbrev = target_util.compilerRtFloatAbbrev; | 23 | const compilerRtFloatAbbrev = target_util.compilerRtFloatAbbrev; |
| 24 | const compilerRtIntAbbrev = target_util.compilerRtIntAbbrev; | 24 | const compilerRtIntAbbrev = target_util.compilerRtIntAbbrev; |
| 25 | | 25 | |
| 26 | const Mutability = enum { Const, ConstArgument, Mut }; | 26 | const Mutability = enum { @"const", mut }; |
| 27 | const BigIntLimb = std.math.big.Limb; | 27 | const BigIntLimb = std.math.big.Limb; |
| 28 | const BigInt = std.math.big.int; | 28 | const BigInt = std.math.big.int; |
| 29 | | 29 | |
| ... | @@ -63,12 +63,17 @@ const TypedefKind = enum { | ... | @@ -63,12 +63,17 @@ const TypedefKind = enum { |
| 63 | }; | 63 | }; |
| 64 | | 64 | |
| 65 | pub const CValueMap = std.AutoHashMap(Air.Inst.Ref, CValue); | 65 | pub const CValueMap = std.AutoHashMap(Air.Inst.Ref, CValue); |
| 66 | pub const TypedefMap = std.ArrayHashMap( | 66 | |
| 67 | Type, | 67 | pub const LazyFnKey = union(enum) { |
| 68 | struct { name: []const u8, rendered: []u8 }, | 68 | tag_name: Decl.Index, |
| 69 | Type.HashContext32, | 69 | }; |
| 70 | true, | 70 | pub const LazyFnValue = struct { |
| 71 | ); | 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 | const LoopDepth = u16; | 78 | const LoopDepth = u16; |
| 74 | const Local = struct { | 79 | const Local = struct { |
| ... | @@ -83,11 +88,6 @@ const LocalsList = std.ArrayListUnmanaged(LocalIndex); | ... | @@ -83,11 +88,6 @@ const LocalsList = std.ArrayListUnmanaged(LocalIndex); |
| 83 | const LocalsMap = std.ArrayHashMapUnmanaged(Type, LocalsList, Type.HashContext32, true); | 88 | const LocalsMap = std.ArrayHashMapUnmanaged(Type, LocalsList, Type.HashContext32, true); |
| 84 | const LocalsStack = std.ArrayListUnmanaged(LocalsMap); | 89 | const LocalsStack = std.ArrayListUnmanaged(LocalsMap); |
| 85 | | 90 | |
| 86 | const FormatTypeAsCIdentContext = struct { | | |
| 87 | ty: Type, | | |
| 88 | mod: *Module, | | |
| 89 | }; | | |
| 90 | | | |
| 91 | const ValueRenderLocation = enum { | 91 | const ValueRenderLocation = enum { |
| 92 | FunctionArgument, | 92 | FunctionArgument, |
| 93 | Initializer, | 93 | Initializer, |
| ... | @@ -108,26 +108,6 @@ const BuiltinInfo = enum { | ... | @@ -108,26 +108,6 @@ const BuiltinInfo = enum { |
| 108 | Bits, | 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 | const reserved_idents = std.ComptimeStringMap(void, .{ | 111 | const reserved_idents = std.ComptimeStringMap(void, .{ |
| 132 | // C language | 112 | // C language |
| 133 | .{ "alignas", { | 113 | .{ "alignas", { |
| ... | @@ -283,6 +263,7 @@ pub const Function = struct { | ... | @@ -283,6 +263,7 @@ pub const Function = struct { |
| 283 | next_arg_index: usize = 0, | 263 | next_arg_index: usize = 0, |
| 284 | next_block_index: usize = 0, | 264 | next_block_index: usize = 0, |
| 285 | object: Object, | 265 | object: Object, |
| | 266 | lazy_fns: LazyFnMap, |
| 286 | func: *Module.Fn, | 267 | func: *Module.Fn, |
| 287 | /// All the locals, to be emitted at the top of the function. | 268 | /// All the locals, to be emitted at the top of the function. |
| 288 | locals: std.ArrayListUnmanaged(Local) = .{}, | 269 | locals: std.ArrayListUnmanaged(Local) = .{}, |
| ... | @@ -319,7 +300,7 @@ pub const Function = struct { | ... | @@ -319,7 +300,7 @@ pub const Function = struct { |
| 319 | const gpa = f.object.dg.gpa; | 300 | const gpa = f.object.dg.gpa; |
| 320 | try f.allocs.put(gpa, decl_c_value.local, true); | 301 | try f.allocs.put(gpa, decl_c_value.local, true); |
| 321 | try writer.writeAll("static "); | 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 | try writer.writeAll(" = "); | 304 | try writer.writeAll(" = "); |
| 324 | try f.object.dg.renderValue(writer, ty, val, .StaticInitializer); | 305 | try f.object.dg.renderValue(writer, ty, val, .StaticInitializer); |
| 325 | try writer.writeAll(";\n "); | 306 | try writer.writeAll(";\n "); |
| ... | @@ -353,7 +334,7 @@ pub const Function = struct { | ... | @@ -353,7 +334,7 @@ pub const Function = struct { |
| 353 | } | 334 | } |
| 354 | | 335 | |
| 355 | fn allocLocal(f: *Function, inst: Air.Inst.Index, ty: Type) !CValue { | 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 | log.debug("%{d}: allocating t{d}", .{ inst, result.local }); | 338 | log.debug("%{d}: allocating t{d}", .{ inst, result.local }); |
| 358 | return result; | 339 | return result; |
| 359 | } | 340 | } |
| ... | @@ -448,6 +429,29 @@ pub const Function = struct { | ... | @@ -448,6 +429,29 @@ pub const Function = struct { |
| 448 | return f.object.dg.fmtIntLiteral(ty, val); | 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 | pub fn deinit(f: *Function) void { | 455 | pub fn deinit(f: *Function) void { |
| 452 | const gpa = f.object.dg.gpa; | 456 | const gpa = f.object.dg.gpa; |
| 453 | f.allocs.deinit(gpa); | 457 | f.allocs.deinit(gpa); |
| ... | @@ -458,11 +462,8 @@ pub const Function = struct { | ... | @@ -458,11 +462,8 @@ pub const Function = struct { |
| 458 | f.free_locals_stack.deinit(gpa); | 462 | f.free_locals_stack.deinit(gpa); |
| 459 | f.blocks.deinit(gpa); | 463 | f.blocks.deinit(gpa); |
| 460 | f.value_map.deinit(); | 464 | f.value_map.deinit(); |
| | 465 | f.lazy_fns.deinit(gpa); |
| 461 | f.object.code.deinit(); | 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 | f.object.dg.ctypes.deinit(gpa); | 467 | f.object.dg.ctypes.deinit(gpa); |
| 467 | f.object.dg.fwd_decl.deinit(); | 468 | f.object.dg.fwd_decl.deinit(); |
| 468 | f.arena.deinit(); | 469 | f.arena.deinit(); |
| ... | @@ -492,9 +493,6 @@ pub const DeclGen = struct { | ... | @@ -492,9 +493,6 @@ pub const DeclGen = struct { |
| 492 | fwd_decl: std.ArrayList(u8), | 493 | fwd_decl: std.ArrayList(u8), |
| 493 | error_msg: ?*Module.ErrorMsg, | 494 | error_msg: ?*Module.ErrorMsg, |
| 494 | ctypes: CType.Store, | 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 | fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } { | 497 | fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } { |
| 500 | @setCold(true); | 498 | @setCold(true); |
| ... | @@ -504,14 +502,6 @@ pub const DeclGen = struct { | ... | @@ -504,14 +502,6 @@ pub const DeclGen = struct { |
| 504 | return error.AnalysisFail; | 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 | fn renderDeclValue( | 505 | fn renderDeclValue( |
| 516 | dg: *DeclGen, | 506 | dg: *DeclGen, |
| 517 | writer: anytype, | 507 | writer: anytype, |
| ... | @@ -1493,7 +1483,7 @@ pub const DeclGen = struct { | ... | @@ -1493,7 +1483,7 @@ pub const DeclGen = struct { |
| 1493 | if (!param_type.hasRuntimeBitsIgnoreComptime()) continue; | 1483 | if (!param_type.hasRuntimeBitsIgnoreComptime()) continue; |
| 1494 | if (index > 0) try w.writeAll(", "); | 1484 | if (index > 0) try w.writeAll(", "); |
| 1495 | const name = CValue{ .arg = index }; | 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 | index += 1; | 1487 | index += 1; |
| 1498 | } | 1488 | } |
| 1499 | | 1489 | |
| ... | @@ -1507,453 +1497,6 @@ pub const DeclGen = struct { | ... | @@ -1507,453 +1497,6 @@ pub const DeclGen = struct { |
| 1507 | if (fn_info.alignment > 0 and kind == .Forward) try w.print(" zig_align_fn({})", .{fn_info.alignment}); | 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 | fn indexToCType(dg: *DeclGen, idx: CType.Index) CType { | 1500 | fn indexToCType(dg: *DeclGen, idx: CType.Index) CType { |
| 1958 | return dg.ctypes.indexToCType(idx); | 1501 | return dg.ctypes.indexToCType(idx); |
| 1959 | } | 1502 | } |
| ... | @@ -2408,31 +1951,27 @@ pub const DeclGen = struct { | ... | @@ -2408,31 +1951,27 @@ pub const DeclGen = struct { |
| 2408 | const idx = try dg.typeToIndex(ty); | 1951 | const idx = try dg.typeToIndex(ty); |
| 2409 | try w.print("{}", .{try dg.renderTypePrefix(w, idx, .suffix, CQualifiers.init(.{ | 1952 | try w.print("{}", .{try dg.renderTypePrefix(w, idx, .suffix, CQualifiers.init(.{ |
| 2410 | .@"const" = switch (mutability) { | 1953 | .@"const" = switch (mutability) { |
| 2411 | .Const, .ConstArgument => true, | 1954 | .mut => false, |
| 2412 | .Mut => false, | 1955 | .@"const" => true, |
| 2413 | }, | 1956 | }, |
| 2414 | }))}); | 1957 | }))}); |
| 2415 | try dg.writeCValue(w, name); | 1958 | try dg.writeCValue(w, name); |
| 2416 | try dg.renderTypeSuffix(w, idx, .suffix); | 1959 | try dg.renderTypeSuffix(w, idx, .suffix); |
| 2417 | } | 1960 | } |
| 2418 | | 1961 | |
| 2419 | fn renderTagNameFn(dg: *DeclGen, enum_ty: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { | 1962 | fn renderTagNameFn(dg: *DeclGen, w: anytype, fn_name: []const u8, enum_ty: Type) !void { |
| 2420 | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); | | |
| 2421 | defer buffer.deinit(); | | |
| 2422 | const bw = buffer.writer(); | | |
| 2423 | | | |
| 2424 | const name_slice_ty = Type.initTag(.const_slice_u8_sentinel_0); | 1963 | const name_slice_ty = Type.initTag(.const_slice_u8_sentinel_0); |
| 2425 | | 1964 | |
| 2426 | try buffer.appendSlice("static "); | 1965 | try w.writeAll("static "); |
| 2427 | try dg.renderType(bw, name_slice_ty, .Complete); | 1966 | try dg.renderType(w, name_slice_ty, .Complete); |
| 2428 | const name_begin = buffer.items.len + " ".len; | 1967 | try w.writeByte(' '); |
| 2429 | try bw.print(" zig_tagName_{}_{d}(", .{ typeToCIdentifier(enum_ty, dg.module), @enumToInt(enum_ty.getOwnerDecl()) }); | 1968 | try w.writeAll(fn_name); |
| 2430 | const name_end = buffer.items.len - "(".len; | 1969 | try w.writeByte('('); |
| 2431 | try dg.renderTypeAndName(bw, enum_ty, .{ .identifier = "tag" }, .Const, 0, .Complete); | 1970 | try dg.renderTypeAndName(w, enum_ty, .{ .identifier = "tag" }, .@"const", 0, .Complete); |
| 2432 | try buffer.appendSlice(") {\n switch (tag) {\n"); | 1971 | try w.writeAll(") {\n switch (tag) {\n"); |
| 2433 | for (enum_ty.enumFields().keys(), 0..) |name, index| { | 1972 | for (enum_ty.enumFields().keys(), 0..) |name, index| { |
| 2434 | const name_z = try dg.typedefs.allocator.dupeZ(u8, name); | 1973 | const name_z = try dg.gpa.dupeZ(u8, name); |
| 2435 | defer dg.typedefs.allocator.free(name_z); | 1974 | defer dg.gpa.free(name_z); |
| 2436 | const name_bytes = name_z[0 .. name_z.len + 1]; | 1975 | const name_bytes = name_z[0 .. name_z.len + 1]; |
| 2437 | | 1976 | |
| 2438 | var tag_pl: Value.Payload.U32 = .{ | 1977 | var tag_pl: Value.Payload.U32 = .{ |
| ... | @@ -2453,40 +1992,23 @@ pub const DeclGen = struct { | ... | @@ -2453,40 +1992,23 @@ pub const DeclGen = struct { |
| 2453 | var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = name.len }; | 1992 | var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = name.len }; |
| 2454 | const len_val = Value.initPayload(&len_pl.base); | 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)}); | 1995 | try w.print(" case {}: {{\n static ", .{try dg.fmtIntLiteral(enum_ty, int_val)}); |
| 2457 | try dg.renderTypeAndName(bw, name_ty, .{ .identifier = "name" }, .Const, 0, .Complete); | 1996 | try dg.renderTypeAndName(w, name_ty, .{ .identifier = "name" }, .@"const", 0, .Complete); |
| 2458 | try buffer.appendSlice(" = "); | 1997 | try w.writeAll(" = "); |
| 2459 | try dg.renderValue(bw, name_ty, name_val, .Initializer); | 1998 | try dg.renderValue(w, name_ty, name_val, .Initializer); |
| 2460 | try buffer.appendSlice(";\n return ("); | 1999 | try w.writeAll(";\n return ("); |
| 2461 | try dg.renderTypecast(bw, name_slice_ty); | 2000 | try dg.renderTypecast(w, name_slice_ty); |
| 2462 | try bw.print("){{{}, {}}};\n", .{ | 2001 | try w.print("){{{}, {}}};\n", .{ |
| 2463 | fmtIdent("name"), try dg.fmtIntLiteral(Type.usize, len_val), | 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 ("); | 2007 | try w.writeAll(" }\n while ("); |
| 2469 | try dg.renderValue(bw, Type.bool, Value.true, .Other); | 2008 | try dg.renderValue(w, Type.bool, Value.true, .Other); |
| 2470 | try buffer.appendSlice(") "); | 2009 | try w.writeAll(") "); |
| 2471 | _ = try airBreakpoint(bw); | 2010 | _ = try airBreakpoint(w); |
| 2472 | try buffer.appendSlice("}\n"); | 2011 | try w.writeAll("}\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); | | |
| 2490 | } | 2012 | } |
| 2491 | | 2013 | |
| 2492 | fn declIsGlobal(dg: *DeclGen, tv: TypedValue) bool { | 2014 | fn declIsGlobal(dg: *DeclGen, tv: TypedValue) bool { |
| ... | @@ -2724,7 +2246,7 @@ pub fn genErrDecls(o: *Object) !void { | ... | @@ -2724,7 +2246,7 @@ pub fn genErrDecls(o: *Object) !void { |
| 2724 | const name_val = Value.initPayload(&name_pl.base); | 2246 | const name_val = Value.initPayload(&name_pl.base); |
| 2725 | | 2247 | |
| 2726 | try writer.writeAll("static "); | 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 | try writer.writeAll(" = "); | 2250 | try writer.writeAll(" = "); |
| 2729 | try o.dg.renderValue(writer, name_ty, name_val, .StaticInitializer); | 2251 | try o.dg.renderValue(writer, name_ty, name_val, .StaticInitializer); |
| 2730 | try writer.writeAll(";\n"); | 2252 | try writer.writeAll(";\n"); |
| ... | @@ -2737,7 +2259,7 @@ pub fn genErrDecls(o: *Object) !void { | ... | @@ -2737,7 +2259,7 @@ pub fn genErrDecls(o: *Object) !void { |
| 2737 | const name_array_ty = Type.initPayload(&name_array_ty_pl.base); | 2259 | const name_array_ty = Type.initPayload(&name_array_ty_pl.base); |
| 2738 | | 2260 | |
| 2739 | try writer.writeAll("static "); | 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 | try writer.writeAll(" = {"); | 2263 | try writer.writeAll(" = {"); |
| 2742 | for (o.dg.module.error_name_list.items, 0..) |name, value| { | 2264 | for (o.dg.module.error_name_list.items, 0..) |name, value| { |
| 2743 | if (value != 0) try writer.writeByte(','); | 2265 | if (value != 0) try writer.writeByte(','); |
| ... | @@ -2767,6 +2289,17 @@ fn genExports(o: *Object) !void { | ... | @@ -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 | pub fn genFunc(f: *Function) !void { | 2303 | pub fn genFunc(f: *Function) !void { |
| 2771 | const tracy = trace(@src()); | 2304 | const tracy = trace(@src()); |
| 2772 | defer tracy.end(); | 2305 | defer tracy.end(); |
| ... | @@ -2845,7 +2378,7 @@ pub fn genFunc(f: *Function) !void { | ... | @@ -2845,7 +2378,7 @@ pub fn genFunc(f: *Function) !void { |
| 2845 | w, | 2378 | w, |
| 2846 | local.ty, | 2379 | local.ty, |
| 2847 | .{ .local = local_index }, | 2380 | .{ .local = local_index }, |
| 2848 | .Mut, | 2381 | .mut, |
| 2849 | local.alignment, | 2382 | local.alignment, |
| 2850 | .Complete, | 2383 | .Complete, |
| 2851 | ); | 2384 | ); |
| ... | @@ -2886,7 +2419,7 @@ pub fn genDecl(o: *Object) !void { | ... | @@ -2886,7 +2419,7 @@ pub fn genDecl(o: *Object) !void { |
| 2886 | | 2419 | |
| 2887 | try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static "); | 2420 | try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static "); |
| 2888 | if (variable.is_threadlocal) try fwd_decl_writer.writeAll("zig_threadlocal "); | 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 | try fwd_decl_writer.writeAll(";\n"); | 2423 | try fwd_decl_writer.writeAll(";\n"); |
| 2891 | try genExports(o); | 2424 | try genExports(o); |
| 2892 | | 2425 | |
| ... | @@ -2896,7 +2429,7 @@ pub fn genDecl(o: *Object) !void { | ... | @@ -2896,7 +2429,7 @@ pub fn genDecl(o: *Object) !void { |
| 2896 | if (!is_global) try w.writeAll("static "); | 2429 | if (!is_global) try w.writeAll("static "); |
| 2897 | if (variable.is_threadlocal) try w.writeAll("zig_threadlocal "); | 2430 | if (variable.is_threadlocal) try w.writeAll("zig_threadlocal "); |
| 2898 | if (o.dg.decl.@"linksection") |section| try w.print("zig_linksection(\"{s}\", ", .{section}); | 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 | if (o.dg.decl.@"linksection" != null) try w.writeAll(", read, write)"); | 2433 | if (o.dg.decl.@"linksection" != null) try w.writeAll(", read, write)"); |
| 2901 | try w.writeAll(" = "); | 2434 | try w.writeAll(" = "); |
| 2902 | try o.dg.renderValue(w, tv.ty, variable.init, .StaticInitializer); | 2435 | try o.dg.renderValue(w, tv.ty, variable.init, .StaticInitializer); |
| ... | @@ -2908,13 +2441,13 @@ pub fn genDecl(o: *Object) !void { | ... | @@ -2908,13 +2441,13 @@ pub fn genDecl(o: *Object) !void { |
| 2908 | const decl_c_value: CValue = .{ .decl = o.dg.decl_index }; | 2441 | const decl_c_value: CValue = .{ .decl = o.dg.decl_index }; |
| 2909 | | 2442 | |
| 2910 | try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static "); | 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 | try fwd_decl_writer.writeAll(";\n"); | 2445 | try fwd_decl_writer.writeAll(";\n"); |
| 2913 | | 2446 | |
| 2914 | const w = o.writer(); | 2447 | const w = o.writer(); |
| 2915 | if (!is_global) try w.writeAll("static "); | 2448 | if (!is_global) try w.writeAll("static "); |
| 2916 | if (o.dg.decl.@"linksection") |section| try w.print("zig_linksection(\"{s}\", ", .{section}); | 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 | if (o.dg.decl.@"linksection" != null) try w.writeAll(", read)"); | 2451 | if (o.dg.decl.@"linksection" != null) try w.writeAll(", read)"); |
| 2919 | try w.writeAll(" = "); | 2452 | try w.writeAll(" = "); |
| 2920 | try o.dg.renderValue(w, tv.ty, tv.val, .StaticInitializer); | 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,7 +2976,7 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3443 | return CValue{ .undef = inst_ty }; | 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 | const target = f.object.dg.module.getTarget(); | 2980 | const target = f.object.dg.module.getTarget(); |
| 3448 | const local = try f.allocAlignedLocal(elem_type, mutability, inst_ty.ptrAlignment(target)); | 2981 | const local = try f.allocAlignedLocal(elem_type, mutability, inst_ty.ptrAlignment(target)); |
| 3449 | log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.local }); | 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,7 +2993,7 @@ fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3460 | return CValue{ .undef = inst_ty }; | 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 | const target = f.object.dg.module.getTarget(); | 2997 | const target = f.object.dg.module.getTarget(); |
| 3465 | const local = try f.allocAlignedLocal(elem_ty, mutability, inst_ty.ptrAlignment(target)); | 2998 | const local = try f.allocAlignedLocal(elem_ty, mutability, inst_ty.ptrAlignment(target)); |
| 3466 | log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.local }); | 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,7 +4470,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4937 | writer, | 4470 | writer, |
| 4938 | output_ty, | 4471 | output_ty, |
| 4939 | local_value, | 4472 | local_value, |
| 4940 | .Mut, | 4473 | .mut, |
| 4941 | alignment, | 4474 | alignment, |
| 4942 | .Complete, | 4475 | .Complete, |
| 4943 | ); | 4476 | ); |
| ... | @@ -4976,7 +4509,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4976,7 +4509,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4976 | writer, | 4509 | writer, |
| 4977 | input_ty, | 4510 | input_ty, |
| 4978 | local_value, | 4511 | local_value, |
| 4979 | .Const, | 4512 | .@"const", |
| 4980 | alignment, | 4513 | alignment, |
| 4981 | .Complete, | 4514 | .Complete, |
| 4982 | ); | 4515 | ); |
| ... | @@ -6474,7 +6007,7 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6474,7 +6007,7 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6474 | const writer = f.object.writer(); | 6007 | const writer = f.object.writer(); |
| 6475 | const local = try f.allocLocal(inst, inst_ty); | 6008 | const local = try f.allocLocal(inst, inst_ty); |
| 6476 | try f.writeCValue(writer, local, .Other); | 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 | try f.writeCValue(writer, operand, .Other); | 6011 | try f.writeCValue(writer, operand, .Other); |
| 6479 | try writer.writeAll(");\n"); | 6012 | try writer.writeAll(");\n"); |
| 6480 | | 6013 | |