authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-10-19 15:10:35-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-10-21 21:38:41-04:00
log7bab406c790566781406a7968be22961ed7c305d
treee2f778d1c66dd62bf41da837bb76a882b792ec6e
parent5aa82ed477b85cf8681bc0dc65f97e813990a2ed

InternPool: store alignment of anon decls

Commit 5393e56500d499753dbc39704c0161b47d1e4d5c has a flaw pointed out by @mlugg: the `ty` field of pointer values changes when comptime values are pointer-casted. This commit introduces a new encoding which additionally stores the "original pointer type" which is used to store the alignment of the anonymous decl, and potentially other information in the future such as section and pointer address space. However, this new encoding is only used when the original pointer type differs from the casted pointer type in a meaningful way. I was able to make the LLVM backend and the C backend lower anonymous decls with the appropriate alignment, however I will need some help figuring out how to do this for the backends that lower anonymous decls via src/codegen.zig and the wasm backend.

13 files changed, 189 insertions(+), 44 deletions(-)

src/Compilation.zig+1
...@@ -3545,6 +3545,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v...@@ -3545,6 +3545,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v
3545 .fwd_decl = fwd_decl.toManaged(gpa),3545 .fwd_decl = fwd_decl.toManaged(gpa),
3546 .ctypes = .{},3546 .ctypes = .{},
3547 .anon_decl_deps = .{},3547 .anon_decl_deps = .{},
3548 .aligned_anon_decls = .{},
3548 };3549 };
3549 defer {3550 defer {
3550 dg.ctypes.deinit(gpa);3551 dg.ctypes.deinit(gpa);
src/InternPool.zig+86-14
...@@ -1074,7 +1074,7 @@ pub const Key = union(enum) {...@@ -1074,7 +1074,7 @@ pub const Key = union(enum) {
10741074
1075 decl: Module.Decl.Index,1075 decl: Module.Decl.Index,
1076 mut_decl: MutDecl,1076 mut_decl: MutDecl,
1077 anon_decl: Index,1077 anon_decl: AnonDecl,
1078 comptime_field: Index,1078 comptime_field: Index,
1079 int: Index,1079 int: Index,
1080 eu_payload: Index,1080 eu_payload: Index,
...@@ -1090,6 +1090,14 @@ pub const Key = union(enum) {...@@ -1090,6 +1090,14 @@ pub const Key = union(enum) {
1090 base: Index,1090 base: Index,
1091 index: u64,1091 index: u64,
1092 };1092 };
1093 pub const AnonDecl = extern struct {
1094 val: Index,
1095 /// Contains the canonical pointer type of the anonymous
1096 /// declaration. This may equal `ty` of the `Ptr` or it may be
1097 /// different. Importantly, when lowering the anonymous decl,
1098 /// the original pointer type alignment must be used.
1099 orig_ty: Index,
1100 };
1093 };1101 };
1094 };1102 };
10951103
...@@ -1231,7 +1239,8 @@ pub const Key = union(enum) {...@@ -1231,7 +1239,8 @@ pub const Key = union(enum) {
1231 common ++ asBytes(&x.decl) ++ asBytes(&x.runtime_index),1239 common ++ asBytes(&x.decl) ++ asBytes(&x.runtime_index),
1232 ),1240 ),
12331241
1234 .anon_decl,1242 .anon_decl => |x| Hash.hash(seed2, common ++ asBytes(&x)),
1243
1235 .int,1244 .int,
1236 .eu_payload,1245 .eu_payload,
1237 .opt_payload,1246 .opt_payload,
...@@ -1500,7 +1509,8 @@ pub const Key = union(enum) {...@@ -1500,7 +1509,8 @@ pub const Key = union(enum) {
1500 return switch (a_info.addr) {1509 return switch (a_info.addr) {
1501 .decl => |a_decl| a_decl == b_info.addr.decl,1510 .decl => |a_decl| a_decl == b_info.addr.decl,
1502 .mut_decl => |a_mut_decl| std.meta.eql(a_mut_decl, b_info.addr.mut_decl),1511 .mut_decl => |a_mut_decl| std.meta.eql(a_mut_decl, b_info.addr.mut_decl),
1503 .anon_decl => |a_decl| a_decl == b_info.addr.anon_decl,1512 .anon_decl => |ad| ad.val == b_info.addr.anon_decl.val and
1513 ad.orig_ty == b_info.addr.anon_decl.orig_ty,
1504 .int => |a_int| a_int == b_info.addr.int,1514 .int => |a_int| a_int == b_info.addr.int,
1505 .eu_payload => |a_eu_payload| a_eu_payload == b_info.addr.eu_payload,1515 .eu_payload => |a_eu_payload| a_eu_payload == b_info.addr.eu_payload,
1506 .opt_payload => |a_opt_payload| a_opt_payload == b_info.addr.opt_payload,1516 .opt_payload => |a_opt_payload| a_opt_payload == b_info.addr.opt_payload,
...@@ -2133,6 +2143,7 @@ pub const Index = enum(u32) {...@@ -2133,6 +2143,7 @@ pub const Index = enum(u32) {
2133 ptr_decl: struct { data: *PtrDecl },2143 ptr_decl: struct { data: *PtrDecl },
2134 ptr_mut_decl: struct { data: *PtrMutDecl },2144 ptr_mut_decl: struct { data: *PtrMutDecl },
2135 ptr_anon_decl: struct { data: *PtrAnonDecl },2145 ptr_anon_decl: struct { data: *PtrAnonDecl },
2146 ptr_anon_decl_aligned: struct { data: *PtrAnonDeclAligned },
2136 ptr_comptime_field: struct { data: *PtrComptimeField },2147 ptr_comptime_field: struct { data: *PtrComptimeField },
2137 ptr_int: struct { data: *PtrBase },2148 ptr_int: struct { data: *PtrBase },
2138 ptr_eu_payload: struct { data: *PtrBase },2149 ptr_eu_payload: struct { data: *PtrBase },
...@@ -2583,8 +2594,16 @@ pub const Tag = enum(u8) {...@@ -2583,8 +2594,16 @@ pub const Tag = enum(u8) {
2583 /// data is extra index of `PtrMutDecl`, which contains the type and address.2594 /// data is extra index of `PtrMutDecl`, which contains the type and address.
2584 ptr_mut_decl,2595 ptr_mut_decl,
2585 /// A pointer to an anonymous decl.2596 /// A pointer to an anonymous decl.
2586 /// data is extra index of `PtrAnonDecl`, which contains the type and decl value.2597 /// data is extra index of `PtrAnonDecl`, which contains the pointer type and decl value.
2598 /// The alignment of the anonymous decl is communicated via the pointer type.
2587 ptr_anon_decl,2599 ptr_anon_decl,
2600 /// A pointer to an anonymous decl.
2601 /// data is extra index of `PtrAnonDeclAligned`, which contains the pointer
2602 /// type and decl value.
2603 /// The original pointer type is also provided, which will be different than `ty`.
2604 /// This encoding is only used when a pointer to an anonymous decl is
2605 /// coerced to a different pointer type with a different alignment.
2606 ptr_anon_decl_aligned,
2588 /// data is extra index of `PtrComptimeField`, which contains the pointer type and field value.2607 /// data is extra index of `PtrComptimeField`, which contains the pointer type and field value.
2589 ptr_comptime_field,2608 ptr_comptime_field,
2590 /// A pointer with an integer value.2609 /// A pointer with an integer value.
...@@ -2781,6 +2800,7 @@ pub const Tag = enum(u8) {...@@ -2781,6 +2800,7 @@ pub const Tag = enum(u8) {
2781 .ptr_decl => PtrDecl,2800 .ptr_decl => PtrDecl,
2782 .ptr_mut_decl => PtrMutDecl,2801 .ptr_mut_decl => PtrMutDecl,
2783 .ptr_anon_decl => PtrAnonDecl,2802 .ptr_anon_decl => PtrAnonDecl,
2803 .ptr_anon_decl_aligned => PtrAnonDeclAligned,
2784 .ptr_comptime_field => PtrComptimeField,2804 .ptr_comptime_field => PtrComptimeField,
2785 .ptr_int => PtrBase,2805 .ptr_int => PtrBase,
2786 .ptr_eu_payload => PtrBase,2806 .ptr_eu_payload => PtrBase,
...@@ -3383,6 +3403,13 @@ pub const PtrAnonDecl = struct {...@@ -3383,6 +3403,13 @@ pub const PtrAnonDecl = struct {
3383 val: Index,3403 val: Index,
3384};3404};
33853405
3406pub const PtrAnonDeclAligned = struct {
3407 ty: Index,
3408 val: Index,
3409 /// Must be nonequal to `ty`. Only the alignment from this value is important.
3410 orig_ty: Index,
3411};
3412
3386pub const PtrMutDecl = struct {3413pub const PtrMutDecl = struct {
3387 ty: Index,3414 ty: Index,
3388 decl: Module.Decl.Index,3415 decl: Module.Decl.Index,
...@@ -3736,7 +3763,20 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -3736,7 +3763,20 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
3736 const info = ip.extraData(PtrAnonDecl, data);3763 const info = ip.extraData(PtrAnonDecl, data);
3737 return .{ .ptr = .{3764 return .{ .ptr = .{
3738 .ty = info.ty,3765 .ty = info.ty,
3739 .addr = .{ .anon_decl = info.val },3766 .addr = .{ .anon_decl = .{
3767 .val = info.val,
3768 .orig_ty = info.ty,
3769 } },
3770 } };
3771 },
3772 .ptr_anon_decl_aligned => {
3773 const info = ip.extraData(PtrAnonDeclAligned, data);
3774 return .{ .ptr = .{
3775 .ty = info.ty,
3776 .addr = .{ .anon_decl = .{
3777 .val = info.val,
3778 .orig_ty = info.orig_ty,
3779 } },
3740 } };3780 } };
3741 },3781 },
3742 .ptr_comptime_field => {3782 .ptr_comptime_field => {
...@@ -3817,7 +3857,17 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -3817,7 +3857,17 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
3817 } };3857 } };
3818 },3858 },
3819 .ptr_anon_decl => .{3859 .ptr_anon_decl => .{
3820 .anon_decl = ip.extraData(PtrAnonDecl, ptr_item.data).val,3860 .anon_decl = .{
3861 .val = ip.extraData(PtrAnonDecl, ptr_item.data).val,
3862 .orig_ty = info.ty,
3863 },
3864 },
3865 .ptr_anon_decl_aligned => b: {
3866 const sub_info = ip.extraData(PtrAnonDeclAligned, ptr_item.data);
3867 break :b .{ .anon_decl = .{
3868 .val = sub_info.val,
3869 .orig_ty = sub_info.orig_ty,
3870 } };
3821 },3871 },
3822 .ptr_comptime_field => .{3872 .ptr_comptime_field => .{
3823 .comptime_field = ip.extraData(PtrComptimeField, ptr_item.data).field_val,3873 .comptime_field = ip.extraData(PtrComptimeField, ptr_item.data).field_val,
...@@ -4571,13 +4621,22 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -4571,13 +4621,22 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
4571 .runtime_index = mut_decl.runtime_index,4621 .runtime_index = mut_decl.runtime_index,
4572 }),4622 }),
4573 }),4623 }),
4574 .anon_decl => |anon_decl| ip.items.appendAssumeCapacity(.{4624 .anon_decl => |anon_decl| ip.items.appendAssumeCapacity(
4575 .tag = .ptr_anon_decl,4625 if (ptrsHaveSameAlignment(ip, ptr.ty, ptr_type, anon_decl.orig_ty)) .{
4576 .data = try ip.addExtra(gpa, PtrAnonDecl{4626 .tag = .ptr_anon_decl,
4577 .ty = ptr.ty,4627 .data = try ip.addExtra(gpa, PtrAnonDecl{
4578 .val = anon_decl,4628 .ty = ptr.ty,
4579 }),4629 .val = anon_decl.val,
4580 }),4630 }),
4631 } else .{
4632 .tag = .ptr_anon_decl_aligned,
4633 .data = try ip.addExtra(gpa, PtrAnonDeclAligned{
4634 .ty = ptr.ty,
4635 .val = anon_decl.val,
4636 .orig_ty = anon_decl.orig_ty,
4637 }),
4638 },
4639 ),
4581 .comptime_field => |field_val| {4640 .comptime_field => |field_val| {
4582 assert(field_val != .none);4641 assert(field_val != .none);
4583 ip.items.appendAssumeCapacity(.{4642 ip.items.appendAssumeCapacity(.{
...@@ -7184,6 +7243,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -7184,6 +7243,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
7184 .ptr_decl => @sizeOf(PtrDecl),7243 .ptr_decl => @sizeOf(PtrDecl),
7185 .ptr_mut_decl => @sizeOf(PtrMutDecl),7244 .ptr_mut_decl => @sizeOf(PtrMutDecl),
7186 .ptr_anon_decl => @sizeOf(PtrAnonDecl),7245 .ptr_anon_decl => @sizeOf(PtrAnonDecl),
7246 .ptr_anon_decl_aligned => @sizeOf(PtrAnonDeclAligned),
7187 .ptr_comptime_field => @sizeOf(PtrComptimeField),7247 .ptr_comptime_field => @sizeOf(PtrComptimeField),
7188 .ptr_int => @sizeOf(PtrBase),7248 .ptr_int => @sizeOf(PtrBase),
7189 .ptr_eu_payload => @sizeOf(PtrBase),7249 .ptr_eu_payload => @sizeOf(PtrBase),
...@@ -7314,6 +7374,7 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void {...@@ -7314,6 +7374,7 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void {
7314 .ptr_decl,7374 .ptr_decl,
7315 .ptr_mut_decl,7375 .ptr_mut_decl,
7316 .ptr_anon_decl,7376 .ptr_anon_decl,
7377 .ptr_anon_decl_aligned,
7317 .ptr_comptime_field,7378 .ptr_comptime_field,
7318 .ptr_int,7379 .ptr_int,
7319 .ptr_eu_payload,7380 .ptr_eu_payload,
...@@ -7695,6 +7756,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {...@@ -7695,6 +7756,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
7695 inline .ptr_decl,7756 inline .ptr_decl,
7696 .ptr_mut_decl,7757 .ptr_mut_decl,
7697 .ptr_anon_decl,7758 .ptr_anon_decl,
7759 .ptr_anon_decl_aligned,
7698 .ptr_comptime_field,7760 .ptr_comptime_field,
7699 .ptr_int,7761 .ptr_int,
7700 .ptr_eu_payload,7762 .ptr_eu_payload,
...@@ -7855,7 +7917,7 @@ pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.Addr.Tag {...@@ -7855,7 +7917,7 @@ pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.Addr.Tag {
7855 switch (ip.items.items(.tag)[base]) {7917 switch (ip.items.items(.tag)[base]) {
7856 .ptr_decl => return .decl,7918 .ptr_decl => return .decl,
7857 .ptr_mut_decl => return .mut_decl,7919 .ptr_mut_decl => return .mut_decl,
7858 .ptr_anon_decl => return .anon_decl,7920 .ptr_anon_decl, .ptr_anon_decl_aligned => return .anon_decl,
7859 .ptr_comptime_field => return .comptime_field,7921 .ptr_comptime_field => return .comptime_field,
7860 .ptr_int => return .int,7922 .ptr_int => return .int,
7861 inline .ptr_eu_payload,7923 inline .ptr_eu_payload,
...@@ -8032,6 +8094,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois...@@ -8032,6 +8094,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
8032 .ptr_decl,8094 .ptr_decl,
8033 .ptr_mut_decl,8095 .ptr_mut_decl,
8034 .ptr_anon_decl,8096 .ptr_anon_decl,
8097 .ptr_anon_decl_aligned,
8035 .ptr_comptime_field,8098 .ptr_comptime_field,
8036 .ptr_int,8099 .ptr_int,
8037 .ptr_eu_payload,8100 .ptr_eu_payload,
...@@ -8281,3 +8344,12 @@ pub fn addFieldName(...@@ -8281,3 +8344,12 @@ pub fn addFieldName(
8281 ip.extra.items[names_start + field_index] = @intFromEnum(name);8344 ip.extra.items[names_start + field_index] = @intFromEnum(name);
8282 return null;8345 return null;
8283}8346}
8347
8348/// Used only by `get` for pointer values, and mainly intended to use `Tag.ptr_anon_decl`
8349/// encoding instead of `Tag.ptr_anon_decl_aligned` when possible.
8350fn ptrsHaveSameAlignment(ip: *InternPool, a_ty: Index, a_info: Key.PtrType, b_ty: Index) bool {
8351 if (a_ty == b_ty) return true;
8352 const b_info = ip.indexToKey(b_ty).ptr_type;
8353 return a_info.flags.alignment == b_info.flags.alignment and
8354 (a_info.child == b_info.child or a_info.flags.alignment != .none);
8355}
src/Sema.zig+11-3
...@@ -3659,7 +3659,10 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -3659,7 +3659,10 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
3659 if (try sema.resolveComptimeKnownAllocValue(block, alloc, null)) |val| {3659 if (try sema.resolveComptimeKnownAllocValue(block, alloc, null)) |val| {
3660 const new_mut_ptr = Air.internedToRef((try mod.intern(.{ .ptr = .{3660 const new_mut_ptr = Air.internedToRef((try mod.intern(.{ .ptr = .{
3661 .ty = alloc_ty.toIntern(),3661 .ty = alloc_ty.toIntern(),
3662 .addr = .{ .anon_decl = val },3662 .addr = .{ .anon_decl = .{
3663 .val = val,
3664 .orig_ty = alloc_ty.toIntern(),
3665 } },
3663 } })));3666 } })));
3664 return sema.makePtrConst(block, new_mut_ptr);3667 return sema.makePtrConst(block, new_mut_ptr);
3665 }3668 }
...@@ -5540,7 +5543,10 @@ fn addStrLitNoAlias(sema: *Sema, bytes: []const u8) CompileError!Air.Inst.Ref {...@@ -5540,7 +5543,10 @@ fn addStrLitNoAlias(sema: *Sema, bytes: []const u8) CompileError!Air.Inst.Ref {
5540 });5543 });
5541 return Air.internedToRef((try mod.intern(.{ .ptr = .{5544 return Air.internedToRef((try mod.intern(.{ .ptr = .{
5542 .ty = ptr_ty.toIntern(),5545 .ty = ptr_ty.toIntern(),
5543 .addr = .{ .anon_decl = val },5546 .addr = .{ .anon_decl = .{
5547 .val = val,
5548 .orig_ty = ptr_ty.toIntern(),
5549 } },
5544 } })));5550 } })));
5545}5551}
55465552
...@@ -30546,7 +30552,8 @@ fn beginComptimePtrLoad(...@@ -30546,7 +30552,8 @@ fn beginComptimePtrLoad(
30546 .ty_without_well_defined_layout = if (!layout_defined) decl.ty else null,30552 .ty_without_well_defined_layout = if (!layout_defined) decl.ty else null,
30547 };30553 };
30548 },30554 },
30549 .anon_decl => |decl_val| blk: {30555 .anon_decl => |anon_decl| blk: {
30556 const decl_val = anon_decl.val;
30550 if (decl_val.toValue().getVariable(mod) != null) return error.RuntimeLoad;30557 if (decl_val.toValue().getVariable(mod) != null) return error.RuntimeLoad;
30551 const decl_ty = ip.typeOf(decl_val).toType();30558 const decl_ty = ip.typeOf(decl_val).toType();
30552 const decl_tv: TypedValue = .{ .ty = decl_ty, .val = decl_val.toValue() };30559 const decl_tv: TypedValue = .{ .ty = decl_ty, .val = decl_val.toValue() };
...@@ -36650,6 +36657,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -36650,6 +36657,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
36650 .simple_value,36657 .simple_value,
36651 .ptr_decl,36658 .ptr_decl,
36652 .ptr_anon_decl,36659 .ptr_anon_decl,
36660 .ptr_anon_decl_aligned,
36653 .ptr_mut_decl,36661 .ptr_mut_decl,
36654 .ptr_comptime_field,36662 .ptr_comptime_field,
36655 .ptr_int,36663 .ptr_int,
src/TypedValue.zig+2-1
...@@ -321,7 +321,8 @@ pub fn print(...@@ -321,7 +321,8 @@ pub fn print(
321 .val = decl.val,321 .val = decl.val,
322 }, writer, level - 1, mod);322 }, writer, level - 1, mod);
323 },323 },
324 .anon_decl => |decl_val| {324 .anon_decl => |anon_decl| {
325 const decl_val = anon_decl.val;
325 if (level == 0) return writer.print("(anon decl '{d}')", .{326 if (level == 0) return writer.print("(anon decl '{d}')", .{
326 @intFromEnum(decl_val),327 @intFromEnum(decl_val),
327 });328 });
src/arch/wasm/CodeGen.zig+13-4
...@@ -3139,16 +3139,25 @@ fn lowerParentPtrDecl(func: *CodeGen, ptr_val: Value, decl_index: Module.Decl.In...@@ -3139,16 +3139,25 @@ fn lowerParentPtrDecl(func: *CodeGen, ptr_val: Value, decl_index: Module.Decl.In
3139 return func.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index, offset);3139 return func.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index, offset);
3140}3140}
31413141
3142fn lowerAnonDeclRef(func: *CodeGen, anon_decl: InternPool.Index, offset: u32) InnerError!WValue {3142fn lowerAnonDeclRef(
3143 func: *CodeGen,
3144 anon_decl: InternPool.Key.Ptr.Addr.AnonDecl,
3145 offset: u32,
3146) InnerError!WValue {
3143 const mod = func.bin_file.base.options.module.?;3147 const mod = func.bin_file.base.options.module.?;
3144 const ty = mod.intern_pool.typeOf(anon_decl).toType();3148 const decl_val = anon_decl.val;
3149 const ty = mod.intern_pool.typeOf(decl_val).toType();
31453150
3146 const is_fn_body = ty.zigTypeTag(mod) == .Fn;3151 const is_fn_body = ty.zigTypeTag(mod) == .Fn;
3147 if (!is_fn_body and !ty.hasRuntimeBitsIgnoreComptime(mod)) {3152 if (!is_fn_body and !ty.hasRuntimeBitsIgnoreComptime(mod)) {
3148 return WValue{ .imm32 = 0xaaaaaaaa };3153 return WValue{ .imm32 = 0xaaaaaaaa };
3149 }3154 }
31503155
3151 const res = try func.bin_file.lowerAnonDecl(anon_decl, func.decl.srcLoc(mod));3156 const alignment = mod.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment;
3157 if (alignment != .none) {
3158 @panic("TODO how to make this anon decl be aligned?");
3159 }
3160 const res = try func.bin_file.lowerAnonDecl(decl_val, func.decl.srcLoc(mod));
3152 switch (res) {3161 switch (res) {
3153 .ok => {},3162 .ok => {},
3154 .fail => |em| {3163 .fail => |em| {
...@@ -3156,7 +3165,7 @@ fn lowerAnonDeclRef(func: *CodeGen, anon_decl: InternPool.Index, offset: u32) In...@@ -3156,7 +3165,7 @@ fn lowerAnonDeclRef(func: *CodeGen, anon_decl: InternPool.Index, offset: u32) In
3156 return error.CodegenFail;3165 return error.CodegenFail;
3157 },3166 },
3158 }3167 }
3159 const target_atom_index = func.bin_file.anon_decls.get(anon_decl).?;3168 const target_atom_index = func.bin_file.anon_decls.get(decl_val).?;
3160 const target_sym_index = func.bin_file.getAtom(target_atom_index).getSymbolIndex().?;3169 const target_sym_index = func.bin_file.getAtom(target_atom_index).getSymbolIndex().?;
3161 if (is_fn_body) {3170 if (is_fn_body) {
3162 return WValue{ .function_index = target_sym_index };3171 return WValue{ .function_index = target_sym_index };
src/codegen.zig+6-1
...@@ -713,7 +713,7 @@ const RelocInfo = struct {...@@ -713,7 +713,7 @@ const RelocInfo = struct {
713fn lowerAnonDeclRef(713fn lowerAnonDeclRef(
714 bin_file: *link.File,714 bin_file: *link.File,
715 src_loc: Module.SrcLoc,715 src_loc: Module.SrcLoc,
716 decl_val: InternPool.Index,716 anon_decl: InternPool.Key.Ptr.Addr.AnonDecl,
717 code: *std.ArrayList(u8),717 code: *std.ArrayList(u8),
718 debug_output: DebugInfoOutput,718 debug_output: DebugInfoOutput,
719 reloc_info: RelocInfo,719 reloc_info: RelocInfo,
...@@ -723,6 +723,7 @@ fn lowerAnonDeclRef(...@@ -723,6 +723,7 @@ fn lowerAnonDeclRef(
723 const mod = bin_file.options.module.?;723 const mod = bin_file.options.module.?;
724724
725 const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8);725 const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8);
726 const decl_val = anon_decl.val;
726 const decl_ty = mod.intern_pool.typeOf(decl_val).toType();727 const decl_ty = mod.intern_pool.typeOf(decl_val).toType();
727 const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn;728 const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn;
728 if (!is_fn_body and !decl_ty.hasRuntimeBits(mod)) {729 if (!is_fn_body and !decl_ty.hasRuntimeBits(mod)) {
...@@ -736,6 +737,10 @@ fn lowerAnonDeclRef(...@@ -736,6 +737,10 @@ fn lowerAnonDeclRef(
736 .fail => |em| return .{ .fail = em },737 .fail => |em| return .{ .fail = em },
737 }738 }
738739
740 const alignment = mod.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment;
741 if (alignment != .none) {
742 @panic("TODO how to make this anon decl be aligned?");
743 }
739 const vaddr = try bin_file.getAnonDeclVAddr(decl_val, .{744 const vaddr = try bin_file.getAnonDeclVAddr(decl_val, .{
740 .parent_atom_index = reloc_info.parent_atom_index,745 .parent_atom_index = reloc_info.parent_atom_index,
741 .offset = code.items.len,746 .offset = code.items.len,
src/codegen/c.zig+19-2
...@@ -531,6 +531,7 @@ pub const DeclGen = struct {...@@ -531,6 +531,7 @@ pub const DeclGen = struct {
531 /// Keeps track of anonymous decls that need to be rendered before this531 /// Keeps track of anonymous decls that need to be rendered before this
532 /// (named) Decl in the output C code.532 /// (named) Decl in the output C code.
533 anon_decl_deps: std.AutoArrayHashMapUnmanaged(InternPool.Index, C.DeclBlock),533 anon_decl_deps: std.AutoArrayHashMapUnmanaged(InternPool.Index, C.DeclBlock),
534 aligned_anon_decls: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),
534535
535 fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {536 fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {
536 @setCold(true);537 @setCold(true);
...@@ -548,11 +549,12 @@ pub const DeclGen = struct {...@@ -548,11 +549,12 @@ pub const DeclGen = struct {
548 writer: anytype,549 writer: anytype,
549 ty: Type,550 ty: Type,
550 ptr_val: Value,551 ptr_val: Value,
551 decl_val: InternPool.Index,552 anon_decl: InternPool.Key.Ptr.Addr.AnonDecl,
552 location: ValueRenderLocation,553 location: ValueRenderLocation,
553 ) error{ OutOfMemory, AnalysisFail }!void {554 ) error{ OutOfMemory, AnalysisFail }!void {
554 const mod = dg.module;555 const mod = dg.module;
555 const ip = &mod.intern_pool;556 const ip = &mod.intern_pool;
557 const decl_val = anon_decl.val;
556 const decl_ty = ip.typeOf(decl_val).toType();558 const decl_ty = ip.typeOf(decl_val).toType();
557559
558 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.560 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.
...@@ -592,8 +594,23 @@ pub const DeclGen = struct {...@@ -592,8 +594,23 @@ pub const DeclGen = struct {
592594
593 // Indicate that the anon decl should be rendered to the output so that595 // Indicate that the anon decl should be rendered to the output so that
594 // our reference above is not undefined.596 // our reference above is not undefined.
597 const ptr_type = ip.indexToKey(anon_decl.orig_ty).ptr_type;
595 const gop = try dg.anon_decl_deps.getOrPut(dg.gpa, decl_val);598 const gop = try dg.anon_decl_deps.getOrPut(dg.gpa, decl_val);
596 if (!gop.found_existing) gop.value_ptr.* = .{};599 if (!gop.found_existing) gop.value_ptr.* = .{};
600
601 // Only insert an alignment entry if the alignment is greater than ABI
602 // alignment. If there is already an entry, keep the greater alignment.
603 const explicit_alignment = ptr_type.flags.alignment;
604 if (explicit_alignment != .none) {
605 const abi_alignment = ptr_type.child.toType().abiAlignment(mod);
606 if (explicit_alignment.compareStrict(.gt, abi_alignment)) {
607 const aligned_gop = try dg.aligned_anon_decls.getOrPut(dg.gpa, decl_val);
608 aligned_gop.value_ptr.* = if (aligned_gop.found_existing)
609 aligned_gop.value_ptr.maxStrict(explicit_alignment)
610 else
611 explicit_alignment;
612 }
613 }
597 }614 }
598615
599 fn renderDeclValue(616 fn renderDeclValue(
...@@ -651,7 +668,7 @@ pub const DeclGen = struct {...@@ -651,7 +668,7 @@ pub const DeclGen = struct {
651 switch (ptr.addr) {668 switch (ptr.addr) {
652 .decl => |d| try dg.renderDeclValue(writer, ptr_ty, ptr_val.toValue(), d, location),669 .decl => |d| try dg.renderDeclValue(writer, ptr_ty, ptr_val.toValue(), d, location),
653 .mut_decl => |md| try dg.renderDeclValue(writer, ptr_ty, ptr_val.toValue(), md.decl, location),670 .mut_decl => |md| try dg.renderDeclValue(writer, ptr_ty, ptr_val.toValue(), md.decl, location),
654 .anon_decl => |decl_val| try dg.renderAnonDeclValue(writer, ptr_ty, ptr_val.toValue(), decl_val, location),671 .anon_decl => |anon_decl| try dg.renderAnonDeclValue(writer, ptr_ty, ptr_val.toValue(), anon_decl, location),
655 .int => |int| {672 .int => |int| {
656 try writer.writeByte('(');673 try writer.writeByte('(');
657 try dg.renderCType(writer, ptr_cty);674 try dg.renderCType(writer, ptr_cty);
src/codegen/llvm.zig+16-15
...@@ -3051,9 +3051,17 @@ pub const Object = struct {...@@ -3051,9 +3051,17 @@ pub const Object = struct {
3051 llvm_addr_space: Builder.AddrSpace,3051 llvm_addr_space: Builder.AddrSpace,
3052 alignment: InternPool.Alignment,3052 alignment: InternPool.Alignment,
3053 ) Error!Builder.Variable.Index {3053 ) Error!Builder.Variable.Index {
3054 assert(alignment != .none);
3054 // TODO: Add address space to the anon_decl_map3055 // TODO: Add address space to the anon_decl_map
3055 const gop = try o.anon_decl_map.getOrPut(o.gpa, decl_val);3056 const gop = try o.anon_decl_map.getOrPut(o.gpa, decl_val);
3056 if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.variable;3057 if (gop.found_existing) {
3058 // Keep the greater of the two alignments.
3059 const variable_index = gop.value_ptr.ptr(&o.builder).kind.variable;
3060 const old_alignment = InternPool.Alignment.fromLlvm(variable_index.getAlignment(&o.builder));
3061 const max_alignment = old_alignment.maxStrict(alignment);
3062 variable_index.setAlignment(max_alignment.toLlvm(), &o.builder);
3063 return variable_index;
3064 }
3057 errdefer assert(o.anon_decl_map.remove(decl_val));3065 errdefer assert(o.anon_decl_map.remove(decl_val));
30583066
3059 const mod = o.module;3067 const mod = o.module;
...@@ -3069,8 +3077,7 @@ pub const Object = struct {...@@ -3069,8 +3077,7 @@ pub const Object = struct {
3069 try variable_index.setInitializer(try o.lowerValue(decl_val), &o.builder);3077 try variable_index.setInitializer(try o.lowerValue(decl_val), &o.builder);
3070 variable_index.setLinkage(.internal, &o.builder);3078 variable_index.setLinkage(.internal, &o.builder);
3071 variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);3079 variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);
3072 if (alignment != .none)3080 variable_index.setAlignment(alignment.toLlvm(), &o.builder);
3073 variable_index.setAlignment(alignment.toLlvm(), &o.builder);
3074 return variable_index;3081 return variable_index;
3075 }3082 }
30763083
...@@ -4253,13 +4260,6 @@ pub const Object = struct {...@@ -4253,13 +4260,6 @@ pub const Object = struct {
4253 return o.builder.bigIntConst(try o.builder.intType(ty.intInfo(mod).bits), bigint);4260 return o.builder.bigIntConst(try o.builder.intType(ty.intInfo(mod).bits), bigint);
4254 }4261 }
42554262
4256 fn lowerParentPtrAnonDecl(o: *Object, decl_val: InternPool.Index) Error!Builder.Constant {
4257 const mod = o.module;
4258 const decl_ty = mod.intern_pool.typeOf(decl_val).toType();
4259 const ptr_ty = try mod.singleMutPtrType(decl_ty);
4260 return o.lowerAnonDeclRef(ptr_ty, decl_val);
4261 }
4262
4263 fn lowerParentPtrDecl(o: *Object, decl_index: Module.Decl.Index) Allocator.Error!Builder.Constant {4263 fn lowerParentPtrDecl(o: *Object, decl_index: Module.Decl.Index) Allocator.Error!Builder.Constant {
4264 const mod = o.module;4264 const mod = o.module;
4265 const decl = mod.declPtr(decl_index);4265 const decl = mod.declPtr(decl_index);
...@@ -4275,7 +4275,7 @@ pub const Object = struct {...@@ -4275,7 +4275,7 @@ pub const Object = struct {
4275 return switch (ptr.addr) {4275 return switch (ptr.addr) {
4276 .decl => |decl| try o.lowerParentPtrDecl(decl),4276 .decl => |decl| try o.lowerParentPtrDecl(decl),
4277 .mut_decl => |mut_decl| try o.lowerParentPtrDecl(mut_decl.decl),4277 .mut_decl => |mut_decl| try o.lowerParentPtrDecl(mut_decl.decl),
4278 .anon_decl => |anon_decl| try o.lowerParentPtrAnonDecl(anon_decl),4278 .anon_decl => |ad| try o.lowerAnonDeclRef(ad.orig_ty.toType(), ad),
4279 .int => |int| try o.lowerIntAsPtr(int),4279 .int => |int| try o.lowerIntAsPtr(int),
4280 .eu_payload => |eu_ptr| {4280 .eu_payload => |eu_ptr| {
4281 const parent_ptr = try o.lowerParentPtr(eu_ptr.toValue());4281 const parent_ptr = try o.lowerParentPtr(eu_ptr.toValue());
...@@ -4394,10 +4394,11 @@ pub const Object = struct {...@@ -4394,10 +4394,11 @@ pub const Object = struct {
4394 fn lowerAnonDeclRef(4394 fn lowerAnonDeclRef(
4395 o: *Object,4395 o: *Object,
4396 ptr_ty: Type,4396 ptr_ty: Type,
4397 decl_val: InternPool.Index,4397 anon_decl: InternPool.Key.Ptr.Addr.AnonDecl,
4398 ) Error!Builder.Constant {4398 ) Error!Builder.Constant {
4399 const mod = o.module;4399 const mod = o.module;
4400 const ip = &mod.intern_pool;4400 const ip = &mod.intern_pool;
4401 const decl_val = anon_decl.val;
4401 const decl_ty = ip.typeOf(decl_val).toType();4402 const decl_ty = ip.typeOf(decl_val).toType();
4402 const target = mod.getTarget();4403 const target = mod.getTarget();
44034404
...@@ -4416,9 +4417,9 @@ pub const Object = struct {...@@ -4416,9 +4417,9 @@ pub const Object = struct {
4416 if (is_fn_body)4417 if (is_fn_body)
4417 @panic("TODO");4418 @panic("TODO");
44184419
4419 const addr_space = target_util.defaultAddressSpace(target, .global_constant);4420 const orig_ty = anon_decl.orig_ty.toType();
4420 const llvm_addr_space = toLlvmAddressSpace(addr_space, target);4421 const llvm_addr_space = toLlvmAddressSpace(orig_ty.ptrAddressSpace(mod), target);
4421 const alignment = ptr_ty.ptrAlignment(mod);4422 const alignment = orig_ty.ptrAlignment(mod);
4422 const llvm_global = (try o.resolveGlobalAnonDecl(decl_val, llvm_addr_space, alignment)).ptrConst(&o.builder).global;4423 const llvm_global = (try o.resolveGlobalAnonDecl(decl_val, llvm_addr_space, alignment)).ptrConst(&o.builder).global;
44234424
4424 const llvm_val = try o.builder.convConst(4425 const llvm_val = try o.builder.convConst(
src/codegen/llvm/Builder.zig+6
...@@ -2477,6 +2477,12 @@ pub const Variable = struct {...@@ -2477,6 +2477,12 @@ pub const Variable = struct {
2477 self.ptr(builder).alignment = alignment;2477 self.ptr(builder).alignment = alignment;
2478 }2478 }
24792479
2480 pub fn getAlignment(self: Index, builder: *Builder) Alignment {
2481 if (builder.useLibLlvm())
2482 return Alignment.fromByteUnits(self.toLlvm(builder).getAlignment());
2483 return self.ptr(builder).alignment;
2484 }
2485
2480 pub fn toLlvm(self: Index, builder: *const Builder) *llvm.Value {2486 pub fn toLlvm(self: Index, builder: *const Builder) *llvm.Value {
2481 return self.ptrConst(builder).global.toLlvm(builder);2487 return self.ptrConst(builder).global.toLlvm(builder);
2482 }2488 }
src/codegen/llvm/bindings.zig+3
...@@ -273,6 +273,9 @@ pub const Value = opaque {...@@ -273,6 +273,9 @@ pub const Value = opaque {
273 pub const setAlignment = LLVMSetAlignment;273 pub const setAlignment = LLVMSetAlignment;
274 extern fn LLVMSetAlignment(V: *Value, Bytes: c_uint) void;274 extern fn LLVMSetAlignment(V: *Value, Bytes: c_uint) void;
275275
276 pub const getAlignment = LLVMGetAlignment;
277 extern fn LLVMGetAlignment(V: *Value) c_uint;
278
276 pub const setFunctionCallConv = LLVMSetFunctionCallConv;279 pub const setFunctionCallConv = LLVMSetFunctionCallConv;
277 extern fn LLVMSetFunctionCallConv(Fn: *Value, CC: CallConv) void;280 extern fn LLVMSetFunctionCallConv(Fn: *Value, CC: CallConv) void;
278281
src/codegen/spirv.zig+6-1
...@@ -959,12 +959,17 @@ const DeclGen = struct {...@@ -959,12 +959,17 @@ const DeclGen = struct {
959 }959 }
960 }960 }
961961
962 fn constantAnonDeclRef(self: *DeclGen, ty: Type, decl_val: InternPool.Index) !IdRef {962 fn constantAnonDeclRef(
963 self: *DeclGen,
964 ty: Type,
965 anon_decl: InternPool.Key.Ptr.Addr.AnonDecl,
966 ) !IdRef {
963 // TODO: Merge this function with constantDeclRef.967 // TODO: Merge this function with constantDeclRef.
964968
965 const mod = self.module;969 const mod = self.module;
966 const ip = &mod.intern_pool;970 const ip = &mod.intern_pool;
967 const ty_ref = try self.resolveType(ty, .direct);971 const ty_ref = try self.resolveType(ty, .direct);
972 const decl_val = anon_decl.val;
968 const decl_ty = ip.typeOf(decl_val).toType();973 const decl_ty = ip.typeOf(decl_val).toType();
969974
970 if (decl_val.toValue().getFunction(mod)) |func| {975 if (decl_val.toValue().getFunction(mod)) |func| {
src/link/C.zig+18-1
...@@ -7,6 +7,7 @@ const fs = std.fs;...@@ -7,6 +7,7 @@ const fs = std.fs;
7const C = @This();7const C = @This();
8const Module = @import("../Module.zig");8const Module = @import("../Module.zig");
9const InternPool = @import("../InternPool.zig");9const InternPool = @import("../InternPool.zig");
10const Alignment = InternPool.Alignment;
10const Compilation = @import("../Compilation.zig");11const Compilation = @import("../Compilation.zig");
11const codegen = @import("../codegen/c.zig");12const codegen = @import("../codegen/c.zig");
12const link = @import("../link.zig");13const link = @import("../link.zig");
...@@ -30,6 +31,10 @@ string_bytes: std.ArrayListUnmanaged(u8) = .{},...@@ -30,6 +31,10 @@ string_bytes: std.ArrayListUnmanaged(u8) = .{},
30/// Tracks all the anonymous decls that are used by all the decls so they can31/// Tracks all the anonymous decls that are used by all the decls so they can
31/// be rendered during flush().32/// be rendered during flush().
32anon_decls: std.AutoArrayHashMapUnmanaged(InternPool.Index, DeclBlock) = .{},33anon_decls: std.AutoArrayHashMapUnmanaged(InternPool.Index, DeclBlock) = .{},
34/// Sparse set of anon decls that are overaligned. Underaligned anon decls are
35/// lowered the same as ABI-aligned anon decls. The keys here are a subset of
36/// the keys of `anon_decls`.
37aligned_anon_decls: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment) = .{},
3338
34/// Optimization, `updateDecl` reuses this buffer rather than creating a new39/// Optimization, `updateDecl` reuses this buffer rather than creating a new
35/// one with every call.40/// one with every call.
...@@ -125,6 +130,7 @@ pub fn deinit(self: *C) void {...@@ -125,6 +130,7 @@ pub fn deinit(self: *C) void {
125 db.deinit(gpa);130 db.deinit(gpa);
126 }131 }
127 self.anon_decls.deinit(gpa);132 self.anon_decls.deinit(gpa);
133 self.aligned_anon_decls.deinit(gpa);
128134
129 self.string_bytes.deinit(gpa);135 self.string_bytes.deinit(gpa);
130 self.fwd_decl_buf.deinit(gpa);136 self.fwd_decl_buf.deinit(gpa);
...@@ -179,6 +185,7 @@ pub fn updateFunc(...@@ -179,6 +185,7 @@ pub fn updateFunc(
179 .fwd_decl = fwd_decl.toManaged(gpa),185 .fwd_decl = fwd_decl.toManaged(gpa),
180 .ctypes = ctypes.*,186 .ctypes = ctypes.*,
181 .anon_decl_deps = self.anon_decls,187 .anon_decl_deps = self.anon_decls,
188 .aligned_anon_decls = self.aligned_anon_decls,
182 },189 },
183 .code = code.toManaged(gpa),190 .code = code.toManaged(gpa),
184 .indent_writer = undefined, // set later so we can get a pointer to object.code191 .indent_writer = undefined, // set later so we can get a pointer to object.code
...@@ -189,6 +196,7 @@ pub fn updateFunc(...@@ -189,6 +196,7 @@ pub fn updateFunc(
189 function.object.indent_writer = .{ .underlying_writer = function.object.code.writer() };196 function.object.indent_writer = .{ .underlying_writer = function.object.code.writer() };
190 defer {197 defer {
191 self.anon_decls = function.object.dg.anon_decl_deps;198 self.anon_decls = function.object.dg.anon_decl_deps;
199 self.aligned_anon_decls = function.object.dg.aligned_anon_decls;
192 fwd_decl.* = function.object.dg.fwd_decl.moveToUnmanaged();200 fwd_decl.* = function.object.dg.fwd_decl.moveToUnmanaged();
193 code.* = function.object.code.moveToUnmanaged();201 code.* = function.object.code.moveToUnmanaged();
194 function.deinit();202 function.deinit();
...@@ -232,6 +240,7 @@ fn updateAnonDecl(self: *C, module: *Module, i: usize) !void {...@@ -232,6 +240,7 @@ fn updateAnonDecl(self: *C, module: *Module, i: usize) !void {
232 .fwd_decl = fwd_decl.toManaged(gpa),240 .fwd_decl = fwd_decl.toManaged(gpa),
233 .ctypes = .{},241 .ctypes = .{},
234 .anon_decl_deps = self.anon_decls,242 .anon_decl_deps = self.anon_decls,
243 .aligned_anon_decls = self.aligned_anon_decls,
235 },244 },
236 .code = code.toManaged(gpa),245 .code = code.toManaged(gpa),
237 .indent_writer = undefined, // set later so we can get a pointer to object.code246 .indent_writer = undefined, // set later so we can get a pointer to object.code
...@@ -240,6 +249,7 @@ fn updateAnonDecl(self: *C, module: *Module, i: usize) !void {...@@ -240,6 +249,7 @@ fn updateAnonDecl(self: *C, module: *Module, i: usize) !void {
240249
241 defer {250 defer {
242 self.anon_decls = object.dg.anon_decl_deps;251 self.anon_decls = object.dg.anon_decl_deps;
252 self.aligned_anon_decls = object.dg.aligned_anon_decls;
243 object.dg.ctypes.deinit(object.dg.gpa);253 object.dg.ctypes.deinit(object.dg.gpa);
244 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();254 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();
245 code.* = object.code.moveToUnmanaged();255 code.* = object.code.moveToUnmanaged();
...@@ -250,7 +260,8 @@ fn updateAnonDecl(self: *C, module: *Module, i: usize) !void {...@@ -250,7 +260,8 @@ fn updateAnonDecl(self: *C, module: *Module, i: usize) !void {
250 .val = anon_decl.toValue(),260 .val = anon_decl.toValue(),
251 };261 };
252 const c_value: codegen.CValue = .{ .constant = anon_decl };262 const c_value: codegen.CValue = .{ .constant = anon_decl };
253 codegen.genDeclValue(&object, tv, false, c_value, .none, .none) catch |err| switch (err) {263 const alignment: Alignment = self.aligned_anon_decls.get(anon_decl) orelse .none;
264 codegen.genDeclValue(&object, tv, false, c_value, alignment, .none) catch |err| switch (err) {
254 error.AnalysisFail => {265 error.AnalysisFail => {
255 @panic("TODO: C backend AnalysisFail on anonymous decl");266 @panic("TODO: C backend AnalysisFail on anonymous decl");
256 //try module.failed_decls.put(gpa, decl_index, object.dg.error_msg.?);267 //try module.failed_decls.put(gpa, decl_index, object.dg.error_msg.?);
...@@ -296,6 +307,7 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi...@@ -296,6 +307,7 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi
296 .fwd_decl = fwd_decl.toManaged(gpa),307 .fwd_decl = fwd_decl.toManaged(gpa),
297 .ctypes = ctypes.*,308 .ctypes = ctypes.*,
298 .anon_decl_deps = self.anon_decls,309 .anon_decl_deps = self.anon_decls,
310 .aligned_anon_decls = self.aligned_anon_decls,
299 },311 },
300 .code = code.toManaged(gpa),312 .code = code.toManaged(gpa),
301 .indent_writer = undefined, // set later so we can get a pointer to object.code313 .indent_writer = undefined, // set later so we can get a pointer to object.code
...@@ -303,6 +315,7 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi...@@ -303,6 +315,7 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi
303 object.indent_writer = .{ .underlying_writer = object.code.writer() };315 object.indent_writer = .{ .underlying_writer = object.code.writer() };
304 defer {316 defer {
305 self.anon_decls = object.dg.anon_decl_deps;317 self.anon_decls = object.dg.anon_decl_deps;
318 self.aligned_anon_decls = object.dg.aligned_anon_decls;
306 object.dg.ctypes.deinit(object.dg.gpa);319 object.dg.ctypes.deinit(object.dg.gpa);
307 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();320 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();
308 code.* = object.code.moveToUnmanaged();321 code.* = object.code.moveToUnmanaged();
...@@ -602,6 +615,7 @@ fn flushErrDecls(self: *C, ctypes: *codegen.CType.Store) FlushDeclError!void {...@@ -602,6 +615,7 @@ fn flushErrDecls(self: *C, ctypes: *codegen.CType.Store) FlushDeclError!void {
602 .fwd_decl = fwd_decl.toManaged(gpa),615 .fwd_decl = fwd_decl.toManaged(gpa),
603 .ctypes = ctypes.*,616 .ctypes = ctypes.*,
604 .anon_decl_deps = self.anon_decls,617 .anon_decl_deps = self.anon_decls,
618 .aligned_anon_decls = self.aligned_anon_decls,
605 },619 },
606 .code = code.toManaged(gpa),620 .code = code.toManaged(gpa),
607 .indent_writer = undefined, // set later so we can get a pointer to object.code621 .indent_writer = undefined, // set later so we can get a pointer to object.code
...@@ -609,6 +623,7 @@ fn flushErrDecls(self: *C, ctypes: *codegen.CType.Store) FlushDeclError!void {...@@ -609,6 +623,7 @@ fn flushErrDecls(self: *C, ctypes: *codegen.CType.Store) FlushDeclError!void {
609 object.indent_writer = .{ .underlying_writer = object.code.writer() };623 object.indent_writer = .{ .underlying_writer = object.code.writer() };
610 defer {624 defer {
611 self.anon_decls = object.dg.anon_decl_deps;625 self.anon_decls = object.dg.anon_decl_deps;
626 self.aligned_anon_decls = object.dg.aligned_anon_decls;
612 object.dg.ctypes.deinit(gpa);627 object.dg.ctypes.deinit(gpa);
613 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();628 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();
614 code.* = object.code.moveToUnmanaged();629 code.* = object.code.moveToUnmanaged();
...@@ -642,6 +657,7 @@ fn flushLazyFn(...@@ -642,6 +657,7 @@ fn flushLazyFn(
642 .fwd_decl = fwd_decl.toManaged(gpa),657 .fwd_decl = fwd_decl.toManaged(gpa),
643 .ctypes = ctypes.*,658 .ctypes = ctypes.*,
644 .anon_decl_deps = .{},659 .anon_decl_deps = .{},
660 .aligned_anon_decls = .{},
645 },661 },
646 .code = code.toManaged(gpa),662 .code = code.toManaged(gpa),
647 .indent_writer = undefined, // set later so we can get a pointer to object.code663 .indent_writer = undefined, // set later so we can get a pointer to object.code
...@@ -651,6 +667,7 @@ fn flushLazyFn(...@@ -651,6 +667,7 @@ fn flushLazyFn(
651 // If this assert trips just handle the anon_decl_deps the same as667 // If this assert trips just handle the anon_decl_deps the same as
652 // `updateFunc()` does.668 // `updateFunc()` does.
653 assert(object.dg.anon_decl_deps.count() == 0);669 assert(object.dg.anon_decl_deps.count() == 0);
670 assert(object.dg.aligned_anon_decls.count() == 0);
654 object.dg.ctypes.deinit(gpa);671 object.dg.ctypes.deinit(gpa);
655 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();672 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();
656 code.* = object.code.moveToUnmanaged();673 code.* = object.code.moveToUnmanaged();
src/value.zig+2-2
...@@ -1571,7 +1571,7 @@ pub const Value = struct {...@@ -1571,7 +1571,7 @@ pub const Value = struct {
1571 .none => switch (ip.indexToKey(switch (ptr.addr) {1571 .none => switch (ip.indexToKey(switch (ptr.addr) {
1572 .decl => |decl| mod.declPtr(decl).ty.toIntern(),1572 .decl => |decl| mod.declPtr(decl).ty.toIntern(),
1573 .mut_decl => |mut_decl| mod.declPtr(mut_decl.decl).ty.toIntern(),1573 .mut_decl => |mut_decl| mod.declPtr(mut_decl.decl).ty.toIntern(),
1574 .anon_decl => |anon_decl| ip.typeOf(anon_decl),1574 .anon_decl => |anon_decl| ip.typeOf(anon_decl.val),
1575 .comptime_field => |comptime_field| ip.typeOf(comptime_field),1575 .comptime_field => |comptime_field| ip.typeOf(comptime_field),
1576 else => unreachable,1576 else => unreachable,
1577 })) {1577 })) {
...@@ -1604,7 +1604,7 @@ pub const Value = struct {...@@ -1604,7 +1604,7 @@ pub const Value = struct {
1604 })).toValue(),1604 })).toValue(),
1605 .ptr => |ptr| switch (ptr.addr) {1605 .ptr => |ptr| switch (ptr.addr) {
1606 .decl => |decl| mod.declPtr(decl).val.maybeElemValue(mod, index),1606 .decl => |decl| mod.declPtr(decl).val.maybeElemValue(mod, index),
1607 .anon_decl => |anon_decl| anon_decl.toValue().maybeElemValue(mod, index),1607 .anon_decl => |anon_decl| anon_decl.val.toValue().maybeElemValue(mod, index),
1608 .mut_decl => |mut_decl| (try mod.declPtr(mut_decl.decl).internValue(mod))1608 .mut_decl => |mut_decl| (try mod.declPtr(mut_decl.decl).internValue(mod))
1609 .toValue().maybeElemValue(mod, index),1609 .toValue().maybeElemValue(mod, index),
1610 .int, .eu_payload => null,1610 .int, .eu_payload => null,