authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-10-26 03:49:16-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-10-26 03:49:16-04:00
logba817fae8f5f71469ae6ac70fc61b9d3a0e19335
tree03ab9b4214484497990249099af9b41b292f350a
parentcc394431ae6eb69e7abd677c268a8ab7299f8aeb
parentcf9735a5e06d302a29d70c737aefd505ca34e0fa
signature Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #17690

Sema: move remaining anon decls to new mechanism

8 files changed, 428 insertions(+), 525 deletions(-)

src/Compilation.zig+1-1
...@@ -3556,7 +3556,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v...@@ -3556,7 +3556,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v
3556 .gpa = gpa,3556 .gpa = gpa,
3557 .module = module,3557 .module = module,
3558 .error_msg = null,3558 .error_msg = null,
3559 .decl_index = decl_index.toOptional(),3559 .pass = .{ .decl = decl_index },
3560 .is_naked_fn = false,3560 .is_naked_fn = false,
3561 .fwd_decl = fwd_decl.toManaged(gpa),3561 .fwd_decl = fwd_decl.toManaged(gpa),
3562 .ctypes = .{},3562 .ctypes = .{},
src/Sema.zig+216-339
...@@ -5466,21 +5466,30 @@ fn addStrLitNoAlias(sema: *Sema, bytes: []const u8) CompileError!Air.Inst.Ref {...@@ -5466,21 +5466,30 @@ fn addStrLitNoAlias(sema: *Sema, bytes: []const u8) CompileError!Air.Inst.Ref {
5466 .ty = array_ty.toIntern(),5466 .ty = array_ty.toIntern(),
5467 .storage = .{ .bytes = bytes },5467 .storage = .{ .bytes = bytes },
5468 } });5468 } });
5469 const ptr_ty = try sema.ptrType(.{5469 return anonDeclRef(sema, val);
5470 .child = array_ty.toIntern(),5470}
5471
5472fn anonDeclRef(sema: *Sema, val: InternPool.Index) CompileError!Air.Inst.Ref {
5473 return Air.internedToRef(try refValue(sema, val));
5474}
5475
5476fn refValue(sema: *Sema, val: InternPool.Index) CompileError!InternPool.Index {
5477 const mod = sema.mod;
5478 const ptr_ty = (try sema.ptrType(.{
5479 .child = mod.intern_pool.typeOf(val),
5471 .flags = .{5480 .flags = .{
5472 .alignment = .none,5481 .alignment = .none,
5473 .is_const = true,5482 .is_const = true,
5474 .address_space = .generic,5483 .address_space = .generic,
5475 },5484 },
5476 });5485 })).toIntern();
5477 return Air.internedToRef((try mod.intern(.{ .ptr = .{5486 return mod.intern(.{ .ptr = .{
5478 .ty = ptr_ty.toIntern(),5487 .ty = ptr_ty,
5479 .addr = .{ .anon_decl = .{5488 .addr = .{ .anon_decl = .{
5480 .val = val,5489 .val = val,
5481 .orig_ty = ptr_ty.toIntern(),5490 .orig_ty = ptr_ty,
5482 } },5491 } },
5483 } })));5492 } });
5484}5493}
54855494
5486fn zirInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {5495fn zirInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -10740,7 +10749,7 @@ const SwitchProngAnalysis = struct {...@@ -10740,7 +10749,7 @@ const SwitchProngAnalysis = struct {
10740 return block.addStructFieldVal(spa.operand, field_index, field_ty);10749 return block.addStructFieldVal(spa.operand, field_index, field_ty);
10741 }10750 }
10742 } else if (capture_byref) {10751 } else if (capture_byref) {
10743 return sema.addConstantMaybeRef(block, operand_ty, item_val, true);10752 return anonDeclRef(sema, item_val.toIntern());
10744 } else {10753 } else {
10745 return inline_case_capture;10754 return inline_case_capture;
10746 }10755 }
...@@ -13765,10 +13774,10 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13765,10 +13774,10 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13765 const coerced_elem_val = try sema.resolveConstValue(block, .unneeded, coerced_elem_val_inst, undefined);13774 const coerced_elem_val = try sema.resolveConstValue(block, .unneeded, coerced_elem_val_inst, undefined);
13766 element_vals[elem_i] = try coerced_elem_val.intern(resolved_elem_ty, mod);13775 element_vals[elem_i] = try coerced_elem_val.intern(resolved_elem_ty, mod);
13767 }13776 }
13768 return sema.addConstantMaybeRef(block, result_ty, (try mod.intern(.{ .aggregate = .{13777 return sema.addConstantMaybeRef(try mod.intern(.{ .aggregate = .{
13769 .ty = result_ty.toIntern(),13778 .ty = result_ty.toIntern(),
13770 .storage = .{ .elems = element_vals },13779 .storage = .{ .elems = element_vals },
13771 } })).toValue(), ptr_addrspace != null);13780 } }), ptr_addrspace != null);
13772 } else break :rs rhs_src;13781 } else break :rs rhs_src;
13773 } else lhs_src;13782 } else lhs_src;
1377413783
...@@ -14034,7 +14043,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14034,7 +14043,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14034 .storage = .{ .elems = element_vals },14043 .storage = .{ .elems = element_vals },
14035 } });14044 } });
14036 };14045 };
14037 return sema.addConstantMaybeRef(block, result_ty, val.toValue(), ptr_addrspace != null);14046 return sema.addConstantMaybeRef(val, ptr_addrspace != null);
14038 }14047 }
1403914048
14040 try sema.requireRuntimeBlock(block, src, lhs_src);14049 try sema.requireRuntimeBlock(block, src, lhs_src);
...@@ -16724,54 +16733,49 @@ fn zirBuiltinSrc(...@@ -16724,54 +16733,49 @@ fn zirBuiltinSrc(
16724 const src = LazySrcLoc.nodeOffset(extra.node);16733 const src = LazySrcLoc.nodeOffset(extra.node);
16725 if (sema.func_index == .none) return sema.fail(block, src, "@src outside function", .{});16734 if (sema.func_index == .none) return sema.fail(block, src, "@src outside function", .{});
16726 const fn_owner_decl = mod.funcOwnerDeclPtr(sema.func_index);16735 const fn_owner_decl = mod.funcOwnerDeclPtr(sema.func_index);
16736 const ip = &mod.intern_pool;
16737 const gpa = sema.gpa;
1672716738
16728 const func_name_val = blk: {16739 const func_name_val = v: {
16729 var anon_decl = try block.startAnonDecl();16740 // This dupe prevents InternPool string pool memory from being reallocated
16730 defer anon_decl.deinit();16741 // while a reference exists.
16731 // TODO: write something like getCoercedInts to avoid needing to dupe16742 const bytes = try sema.arena.dupe(u8, ip.stringToSlice(fn_owner_decl.name));
16732 const name = try sema.arena.dupe(u8, mod.intern_pool.stringToSlice(fn_owner_decl.name));16743 const array_ty = try ip.get(gpa, .{ .array_type = .{
16733 const new_decl_ty = try mod.arrayType(.{16744 .len = bytes.len,
16734 .len = name.len,
16735 .sentinel = .zero_u8,16745 .sentinel = .zero_u8,
16736 .child = .u8_type,16746 .child = .u8_type,
16737 });16747 } });
16738 const new_decl = try anon_decl.finish(16748 break :v try ip.get(gpa, .{ .ptr = .{
16739 new_decl_ty,
16740 (try mod.intern(.{ .aggregate = .{
16741 .ty = new_decl_ty.toIntern(),
16742 .storage = .{ .bytes = name },
16743 } })).toValue(),
16744 .none, // default alignment
16745 );
16746 break :blk try mod.intern(.{ .ptr = .{
16747 .ty = .slice_const_u8_sentinel_0_type,16749 .ty = .slice_const_u8_sentinel_0_type,
16748 .addr = .{ .decl = new_decl },16750 .len = (try mod.intValue(Type.usize, bytes.len)).toIntern(),
16749 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),16751 .addr = .{ .anon_decl = .{
16752 .orig_ty = .slice_const_u8_sentinel_0_type,
16753 .val = try ip.get(gpa, .{ .aggregate = .{
16754 .ty = array_ty,
16755 .storage = .{ .bytes = bytes },
16756 } }),
16757 } },
16750 } });16758 } });
16751 };16759 };
1675216760
16753 const file_name_val = blk: {16761 const file_name_val = v: {
16754 var anon_decl = try block.startAnonDecl();
16755 defer anon_decl.deinit();
16756 // The compiler must not call realpath anywhere.16762 // The compiler must not call realpath anywhere.
16757 const name = try fn_owner_decl.getFileScope(mod).fullPathZ(sema.arena);16763 const bytes = try fn_owner_decl.getFileScope(mod).fullPathZ(sema.arena);
16758 const new_decl_ty = try mod.arrayType(.{16764 const array_ty = try ip.get(gpa, .{ .array_type = .{
16759 .len = name.len,16765 .len = bytes.len,
16760 .sentinel = .zero_u8,16766 .sentinel = .zero_u8,
16761 .child = .u8_type,16767 .child = .u8_type,
16762 });16768 } });
16763 const new_decl = try anon_decl.finish(16769 break :v try ip.get(gpa, .{ .ptr = .{
16764 new_decl_ty,
16765 (try mod.intern(.{ .aggregate = .{
16766 .ty = new_decl_ty.toIntern(),
16767 .storage = .{ .bytes = name },
16768 } })).toValue(),
16769 .none, // default alignment
16770 );
16771 break :blk try mod.intern(.{ .ptr = .{
16772 .ty = .slice_const_u8_sentinel_0_type,16770 .ty = .slice_const_u8_sentinel_0_type,
16773 .addr = .{ .decl = new_decl },16771 .len = (try mod.intValue(Type.usize, bytes.len)).toIntern(),
16774 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),16772 .addr = .{ .anon_decl = .{
16773 .orig_ty = .slice_const_u8_sentinel_0_type,
16774 .val = try ip.get(gpa, .{ .aggregate = .{
16775 .ty = array_ty,
16776 .storage = .{ .bytes = bytes },
16777 } }),
16778 } },
16775 } });16779 } });
16776 };16780 };
1677716781
...@@ -16818,10 +16822,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16818,10 +16822,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16818 .val = .void_value,16822 .val = .void_value,
16819 } }))),16823 } }))),
16820 .Fn => {16824 .Fn => {
16821 // TODO: look into memoizing this result.
16822 var params_anon_decl = try block.startAnonDecl();
16823 defer params_anon_decl.deinit();
16824
16825 const fn_info_decl_index = (try sema.namespaceLookup(16825 const fn_info_decl_index = (try sema.namespaceLookup(
16826 block,16826 block,
16827 src,16827 src,
...@@ -16878,23 +16878,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16878,23 +16878,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16878 .len = param_vals.len,16878 .len = param_vals.len,
16879 .child = param_info_ty.toIntern(),16879 .child = param_info_ty.toIntern(),
16880 });16880 });
16881 const new_decl = try params_anon_decl.finish(16881 const new_decl_val = try mod.intern(.{ .aggregate = .{
16882 new_decl_ty,16882 .ty = new_decl_ty.toIntern(),
16883 (try mod.intern(.{ .aggregate = .{16883 .storage = .{ .elems = param_vals },
16884 .ty = new_decl_ty.toIntern(),16884 } });
16885 .storage = .{ .elems = param_vals },16885 const ptr_ty = (try sema.ptrType(.{
16886 } })).toValue(),16886 .child = param_info_ty.toIntern(),
16887 .none, // default alignment16887 .flags = .{
16888 );16888 .size = .Slice,
16889 .is_const = true,
16890 },
16891 })).toIntern();
16889 break :v try mod.intern(.{ .ptr = .{16892 break :v try mod.intern(.{ .ptr = .{
16890 .ty = (try sema.ptrType(.{16893 .ty = ptr_ty,
16891 .child = param_info_ty.toIntern(),16894 .addr = .{ .anon_decl = .{
16892 .flags = .{16895 .orig_ty = ptr_ty,
16893 .size = .Slice,16896 .val = new_decl_val,
16894 .is_const = true,16897 } },
16895 },
16896 })).toIntern(),
16897 .addr = .{ .decl = new_decl },
16898 .len = (try mod.intValue(Type.usize, param_vals.len)).toIntern(),16898 .len = (try mod.intValue(Type.usize, param_vals.len)).toIntern(),
16899 } });16899 } });
16900 };16900 };
...@@ -17035,7 +17035,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17035,7 +17035,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17035 // is_allowzero: bool,17035 // is_allowzero: bool,
17036 Value.makeBool(info.flags.is_allowzero).toIntern(),17036 Value.makeBool(info.flags.is_allowzero).toIntern(),
17037 // sentinel: ?*const anyopaque,17037 // sentinel: ?*const anyopaque,
17038 (try sema.optRefValue(block, info.child.toType(), switch (info.sentinel) {17038 (try sema.optRefValue(switch (info.sentinel) {
17039 .none => null,17039 .none => null,
17040 else => info.sentinel.toValue(),17040 else => info.sentinel.toValue(),
17041 })).toIntern(),17041 })).toIntern(),
...@@ -17070,7 +17070,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17070,7 +17070,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17070 // child: type,17070 // child: type,
17071 info.elem_type.toIntern(),17071 info.elem_type.toIntern(),
17072 // sentinel: ?*const anyopaque,17072 // sentinel: ?*const anyopaque,
17073 (try sema.optRefValue(block, info.elem_type, info.sentinel)).toIntern(),17073 (try sema.optRefValue(info.sentinel)).toIntern(),
17074 };17074 };
17075 return Air.internedToRef((try mod.intern(.{ .un = .{17075 return Air.internedToRef((try mod.intern(.{ .un = .{
17076 .ty = type_info_ty.toIntern(),17076 .ty = type_info_ty.toIntern(),
...@@ -17139,9 +17139,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17139,9 +17139,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17139 } })));17139 } })));
17140 },17140 },
17141 .ErrorSet => {17141 .ErrorSet => {
17142 var fields_anon_decl = try block.startAnonDecl();
17143 defer fields_anon_decl.deinit();
17144
17145 // Get the Error type17142 // Get the Error type
17146 const error_field_ty = t: {17143 const error_field_ty = t: {
17147 const set_field_ty_decl_index = (try sema.namespaceLookup(17144 const set_field_ty_decl_index = (try sema.namespaceLookup(
...@@ -17170,23 +17167,20 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17170,23 +17167,20 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17170 // TODO: write something like getCoercedInts to avoid needing to dupe17167 // TODO: write something like getCoercedInts to avoid needing to dupe
17171 const name = try sema.arena.dupe(u8, ip.stringToSlice(names.get(ip)[i]));17168 const name = try sema.arena.dupe(u8, ip.stringToSlice(names.get(ip)[i]));
17172 const name_val = v: {17169 const name_val = v: {
17173 var anon_decl = try block.startAnonDecl();
17174 defer anon_decl.deinit();
17175 const new_decl_ty = try mod.arrayType(.{17170 const new_decl_ty = try mod.arrayType(.{
17176 .len = name.len,17171 .len = name.len,
17177 .child = .u8_type,17172 .child = .u8_type,
17178 });17173 });
17179 const new_decl = try anon_decl.finish(17174 const new_decl_val = try mod.intern(.{ .aggregate = .{
17180 new_decl_ty,17175 .ty = new_decl_ty.toIntern(),
17181 (try mod.intern(.{ .aggregate = .{17176 .storage = .{ .bytes = name },
17182 .ty = new_decl_ty.toIntern(),17177 } });
17183 .storage = .{ .bytes = name },
17184 } })).toValue(),
17185 .none, // default alignment
17186 );
17187 break :v try mod.intern(.{ .ptr = .{17178 break :v try mod.intern(.{ .ptr = .{
17188 .ty = .slice_const_u8_type,17179 .ty = .slice_const_u8_type,
17189 .addr = .{ .decl = new_decl },17180 .addr = .{ .anon_decl = .{
17181 .val = new_decl_val,
17182 .orig_ty = .slice_const_u8_type,
17183 } },
17190 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),17184 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),
17191 } });17185 } });
17192 };17186 };
...@@ -17219,17 +17213,16 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17219,17 +17213,16 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17219 .len = vals.len,17213 .len = vals.len,
17220 .child = error_field_ty.toIntern(),17214 .child = error_field_ty.toIntern(),
17221 });17215 });
17222 const new_decl = try fields_anon_decl.finish(17216 const new_decl_val = try mod.intern(.{ .aggregate = .{
17223 array_errors_ty,17217 .ty = array_errors_ty.toIntern(),
17224 (try mod.intern(.{ .aggregate = .{17218 .storage = .{ .elems = vals },
17225 .ty = array_errors_ty.toIntern(),17219 } });
17226 .storage = .{ .elems = vals },
17227 } })).toValue(),
17228 .none, // default alignment
17229 );
17230 break :v try mod.intern(.{ .ptr = .{17220 break :v try mod.intern(.{ .ptr = .{
17231 .ty = slice_errors_ty.toIntern(),17221 .ty = slice_errors_ty.toIntern(),
17232 .addr = .{ .decl = new_decl },17222 .addr = .{ .anon_decl = .{
17223 .orig_ty = slice_errors_ty.toIntern(),
17224 .val = new_decl_val,
17225 } },
17233 .len = (try mod.intValue(Type.usize, vals.len)).toIntern(),17226 .len = (try mod.intValue(Type.usize, vals.len)).toIntern(),
17234 } });17227 } });
17235 } else .none;17228 } else .none;
...@@ -17275,12 +17268,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17275,12 +17268,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17275 } })));17268 } })));
17276 },17269 },
17277 .Enum => {17270 .Enum => {
17278 // TODO: look into memoizing this result.
17279 const is_exhaustive = Value.makeBool(ip.indexToKey(ty.toIntern()).enum_type.tag_mode != .nonexhaustive);17271 const is_exhaustive = Value.makeBool(ip.indexToKey(ty.toIntern()).enum_type.tag_mode != .nonexhaustive);
1728017272
17281 var fields_anon_decl = try block.startAnonDecl();
17282 defer fields_anon_decl.deinit();
17283
17284 const enum_field_ty = t: {17273 const enum_field_ty = t: {
17285 const enum_field_ty_decl_index = (try sema.namespaceLookup(17274 const enum_field_ty_decl_index = (try sema.namespaceLookup(
17286 block,17275 block,
...@@ -17308,23 +17297,20 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17308,23 +17297,20 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17308 // TODO: write something like getCoercedInts to avoid needing to dupe17297 // TODO: write something like getCoercedInts to avoid needing to dupe
17309 const name = try sema.arena.dupe(u8, ip.stringToSlice(enum_type.names.get(ip)[i]));17298 const name = try sema.arena.dupe(u8, ip.stringToSlice(enum_type.names.get(ip)[i]));
17310 const name_val = v: {17299 const name_val = v: {
17311 var anon_decl = try block.startAnonDecl();
17312 defer anon_decl.deinit();
17313 const new_decl_ty = try mod.arrayType(.{17300 const new_decl_ty = try mod.arrayType(.{
17314 .len = name.len,17301 .len = name.len,
17315 .child = .u8_type,17302 .child = .u8_type,
17316 });17303 });
17317 const new_decl = try anon_decl.finish(17304 const new_decl_val = try mod.intern(.{ .aggregate = .{
17318 new_decl_ty,17305 .ty = new_decl_ty.toIntern(),
17319 (try mod.intern(.{ .aggregate = .{17306 .storage = .{ .bytes = name },
17320 .ty = new_decl_ty.toIntern(),17307 } });
17321 .storage = .{ .bytes = name },
17322 } })).toValue(),
17323 .none, // default alignment
17324 );
17325 break :v try mod.intern(.{ .ptr = .{17308 break :v try mod.intern(.{ .ptr = .{
17326 .ty = .slice_const_u8_type,17309 .ty = .slice_const_u8_type,
17327 .addr = .{ .decl = new_decl },17310 .addr = .{ .anon_decl = .{
17311 .val = new_decl_val,
17312 .orig_ty = .slice_const_u8_type,
17313 } },
17328 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),17314 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),
17329 } });17315 } });
17330 };17316 };
...@@ -17346,23 +17332,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17346,23 +17332,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17346 .len = enum_field_vals.len,17332 .len = enum_field_vals.len,
17347 .child = enum_field_ty.toIntern(),17333 .child = enum_field_ty.toIntern(),
17348 });17334 });
17349 const new_decl = try fields_anon_decl.finish(17335 const new_decl_val = try mod.intern(.{ .aggregate = .{
17350 fields_array_ty,17336 .ty = fields_array_ty.toIntern(),
17351 (try mod.intern(.{ .aggregate = .{17337 .storage = .{ .elems = enum_field_vals },
17352 .ty = fields_array_ty.toIntern(),17338 } });
17353 .storage = .{ .elems = enum_field_vals },17339 const ptr_ty = (try sema.ptrType(.{
17354 } })).toValue(),17340 .child = enum_field_ty.toIntern(),
17355 .none, // default alignment17341 .flags = .{
17356 );17342 .size = .Slice,
17343 .is_const = true,
17344 },
17345 })).toIntern();
17357 break :v try mod.intern(.{ .ptr = .{17346 break :v try mod.intern(.{ .ptr = .{
17358 .ty = (try sema.ptrType(.{17347 .ty = ptr_ty,
17359 .child = enum_field_ty.toIntern(),17348 .addr = .{ .anon_decl = .{
17360 .flags = .{17349 .val = new_decl_val,
17361 .size = .Slice,17350 .orig_ty = ptr_ty,
17362 .is_const = true,17351 } },
17363 },
17364 })).toIntern(),
17365 .addr = .{ .decl = new_decl },
17366 .len = (try mod.intValue(Type.usize, enum_field_vals.len)).toIntern(),17352 .len = (try mod.intValue(Type.usize, enum_field_vals.len)).toIntern(),
17367 } });17353 } });
17368 };17354 };
...@@ -17402,11 +17388,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17402,11 +17388,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17402 } })));17388 } })));
17403 },17389 },
17404 .Union => {17390 .Union => {
17405 // TODO: look into memoizing this result.
17406
17407 var fields_anon_decl = try block.startAnonDecl();
17408 defer fields_anon_decl.deinit();
17409
17410 const type_union_ty = t: {17391 const type_union_ty = t: {
17411 const type_union_ty_decl_index = (try sema.namespaceLookup(17392 const type_union_ty_decl_index = (try sema.namespaceLookup(
17412 block,17393 block,
...@@ -17444,23 +17425,20 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17444,23 +17425,20 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17444 // TODO: write something like getCoercedInts to avoid needing to dupe17425 // TODO: write something like getCoercedInts to avoid needing to dupe
17445 const name = try sema.arena.dupe(u8, ip.stringToSlice(union_obj.field_names.get(ip)[i]));17426 const name = try sema.arena.dupe(u8, ip.stringToSlice(union_obj.field_names.get(ip)[i]));
17446 const name_val = v: {17427 const name_val = v: {
17447 var anon_decl = try block.startAnonDecl();
17448 defer anon_decl.deinit();
17449 const new_decl_ty = try mod.arrayType(.{17428 const new_decl_ty = try mod.arrayType(.{
17450 .len = name.len,17429 .len = name.len,
17451 .child = .u8_type,17430 .child = .u8_type,
17452 });17431 });
17453 const new_decl = try anon_decl.finish(17432 const new_decl_val = try mod.intern(.{ .aggregate = .{
17454 new_decl_ty,17433 .ty = new_decl_ty.toIntern(),
17455 (try mod.intern(.{ .aggregate = .{17434 .storage = .{ .bytes = name },
17456 .ty = new_decl_ty.toIntern(),17435 } });
17457 .storage = .{ .bytes = name },
17458 } })).toValue(),
17459 .none, // default alignment
17460 );
17461 break :v try mod.intern(.{ .ptr = .{17436 break :v try mod.intern(.{ .ptr = .{
17462 .ty = .slice_const_u8_type,17437 .ty = .slice_const_u8_type,
17463 .addr = .{ .decl = new_decl },17438 .addr = .{ .anon_decl = .{
17439 .val = new_decl_val,
17440 .orig_ty = .slice_const_u8_type,
17441 } },
17464 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),17442 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),
17465 } });17443 } });
17466 };17444 };
...@@ -17490,23 +17468,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17490,23 +17468,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17490 .len = union_field_vals.len,17468 .len = union_field_vals.len,
17491 .child = union_field_ty.toIntern(),17469 .child = union_field_ty.toIntern(),
17492 });17470 });
17493 const new_decl = try fields_anon_decl.finish(17471 const new_decl_val = try mod.intern(.{ .aggregate = .{
17494 array_fields_ty,17472 .ty = array_fields_ty.toIntern(),
17495 (try mod.intern(.{ .aggregate = .{17473 .storage = .{ .elems = union_field_vals },
17496 .ty = array_fields_ty.toIntern(),17474 } });
17497 .storage = .{ .elems = union_field_vals },17475 const ptr_ty = (try sema.ptrType(.{
17498 } })).toValue(),17476 .child = union_field_ty.toIntern(),
17499 .none, // default alignment17477 .flags = .{
17500 );17478 .size = .Slice,
17479 .is_const = true,
17480 },
17481 })).toIntern();
17501 break :v try mod.intern(.{ .ptr = .{17482 break :v try mod.intern(.{ .ptr = .{
17502 .ty = (try sema.ptrType(.{17483 .ty = ptr_ty,
17503 .child = union_field_ty.toIntern(),17484 .addr = .{ .anon_decl = .{
17504 .flags = .{17485 .orig_ty = ptr_ty,
17505 .size = .Slice,17486 .val = new_decl_val,
17506 .is_const = true,17487 } },
17507 },
17508 })).toIntern(),
17509 .addr = .{ .decl = new_decl },
17510 .len = (try mod.intValue(Type.usize, union_field_vals.len)).toIntern(),17488 .len = (try mod.intValue(Type.usize, union_field_vals.len)).toIntern(),
17511 } });17489 } });
17512 };17490 };
...@@ -17552,11 +17530,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17552,11 +17530,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17552 } })));17530 } })));
17553 },17531 },
17554 .Struct => {17532 .Struct => {
17555 // TODO: look into memoizing this result.
17556
17557 var fields_anon_decl = try block.startAnonDecl();
17558 defer fields_anon_decl.deinit();
17559
17560 const type_struct_ty = t: {17533 const type_struct_ty = t: {
17561 const type_struct_ty_decl_index = (try sema.namespaceLookup(17534 const type_struct_ty_decl_index = (try sema.namespaceLookup(
17562 block,17535 block,
...@@ -17596,8 +17569,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17596,8 +17569,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17596 const field_ty = anon_struct_type.types.get(ip)[i];17569 const field_ty = anon_struct_type.types.get(ip)[i];
17597 const field_val = anon_struct_type.values.get(ip)[i];17570 const field_val = anon_struct_type.values.get(ip)[i];
17598 const name_val = v: {17571 const name_val = v: {
17599 var anon_decl = try block.startAnonDecl();
17600 defer anon_decl.deinit();
17601 // TODO: write something like getCoercedInts to avoid needing to dupe17572 // TODO: write something like getCoercedInts to avoid needing to dupe
17602 const bytes = if (tuple.names.len != 0)17573 const bytes = if (tuple.names.len != 0)
17603 // https://github.com/ziglang/zig/issues/1570917574 // https://github.com/ziglang/zig/issues/15709
...@@ -17608,17 +17579,16 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17608,17 +17579,16 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17608 .len = bytes.len,17579 .len = bytes.len,
17609 .child = .u8_type,17580 .child = .u8_type,
17610 });17581 });
17611 const new_decl = try anon_decl.finish(17582 const new_decl_val = try mod.intern(.{ .aggregate = .{
17612 new_decl_ty,17583 .ty = new_decl_ty.toIntern(),
17613 (try mod.intern(.{ .aggregate = .{17584 .storage = .{ .bytes = bytes },
17614 .ty = new_decl_ty.toIntern(),17585 } });
17615 .storage = .{ .bytes = bytes },
17616 } })).toValue(),
17617 .none, // default alignment
17618 );
17619 break :v try mod.intern(.{ .ptr = .{17586 break :v try mod.intern(.{ .ptr = .{
17620 .ty = .slice_const_u8_type,17587 .ty = .slice_const_u8_type,
17621 .addr = .{ .decl = new_decl },17588 .addr = .{ .anon_decl = .{
17589 .val = new_decl_val,
17590 .orig_ty = .slice_const_u8_type,
17591 } },
17622 .len = (try mod.intValue(Type.usize, bytes.len)).toIntern(),17592 .len = (try mod.intValue(Type.usize, bytes.len)).toIntern(),
17623 } });17593 } });
17624 };17594 };
...@@ -17627,7 +17597,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17627,7 +17597,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1762717597
17628 const is_comptime = field_val != .none;17598 const is_comptime = field_val != .none;
17629 const opt_default_val = if (is_comptime) field_val.toValue() else null;17599 const opt_default_val = if (is_comptime) field_val.toValue() else null;
17630 const default_val_ptr = try sema.optRefValue(block, field_ty.toType(), opt_default_val);17600 const default_val_ptr = try sema.optRefValue(opt_default_val);
17631 const struct_field_fields = .{17601 const struct_field_fields = .{
17632 // name: []const u8,17602 // name: []const u8,
17633 name_val,17603 name_val,
...@@ -17662,29 +17632,26 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17662,29 +17632,26 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17662 const field_init = struct_type.fieldInit(ip, i);17632 const field_init = struct_type.fieldInit(ip, i);
17663 const field_is_comptime = struct_type.fieldIsComptime(ip, i);17633 const field_is_comptime = struct_type.fieldIsComptime(ip, i);
17664 const name_val = v: {17634 const name_val = v: {
17665 var anon_decl = try block.startAnonDecl();
17666 defer anon_decl.deinit();
17667 const new_decl_ty = try mod.arrayType(.{17635 const new_decl_ty = try mod.arrayType(.{
17668 .len = name.len,17636 .len = name.len,
17669 .child = .u8_type,17637 .child = .u8_type,
17670 });17638 });
17671 const new_decl = try anon_decl.finish(17639 const new_decl_val = try mod.intern(.{ .aggregate = .{
17672 new_decl_ty,17640 .ty = new_decl_ty.toIntern(),
17673 (try mod.intern(.{ .aggregate = .{17641 .storage = .{ .bytes = name },
17674 .ty = new_decl_ty.toIntern(),17642 } });
17675 .storage = .{ .bytes = name },
17676 } })).toValue(),
17677 .none, // default alignment
17678 );
17679 break :v try mod.intern(.{ .ptr = .{17643 break :v try mod.intern(.{ .ptr = .{
17680 .ty = .slice_const_u8_type,17644 .ty = .slice_const_u8_type,
17681 .addr = .{ .decl = new_decl },17645 .addr = .{ .anon_decl = .{
17646 .val = new_decl_val,
17647 .orig_ty = .slice_const_u8_type,
17648 } },
17682 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),17649 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),
17683 } });17650 } });
17684 };17651 };
1768517652
17686 const opt_default_val = if (field_init == .none) null else field_init.toValue();17653 const opt_default_val = if (field_init == .none) null else field_init.toValue();
17687 const default_val_ptr = try sema.optRefValue(block, field_ty, opt_default_val);17654 const default_val_ptr = try sema.optRefValue(opt_default_val);
17688 const alignment = switch (struct_type.layout) {17655 const alignment = switch (struct_type.layout) {
17689 .Packed => .none,17656 .Packed => .none,
17690 else => try sema.structFieldAlignment(17657 else => try sema.structFieldAlignment(
...@@ -17718,23 +17685,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17718,23 +17685,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17718 .len = struct_field_vals.len,17685 .len = struct_field_vals.len,
17719 .child = struct_field_ty.toIntern(),17686 .child = struct_field_ty.toIntern(),
17720 });17687 });
17721 const new_decl = try fields_anon_decl.finish(17688 const new_decl_val = try mod.intern(.{ .aggregate = .{
17722 array_fields_ty,17689 .ty = array_fields_ty.toIntern(),
17723 (try mod.intern(.{ .aggregate = .{17690 .storage = .{ .elems = struct_field_vals },
17724 .ty = array_fields_ty.toIntern(),17691 } });
17725 .storage = .{ .elems = struct_field_vals },17692 const ptr_ty = (try sema.ptrType(.{
17726 } })).toValue(),17693 .child = struct_field_ty.toIntern(),
17727 .none, // default alignment17694 .flags = .{
17728 );17695 .size = .Slice,
17696 .is_const = true,
17697 },
17698 })).toIntern();
17729 break :v try mod.intern(.{ .ptr = .{17699 break :v try mod.intern(.{ .ptr = .{
17730 .ty = (try sema.ptrType(.{17700 .ty = ptr_ty,
17731 .child = struct_field_ty.toIntern(),17701 .addr = .{ .anon_decl = .{
17732 .flags = .{17702 .orig_ty = ptr_ty,
17733 .size = .Slice,17703 .val = new_decl_val,
17734 .is_const = true,17704 } },
17735 },
17736 })).toIntern(),
17737 .addr = .{ .decl = new_decl },
17738 .len = (try mod.intValue(Type.usize, struct_field_vals.len)).toIntern(),17705 .len = (try mod.intValue(Type.usize, struct_field_vals.len)).toIntern(),
17739 } });17706 } });
17740 };17707 };
...@@ -17786,8 +17753,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17786,8 +17753,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17786 } })));17753 } })));
17787 },17754 },
17788 .Opaque => {17755 .Opaque => {
17789 // TODO: look into memoizing this result.
17790
17791 const type_opaque_ty = t: {17756 const type_opaque_ty = t: {
17792 const type_opaque_ty_decl_index = (try sema.namespaceLookup(17757 const type_opaque_ty_decl_index = (try sema.namespaceLookup(
17793 block,17758 block,
...@@ -17832,9 +17797,6 @@ fn typeInfoDecls(...@@ -17832,9 +17797,6 @@ fn typeInfoDecls(
17832 const mod = sema.mod;17797 const mod = sema.mod;
17833 const gpa = sema.gpa;17798 const gpa = sema.gpa;
1783417799
17835 var decls_anon_decl = try block.startAnonDecl();
17836 defer decls_anon_decl.deinit();
17837
17838 const declaration_ty = t: {17800 const declaration_ty = t: {
17839 const declaration_ty_decl_index = (try sema.namespaceLookup(17801 const declaration_ty_decl_index = (try sema.namespaceLookup(
17840 block,17802 block,
...@@ -17864,23 +17826,23 @@ fn typeInfoDecls(...@@ -17864,23 +17826,23 @@ fn typeInfoDecls(
17864 .len = decl_vals.items.len,17826 .len = decl_vals.items.len,
17865 .child = declaration_ty.toIntern(),17827 .child = declaration_ty.toIntern(),
17866 });17828 });
17867 const new_decl = try decls_anon_decl.finish(17829 const new_decl_val = try mod.intern(.{ .aggregate = .{
17868 array_decl_ty,17830 .ty = array_decl_ty.toIntern(),
17869 (try mod.intern(.{ .aggregate = .{17831 .storage = .{ .elems = decl_vals.items },
17870 .ty = array_decl_ty.toIntern(),17832 } });
17871 .storage = .{ .elems = decl_vals.items },17833 const ptr_ty = (try sema.ptrType(.{
17872 } })).toValue(),17834 .child = declaration_ty.toIntern(),
17873 .none, // default alignment17835 .flags = .{
17874 );17836 .size = .Slice,
17837 .is_const = true,
17838 },
17839 })).toIntern();
17875 return try mod.intern(.{ .ptr = .{17840 return try mod.intern(.{ .ptr = .{
17876 .ty = (try sema.ptrType(.{17841 .ty = ptr_ty,
17877 .child = declaration_ty.toIntern(),17842 .addr = .{ .anon_decl = .{
17878 .flags = .{17843 .orig_ty = ptr_ty,
17879 .size = .Slice,17844 .val = new_decl_val,
17880 .is_const = true,17845 } },
17881 },
17882 })).toIntern(),
17883 .addr = .{ .decl = new_decl },
17884 .len = (try mod.intValue(Type.usize, decl_vals.items.len)).toIntern(),17846 .len = (try mod.intValue(Type.usize, decl_vals.items.len)).toIntern(),
17885 } });17847 } });
17886}17848}
...@@ -17909,25 +17871,22 @@ fn typeInfoNamespaceDecls(...@@ -17909,25 +17871,22 @@ fn typeInfoNamespaceDecls(
17909 }17871 }
17910 if (decl.kind != .named or !decl.is_pub) continue;17872 if (decl.kind != .named or !decl.is_pub) continue;
17911 const name_val = v: {17873 const name_val = v: {
17912 var anon_decl = try block.startAnonDecl();
17913 defer anon_decl.deinit();
17914 // TODO: write something like getCoercedInts to avoid needing to dupe17874 // TODO: write something like getCoercedInts to avoid needing to dupe
17915 const name = try sema.arena.dupe(u8, ip.stringToSlice(decl.name));17875 const name = try sema.arena.dupe(u8, ip.stringToSlice(decl.name));
17916 const new_decl_ty = try mod.arrayType(.{17876 const new_decl_ty = try mod.arrayType(.{
17917 .len = name.len,17877 .len = name.len,
17918 .child = .u8_type,17878 .child = .u8_type,
17919 });17879 });
17920 const new_decl = try anon_decl.finish(17880 const new_decl_val = try mod.intern(.{ .aggregate = .{
17921 new_decl_ty,17881 .ty = new_decl_ty.toIntern(),
17922 (try mod.intern(.{ .aggregate = .{17882 .storage = .{ .bytes = name },
17923 .ty = new_decl_ty.toIntern(),17883 } });
17924 .storage = .{ .bytes = name },
17925 } })).toValue(),
17926 .none, // default alignment
17927 );
17928 break :v try mod.intern(.{ .ptr = .{17884 break :v try mod.intern(.{ .ptr = .{
17929 .ty = .slice_const_u8_type,17885 .ty = .slice_const_u8_type,
17930 .addr = .{ .decl = new_decl },17886 .addr = .{ .anon_decl = .{
17887 .orig_ty = .slice_const_u8_type,
17888 .val = new_decl_val,
17889 } },
17931 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),17890 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),
17932 } });17891 } });
17933 };17892 };
...@@ -19072,10 +19031,7 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is...@@ -19072,10 +19031,7 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is
1907219031
19073 if (is_byref) {19032 if (is_byref) {
19074 const init_val = (try sema.resolveValue(init_ref)).?;19033 const init_val = (try sema.resolveValue(init_ref)).?;
19075 var anon_decl = try block.startAnonDecl();19034 return anonDeclRef(sema, init_val.toIntern());
19076 defer anon_decl.deinit();
19077 const decl = try anon_decl.finish(init_ty, init_val, .none);
19078 return sema.analyzeDeclRef(decl);
19079 } else {19035 } else {
19080 return init_ref;19036 return init_ref;
19081 }19037 }
...@@ -19298,7 +19254,7 @@ fn zirStructInit(...@@ -19298,7 +19254,7 @@ fn zirStructInit(
19298 } })).toValue();19254 } })).toValue();
19299 const final_val_inst = try sema.coerce(block, result_ty, Air.internedToRef(struct_val.toIntern()), src);19255 const final_val_inst = try sema.coerce(block, result_ty, Air.internedToRef(struct_val.toIntern()), src);
19300 const final_val = (try sema.resolveValue(final_val_inst)).?;19256 const final_val = (try sema.resolveValue(final_val_inst)).?;
19301 return sema.addConstantMaybeRef(block, resolved_ty, final_val, is_ref);19257 return sema.addConstantMaybeRef(final_val.toIntern(), is_ref);
19302 }19258 }
1930319259
19304 if (try sema.typeRequiresComptime(resolved_ty)) {19260 if (try sema.typeRequiresComptime(resolved_ty)) {
...@@ -19458,7 +19414,7 @@ fn finishStructInit(...@@ -19458,7 +19414,7 @@ fn finishStructInit(
19458 } });19414 } });
19459 const final_val_inst = try sema.coerce(block, result_ty, Air.internedToRef(struct_val), init_src);19415 const final_val_inst = try sema.coerce(block, result_ty, Air.internedToRef(struct_val), init_src);
19460 const final_val = (try sema.resolveValue(final_val_inst)).?;19416 const final_val = (try sema.resolveValue(final_val_inst)).?;
19461 return sema.addConstantMaybeRef(block, result_ty, final_val, is_ref);19417 return sema.addConstantMaybeRef(final_val.toIntern(), is_ref);
19462 };19418 };
1946319419
19464 if (try sema.typeRequiresComptime(struct_ty)) {19420 if (try sema.typeRequiresComptime(struct_ty)) {
...@@ -19611,7 +19567,7 @@ fn structInitAnon(...@@ -19611,7 +19567,7 @@ fn structInitAnon(
19611 .ty = tuple_ty,19567 .ty = tuple_ty,
19612 .storage = .{ .elems = values },19568 .storage = .{ .elems = values },
19613 } });19569 } });
19614 return sema.addConstantMaybeRef(block, tuple_ty.toType(), tuple_val.toValue(), is_ref);19570 return sema.addConstantMaybeRef(tuple_val, is_ref);
19615 };19571 };
1961619572
19617 sema.requireRuntimeBlock(block, .unneeded, null) catch |err| switch (err) {19573 sema.requireRuntimeBlock(block, .unneeded, null) catch |err| switch (err) {
...@@ -19777,7 +19733,8 @@ fn zirArrayInit(...@@ -19777,7 +19733,8 @@ fn zirArrayInit(
19777 .storage = .{ .elems = elem_vals },19733 .storage = .{ .elems = elem_vals },
19778 } });19734 } });
19779 const result_ref = try sema.coerce(block, result_ty, Air.internedToRef(arr_val), src);19735 const result_ref = try sema.coerce(block, result_ty, Air.internedToRef(arr_val), src);
19780 return sema.addConstantMaybeRef(block, result_ty, (try sema.resolveValue(result_ref)).?, is_ref);19736 const result_val = (try sema.resolveValue(result_ref)).?;
19737 return sema.addConstantMaybeRef(result_val.toIntern(), is_ref);
19781 };19738 };
1978219739
19783 sema.requireRuntimeBlock(block, .unneeded, null) catch |err| switch (err) {19740 sema.requireRuntimeBlock(block, .unneeded, null) catch |err| switch (err) {
...@@ -19896,7 +19853,7 @@ fn arrayInitAnon(...@@ -19896,7 +19853,7 @@ fn arrayInitAnon(
19896 .ty = tuple_ty,19853 .ty = tuple_ty,
19897 .storage = .{ .elems = values },19854 .storage = .{ .elems = values },
19898 } });19855 } });
19899 return sema.addConstantMaybeRef(block, tuple_ty.toType(), tuple_val.toValue(), is_ref);19856 return sema.addConstantMaybeRef(tuple_val, is_ref);
19900 };19857 };
1990119858
19902 try sema.requireRuntimeBlock(block, src, runtime_src);19859 try sema.requireRuntimeBlock(block, src, runtime_src);
...@@ -19931,23 +19888,8 @@ fn arrayInitAnon(...@@ -19931,23 +19888,8 @@ fn arrayInitAnon(
19931 return block.addAggregateInit(tuple_ty.toType(), element_refs);19888 return block.addAggregateInit(tuple_ty.toType(), element_refs);
19932}19889}
1993319890
19934fn addConstantMaybeRef(19891fn addConstantMaybeRef(sema: *Sema, val: InternPool.Index, is_ref: bool) !Air.Inst.Ref {
19935 sema: *Sema,19892 return if (is_ref) anonDeclRef(sema, val) else Air.internedToRef(val);
19936 block: *Block,
19937 ty: Type,
19938 val: Value,
19939 is_ref: bool,
19940) !Air.Inst.Ref {
19941 if (!is_ref) return Air.internedToRef(val.toIntern());
19942
19943 var anon_decl = try block.startAnonDecl();
19944 defer anon_decl.deinit();
19945 const decl = try anon_decl.finish(
19946 ty,
19947 val,
19948 .none, // default alignment
19949 );
19950 return sema.analyzeDeclRef(decl);
19951}19893}
1995219894
19953fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {19895fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -21429,28 +21371,9 @@ fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -21429,28 +21371,9 @@ fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
21429 const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };21371 const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
21430 const ty = try sema.resolveType(block, ty_src, inst_data.operand);21372 const ty = try sema.resolveType(block, ty_src, inst_data.operand);
2143121373
21432 var anon_decl = try block.startAnonDecl();
21433 defer anon_decl.deinit();
21434
21435 var bytes = std.ArrayList(u8).init(sema.arena);21374 var bytes = std.ArrayList(u8).init(sema.arena);
21436 defer bytes.deinit();
21437 try ty.print(bytes.writer(), mod);21375 try ty.print(bytes.writer(), mod);
2143821376 return addStrLitNoAlias(sema, bytes.items);
21439 const decl_ty = try mod.arrayType(.{
21440 .len = bytes.items.len,
21441 .sentinel = .zero_u8,
21442 .child = .u8_type,
21443 });
21444 const new_decl = try anon_decl.finish(
21445 decl_ty,
21446 (try mod.intern(.{ .aggregate = .{
21447 .ty = decl_ty.toIntern(),
21448 .storage = .{ .bytes = bytes.items },
21449 } })).toValue(),
21450 .none, // default alignment
21451 );
21452
21453 return sema.analyzeDeclRef(new_decl);
21454}21377}
2145521378
21456fn zirFrameType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {21379fn zirFrameType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -26333,13 +26256,8 @@ fn fieldPtr(...@@ -26333,13 +26256,8 @@ fn fieldPtr(
26333 switch (inner_ty.zigTypeTag(mod)) {26256 switch (inner_ty.zigTypeTag(mod)) {
26334 .Array => {26257 .Array => {
26335 if (ip.stringEqlSlice(field_name, "len")) {26258 if (ip.stringEqlSlice(field_name, "len")) {
26336 var anon_decl = try block.startAnonDecl();26259 const int_val = try mod.intValue(Type.usize, inner_ty.arrayLen(mod));
26337 defer anon_decl.deinit();26260 return anonDeclRef(sema, int_val.toIntern());
26338 return sema.analyzeDeclRef(try anon_decl.finish(
26339 Type.usize,
26340 try mod.intValue(Type.usize, inner_ty.arrayLen(mod)),
26341 .none, // default alignment
26342 ));
26343 } else {26261 } else {
26344 return sema.fail(26262 return sema.fail(
26345 block,26263 block,
...@@ -26448,20 +26366,14 @@ fn fieldPtr(...@@ -26448,20 +26366,14 @@ fn fieldPtr(
26448 else => unreachable,26366 else => unreachable,
26449 }26367 }
2645026368
26451 var anon_decl = try block.startAnonDecl();
26452 defer anon_decl.deinit();
26453 const error_set_type = if (!child_type.isAnyError(mod))26369 const error_set_type = if (!child_type.isAnyError(mod))
26454 child_type26370 child_type
26455 else26371 else
26456 try mod.singleErrorSetType(field_name);26372 try mod.singleErrorSetType(field_name);
26457 return sema.analyzeDeclRef(try anon_decl.finish(26373 return anonDeclRef(sema, try mod.intern(.{ .err = .{
26458 error_set_type,26374 .ty = error_set_type.toIntern(),
26459 (try mod.intern(.{ .err = .{26375 .name = field_name,
26460 .ty = error_set_type.toIntern(),26376 } }));
26461 .name = field_name,
26462 } })).toValue(),
26463 .none, // default alignment
26464 ));
26465 },26377 },
26466 .Union => {26378 .Union => {
26467 if (child_type.getNamespaceIndex(mod).unwrap()) |namespace| {26379 if (child_type.getNamespaceIndex(mod).unwrap()) |namespace| {
...@@ -26473,13 +26385,8 @@ fn fieldPtr(...@@ -26473,13 +26385,8 @@ fn fieldPtr(
26473 if (child_type.unionTagType(mod)) |enum_ty| {26385 if (child_type.unionTagType(mod)) |enum_ty| {
26474 if (enum_ty.enumFieldIndex(field_name, mod)) |field_index| {26386 if (enum_ty.enumFieldIndex(field_name, mod)) |field_index| {
26475 const field_index_u32: u32 = @intCast(field_index);26387 const field_index_u32: u32 = @intCast(field_index);
26476 var anon_decl = try block.startAnonDecl();26388 const idx_val = try mod.enumValueFieldIndex(enum_ty, field_index_u32);
26477 defer anon_decl.deinit();26389 return anonDeclRef(sema, idx_val.toIntern());
26478 return sema.analyzeDeclRef(try anon_decl.finish(
26479 enum_ty,
26480 try mod.enumValueFieldIndex(enum_ty, field_index_u32),
26481 .none, // default alignment
26482 ));
26483 }26390 }
26484 }26391 }
26485 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);26392 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
...@@ -26494,13 +26401,8 @@ fn fieldPtr(...@@ -26494,13 +26401,8 @@ fn fieldPtr(
26494 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);26401 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
26495 };26402 };
26496 const field_index_u32: u32 = @intCast(field_index);26403 const field_index_u32: u32 = @intCast(field_index);
26497 var anon_decl = try block.startAnonDecl();26404 const idx_val = try mod.enumValueFieldIndex(child_type, field_index_u32);
26498 defer anon_decl.deinit();26405 return anonDeclRef(sema, idx_val.toIntern());
26499 return sema.analyzeDeclRef(try anon_decl.finish(
26500 child_type,
26501 try mod.enumValueFieldIndex(child_type, field_index_u32),
26502 .none, // default alignment
26503 ));
26504 },26406 },
26505 .Struct, .Opaque => {26407 .Struct, .Opaque => {
26506 if (child_type.getNamespaceIndex(mod).unwrap()) |namespace| {26408 if (child_type.getNamespaceIndex(mod).unwrap()) |namespace| {
...@@ -31669,31 +31571,13 @@ fn ensureFuncBodyAnalyzed(sema: *Sema, func: InternPool.Index) CompileError!void...@@ -31669,31 +31571,13 @@ fn ensureFuncBodyAnalyzed(sema: *Sema, func: InternPool.Index) CompileError!void
31669 };31571 };
31670}31572}
3167131573
31672fn refValue(sema: *Sema, block: *Block, ty: Type, val: Value) !Value {31574fn optRefValue(sema: *Sema, opt_val: ?Value) !Value {
31673 const mod = sema.mod;
31674 var anon_decl = try block.startAnonDecl();
31675 defer anon_decl.deinit();
31676 const decl = try anon_decl.finish(
31677 ty,
31678 val,
31679 .none, // default alignment
31680 );
31681 try sema.maybeQueueFuncBodyAnalysis(decl);
31682 try mod.declareDeclDependency(sema.owner_decl_index, decl);
31683 const result = try mod.intern(.{ .ptr = .{
31684 .ty = (try mod.singleConstPtrType(ty)).toIntern(),
31685 .addr = .{ .decl = decl },
31686 } });
31687 return result.toValue();
31688}
31689
31690fn optRefValue(sema: *Sema, block: *Block, ty: Type, opt_val: ?Value) !Value {
31691 const mod = sema.mod;31575 const mod = sema.mod;
31692 const ptr_anyopaque_ty = try mod.singleConstPtrType(Type.anyopaque);31576 const ptr_anyopaque_ty = try mod.singleConstPtrType(Type.anyopaque);
31693 return (try mod.intern(.{ .opt = .{31577 return (try mod.intern(.{ .opt = .{
31694 .ty = (try mod.optionalType(ptr_anyopaque_ty.toIntern())).toIntern(),31578 .ty = (try mod.optionalType(ptr_anyopaque_ty.toIntern())).toIntern(),
31695 .val = if (opt_val) |val| (try mod.getCoerced(31579 .val = if (opt_val) |val| (try mod.getCoerced(
31696 try sema.refValue(block, ty, val),31580 (try sema.refValue(val.toIntern())).toValue(),
31697 ptr_anyopaque_ty,31581 ptr_anyopaque_ty,
31698 )).toIntern() else .none,31582 )).toIntern() else .none,
31699 } })).toValue();31583 } })).toValue();
...@@ -31755,15 +31639,8 @@ fn analyzeRef(...@@ -31755,15 +31639,8 @@ fn analyzeRef(
31755 switch (mod.intern_pool.indexToKey(val.toIntern())) {31639 switch (mod.intern_pool.indexToKey(val.toIntern())) {
31756 .extern_func => |extern_func| return sema.analyzeDeclRef(extern_func.decl),31640 .extern_func => |extern_func| return sema.analyzeDeclRef(extern_func.decl),
31757 .func => |func| return sema.analyzeDeclRef(func.owner_decl),31641 .func => |func| return sema.analyzeDeclRef(func.owner_decl),
31758 else => {},31642 else => return anonDeclRef(sema, val.toIntern()),
31759 }31643 }
31760 var anon_decl = try block.startAnonDecl();
31761 defer anon_decl.deinit();
31762 return sema.analyzeDeclRef(try anon_decl.finish(
31763 operand_ty,
31764 val,
31765 .none, // default alignment
31766 ));
31767 }31644 }
3176831645
31769 try sema.requireRuntimeBlock(block, src, null);31646 try sema.requireRuntimeBlock(block, src, null);
...@@ -36848,7 +36725,7 @@ fn analyzeComptimeAlloc(...@@ -36848,7 +36725,7 @@ fn analyzeComptimeAlloc(
36848 },36725 },
36849 });36726 });
3685036727
36851 var anon_decl = try block.startAnonDecl();36728 var anon_decl = try block.startAnonDecl(); // TODO: comptime value mutation without Decl
36852 defer anon_decl.deinit();36729 defer anon_decl.deinit();
3685336730
36854 const decl_index = try anon_decl.finish(36731 const decl_index = try anon_decl.finish(
src/codegen/c.zig+64-58
...@@ -522,7 +522,7 @@ pub const Object = struct {...@@ -522,7 +522,7 @@ pub const Object = struct {
522pub const DeclGen = struct {522pub const DeclGen = struct {
523 gpa: mem.Allocator,523 gpa: mem.Allocator,
524 module: *Module,524 module: *Module,
525 decl_index: Decl.OptionalIndex,525 pass: Pass,
526 is_naked_fn: bool,526 is_naked_fn: bool,
527 /// This is a borrowed reference from `link.C`.527 /// This is a borrowed reference from `link.C`.
528 fwd_decl: std.ArrayList(u8),528 fwd_decl: std.ArrayList(u8),
...@@ -533,10 +533,16 @@ pub const DeclGen = struct {...@@ -533,10 +533,16 @@ pub const DeclGen = struct {
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),534 aligned_anon_decls: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),
535535
536 pub const Pass = union(enum) {
537 decl: Decl.Index,
538 anon: InternPool.Index,
539 flush,
540 };
541
536 fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {542 fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {
537 @setCold(true);543 @setCold(true);
538 const mod = dg.module;544 const mod = dg.module;
539 const decl_index = dg.decl_index.unwrap().?;545 const decl_index = dg.pass.decl;
540 const decl = mod.declPtr(decl_index);546 const decl = mod.declPtr(decl_index);
541 const src = LazySrcLoc.nodeOffset(0);547 const src = LazySrcLoc.nodeOffset(0);
542 const src_loc = src.toSrcLoc(decl, mod);548 const src_loc = src.toSrcLoc(decl, mod);
...@@ -1284,11 +1290,14 @@ pub const DeclGen = struct {...@@ -1284,11 +1290,14 @@ pub const DeclGen = struct {
1284 var index: usize = 0;1290 var index: usize = 0;
1285 while (index < ai.len) : (index += 1) {1291 while (index < ai.len) : (index += 1) {
1286 const elem_val = try val.elemValue(mod, index);1292 const elem_val = try val.elemValue(mod, index);
1287 const elem_val_u8 = if (elem_val.isUndef(mod)) undefPattern(u8) else @as(u8, @intCast(elem_val.toUnsignedInt(mod)));1293 const elem_val_u8: u8 = if (elem_val.isUndef(mod))
1294 undefPattern(u8)
1295 else
1296 @intCast(elem_val.toUnsignedInt(mod));
1288 try literal.writeChar(elem_val_u8);1297 try literal.writeChar(elem_val_u8);
1289 }1298 }
1290 if (ai.sentinel) |s| {1299 if (ai.sentinel) |s| {
1291 const s_u8 = @as(u8, @intCast(s.toUnsignedInt(mod)));1300 const s_u8: u8 = @intCast(s.toUnsignedInt(mod));
1292 if (s_u8 != 0) try literal.writeChar(s_u8);1301 if (s_u8 != 0) try literal.writeChar(s_u8);
1293 }1302 }
1294 try literal.end();1303 try literal.end();
...@@ -1298,7 +1307,10 @@ pub const DeclGen = struct {...@@ -1298,7 +1307,10 @@ pub const DeclGen = struct {
1298 while (index < ai.len) : (index += 1) {1307 while (index < ai.len) : (index += 1) {
1299 if (index != 0) try writer.writeByte(',');1308 if (index != 0) try writer.writeByte(',');
1300 const elem_val = try val.elemValue(mod, index);1309 const elem_val = try val.elemValue(mod, index);
1301 const elem_val_u8 = if (elem_val.isUndef(mod)) undefPattern(u8) else @as(u8, @intCast(elem_val.toUnsignedInt(mod)));1310 const elem_val_u8: u8 = if (elem_val.isUndef(mod))
1311 undefPattern(u8)
1312 else
1313 @intCast(elem_val.toUnsignedInt(mod));
1302 try writer.print("'\\x{x}'", .{elem_val_u8});1314 try writer.print("'\\x{x}'", .{elem_val_u8});
1303 }1315 }
1304 if (ai.sentinel) |s| {1316 if (ai.sentinel) |s| {
...@@ -1566,18 +1578,11 @@ pub const DeclGen = struct {...@@ -1566,18 +1578,11 @@ pub const DeclGen = struct {
1566 else => unreachable,1578 else => unreachable,
1567 }1579 }
1568 }1580 }
1569 if (fn_decl.val.getFunction(mod)) |func| if (func.analysis(ip).is_cold) try w.writeAll("zig_cold ");1581 if (fn_decl.val.getFunction(mod)) |func| if (func.analysis(ip).is_cold)
1582 try w.writeAll("zig_cold ");
1570 if (fn_info.return_type == .noreturn_type) try w.writeAll("zig_noreturn ");1583 if (fn_info.return_type == .noreturn_type) try w.writeAll("zig_noreturn ");
15711584
1572 const trailing = try renderTypePrefix(1585 const trailing = try renderTypePrefix(dg.pass, store.*, mod, w, fn_cty_idx, .suffix, .{});
1573 dg.decl_index,
1574 store.*,
1575 mod,
1576 w,
1577 fn_cty_idx,
1578 .suffix,
1579 .{},
1580 );
1581 try w.print("{}", .{trailing});1586 try w.print("{}", .{trailing});
15821587
1583 if (toCallingConvention(fn_info.cc)) |call_conv| {1588 if (toCallingConvention(fn_info.cc)) |call_conv| {
...@@ -1597,7 +1602,7 @@ pub const DeclGen = struct {...@@ -1597,7 +1602,7 @@ pub const DeclGen = struct {
1597 }1602 }
15981603
1599 try renderTypeSuffix(1604 try renderTypeSuffix(
1600 dg.decl_index,1605 dg.pass,
1601 store.*,1606 store.*,
1602 mod,1607 mod,
1603 w,1608 w,
...@@ -1652,8 +1657,8 @@ pub const DeclGen = struct {...@@ -1652,8 +1657,8 @@ pub const DeclGen = struct {
1652 fn renderCType(dg: *DeclGen, w: anytype, idx: CType.Index) error{ OutOfMemory, AnalysisFail }!void {1657 fn renderCType(dg: *DeclGen, w: anytype, idx: CType.Index) error{ OutOfMemory, AnalysisFail }!void {
1653 const store = &dg.ctypes.set;1658 const store = &dg.ctypes.set;
1654 const mod = dg.module;1659 const mod = dg.module;
1655 _ = try renderTypePrefix(dg.decl_index, store.*, mod, w, idx, .suffix, .{});1660 _ = try renderTypePrefix(dg.pass, store.*, mod, w, idx, .suffix, .{});
1656 try renderTypeSuffix(dg.decl_index, store.*, mod, w, idx, .suffix, .{});1661 try renderTypeSuffix(dg.pass, store.*, mod, w, idx, .suffix, .{});
1657 }1662 }
16581663
1659 const IntCastContext = union(enum) {1664 const IntCastContext = union(enum) {
...@@ -1799,11 +1804,10 @@ pub const DeclGen = struct {...@@ -1799,11 +1804,10 @@ pub const DeclGen = struct {
1799 .gt => try w.print("zig_align({}) ", .{alignas.toByteUnits()}),1804 .gt => try w.print("zig_align({}) ", .{alignas.toByteUnits()}),
1800 }1805 }
18011806
1802 const trailing =1807 const trailing = try renderTypePrefix(dg.pass, store.*, mod, w, cty_idx, .suffix, qualifiers);
1803 try renderTypePrefix(dg.decl_index, store.*, mod, w, cty_idx, .suffix, qualifiers);
1804 try w.print("{}", .{trailing});1808 try w.print("{}", .{trailing});
1805 try dg.writeCValue(w, name);1809 try dg.writeCValue(w, name);
1806 try renderTypeSuffix(dg.decl_index, store.*, mod, w, cty_idx, .suffix, .{});1810 try renderTypeSuffix(dg.pass, store.*, mod, w, cty_idx, .suffix, .{});
1807 }1811 }
18081812
1809 fn declIsGlobal(dg: *DeclGen, tv: TypedValue) bool {1813 fn declIsGlobal(dg: *DeclGen, tv: TypedValue) bool {
...@@ -2070,7 +2074,7 @@ fn renderTypeName(...@@ -2070,7 +2074,7 @@ fn renderTypeName(
2070 }2074 }
2071}2075}
2072fn renderTypePrefix(2076fn renderTypePrefix(
2073 decl: Decl.OptionalIndex,2077 pass: DeclGen.Pass,
2074 store: CType.Store.Set,2078 store: CType.Store.Set,
2075 mod: *Module,2079 mod: *Module,
2076 w: anytype,2080 w: anytype,
...@@ -2128,7 +2132,7 @@ fn renderTypePrefix(...@@ -2128,7 +2132,7 @@ fn renderTypePrefix(
2128 => |tag| {2132 => |tag| {
2129 const child_idx = cty.cast(CType.Payload.Child).?.data;2133 const child_idx = cty.cast(CType.Payload.Child).?.data;
2130 const child_trailing = try renderTypePrefix(2134 const child_trailing = try renderTypePrefix(
2131 decl,2135 pass,
2132 store,2136 store,
2133 mod,2137 mod,
2134 w,2138 w,
...@@ -2152,15 +2156,8 @@ fn renderTypePrefix(...@@ -2152,15 +2156,8 @@ fn renderTypePrefix(
2152 .vector,2156 .vector,
2153 => {2157 => {
2154 const child_idx = cty.cast(CType.Payload.Sequence).?.data.elem_type;2158 const child_idx = cty.cast(CType.Payload.Sequence).?.data.elem_type;
2155 const child_trailing = try renderTypePrefix(2159 const child_trailing =
2156 decl,2160 try renderTypePrefix(pass, store, mod, w, child_idx, .suffix, qualifiers);
2157 store,
2158 mod,
2159 w,
2160 child_idx,
2161 .suffix,
2162 qualifiers,
2163 );
2164 switch (parent_fix) {2161 switch (parent_fix) {
2165 .prefix => {2162 .prefix => {
2166 try w.print("{}(", .{child_trailing});2163 try w.print("{}(", .{child_trailing});
...@@ -2172,10 +2169,11 @@ fn renderTypePrefix(...@@ -2172,10 +2169,11 @@ fn renderTypePrefix(
21722169
2173 .fwd_anon_struct,2170 .fwd_anon_struct,
2174 .fwd_anon_union,2171 .fwd_anon_union,
2175 => if (decl.unwrap()) |decl_index|2172 => switch (pass) {
2176 try w.print("anon__{d}_{d}", .{ @intFromEnum(decl_index), idx })2173 .decl => |decl_index| try w.print("decl__{d}_{d}", .{ @intFromEnum(decl_index), idx }),
2177 else2174 .anon => |anon_decl| try w.print("anon__{d}_{d}", .{ @intFromEnum(anon_decl), idx }),
2178 try renderTypeName(mod, w, idx, cty, ""),2175 .flush => try renderTypeName(mod, w, idx, cty, ""),
2176 },
21792177
2180 .fwd_struct,2178 .fwd_struct,
2181 .fwd_union,2179 .fwd_union,
...@@ -2201,7 +2199,7 @@ fn renderTypePrefix(...@@ -2201,7 +2199,7 @@ fn renderTypePrefix(
2201 .packed_struct,2199 .packed_struct,
2202 .packed_union,2200 .packed_union,
2203 => return renderTypePrefix(2201 => return renderTypePrefix(
2204 decl,2202 pass,
2205 store,2203 store,
2206 mod,2204 mod,
2207 w,2205 w,
...@@ -2214,7 +2212,7 @@ fn renderTypePrefix(...@@ -2214,7 +2212,7 @@ fn renderTypePrefix(
2214 .varargs_function,2212 .varargs_function,
2215 => {2213 => {
2216 const child_trailing = try renderTypePrefix(2214 const child_trailing = try renderTypePrefix(
2217 decl,2215 pass,
2218 store,2216 store,
2219 mod,2217 mod,
2220 w,2218 w,
...@@ -2241,7 +2239,7 @@ fn renderTypePrefix(...@@ -2241,7 +2239,7 @@ fn renderTypePrefix(
2241 return trailing;2239 return trailing;
2242}2240}
2243fn renderTypeSuffix(2241fn renderTypeSuffix(
2244 decl: Decl.OptionalIndex,2242 pass: DeclGen.Pass,
2245 store: CType.Store.Set,2243 store: CType.Store.Set,
2246 mod: *Module,2244 mod: *Module,
2247 w: anytype,2245 w: anytype,
...@@ -2295,7 +2293,7 @@ fn renderTypeSuffix(...@@ -2295,7 +2293,7 @@ fn renderTypeSuffix(
2295 .pointer_volatile,2293 .pointer_volatile,
2296 .pointer_const_volatile,2294 .pointer_const_volatile,
2297 => try renderTypeSuffix(2295 => try renderTypeSuffix(
2298 decl,2296 pass,
2299 store,2297 store,
2300 mod,2298 mod,
2301 w,2299 w,
...@@ -2314,7 +2312,7 @@ fn renderTypeSuffix(...@@ -2314,7 +2312,7 @@ fn renderTypeSuffix(
23142312
2315 try w.print("[{}]", .{cty.cast(CType.Payload.Sequence).?.data.len});2313 try w.print("[{}]", .{cty.cast(CType.Payload.Sequence).?.data.len});
2316 try renderTypeSuffix(2314 try renderTypeSuffix(
2317 decl,2315 pass,
2318 store,2316 store,
2319 mod,2317 mod,
2320 w,2318 w,
...@@ -2356,9 +2354,9 @@ fn renderTypeSuffix(...@@ -2356,9 +2354,9 @@ fn renderTypeSuffix(
2356 if (need_comma) try w.writeAll(", ");2354 if (need_comma) try w.writeAll(", ");
2357 need_comma = true;2355 need_comma = true;
2358 const trailing =2356 const trailing =
2359 try renderTypePrefix(decl, store, mod, w, param_type, .suffix, qualifiers);2357 try renderTypePrefix(pass, store, mod, w, param_type, .suffix, qualifiers);
2360 if (qualifiers.contains(.@"const")) try w.print("{}a{d}", .{ trailing, param_i });2358 if (qualifiers.contains(.@"const")) try w.print("{}a{d}", .{ trailing, param_i });
2361 try renderTypeSuffix(decl, store, mod, w, param_type, .suffix, .{});2359 try renderTypeSuffix(pass, store, mod, w, param_type, .suffix, .{});
2362 }2360 }
2363 switch (tag) {2361 switch (tag) {
2364 .function => {},2362 .function => {},
...@@ -2372,7 +2370,7 @@ fn renderTypeSuffix(...@@ -2372,7 +2370,7 @@ fn renderTypeSuffix(
2372 if (!need_comma) try w.writeAll("void");2370 if (!need_comma) try w.writeAll("void");
2373 try w.writeByte(')');2371 try w.writeByte(')');
23742372
2375 try renderTypeSuffix(decl, store, mod, w, data.return_type, .suffix, .{});2373 try renderTypeSuffix(pass, store, mod, w, data.return_type, .suffix, .{});
2376 },2374 },
2377 }2375 }
2378}2376}
...@@ -2392,9 +2390,9 @@ fn renderAggregateFields(...@@ -2392,9 +2390,9 @@ fn renderAggregateFields(
2392 .eq => {},2390 .eq => {},
2393 .gt => try writer.print("zig_align({}) ", .{field.alignas.toByteUnits()}),2391 .gt => try writer.print("zig_align({}) ", .{field.alignas.toByteUnits()}),
2394 }2392 }
2395 const trailing = try renderTypePrefix(.none, store, mod, writer, field.type, .suffix, .{});2393 const trailing = try renderTypePrefix(.flush, store, mod, writer, field.type, .suffix, .{});
2396 try writer.print("{}{ }", .{ trailing, fmtIdent(mem.span(field.name)) });2394 try writer.print("{}{ }", .{ trailing, fmtIdent(mem.span(field.name)) });
2397 try renderTypeSuffix(.none, store, mod, writer, field.type, .suffix, .{});2395 try renderTypeSuffix(.flush, store, mod, writer, field.type, .suffix, .{});
2398 try writer.writeAll(";\n");2396 try writer.writeAll(";\n");
2399 }2397 }
2400 try writer.writeByteNTimes(' ', indent);2398 try writer.writeByteNTimes(' ', indent);
...@@ -2406,18 +2404,18 @@ pub fn genTypeDecl(...@@ -2406,18 +2404,18 @@ pub fn genTypeDecl(
2406 writer: anytype,2404 writer: anytype,
2407 global_store: CType.Store.Set,2405 global_store: CType.Store.Set,
2408 global_idx: CType.Index,2406 global_idx: CType.Index,
2409 decl: Decl.OptionalIndex,2407 pass: DeclGen.Pass,
2410 decl_store: CType.Store.Set,2408 decl_store: CType.Store.Set,
2411 decl_idx: CType.Index,2409 decl_idx: CType.Index,
2412 found_existing: bool,2410 found_existing: bool,
2413) !void {2411) !void {
2414 const global_cty = global_store.indexToCType(global_idx);2412 const global_cty = global_store.indexToCType(global_idx);
2415 switch (global_cty.tag()) {2413 switch (global_cty.tag()) {
2416 .fwd_anon_struct => if (decl != .none) {2414 .fwd_anon_struct => if (pass != .flush) {
2417 try writer.writeAll("typedef ");2415 try writer.writeAll("typedef ");
2418 _ = try renderTypePrefix(.none, global_store, mod, writer, global_idx, .suffix, .{});2416 _ = try renderTypePrefix(.flush, global_store, mod, writer, global_idx, .suffix, .{});
2419 try writer.writeByte(' ');2417 try writer.writeByte(' ');
2420 _ = try renderTypePrefix(decl, decl_store, mod, writer, decl_idx, .suffix, .{});2418 _ = try renderTypePrefix(pass, decl_store, mod, writer, decl_idx, .suffix, .{});
2421 try writer.writeAll(";\n");2419 try writer.writeAll(";\n");
2422 },2420 },
24232421
...@@ -2435,7 +2433,15 @@ pub fn genTypeDecl(...@@ -2435,7 +2433,15 @@ pub fn genTypeDecl(
2435 .fwd_union,2433 .fwd_union,
2436 => {2434 => {
2437 const owner_decl = global_cty.cast(CType.Payload.FwdDecl).?.data;2435 const owner_decl = global_cty.cast(CType.Payload.FwdDecl).?.data;
2438 _ = try renderTypePrefix(.none, global_store, mod, writer, global_idx, .suffix, .{});2436 _ = try renderTypePrefix(
2437 .flush,
2438 global_store,
2439 mod,
2440 writer,
2441 global_idx,
2442 .suffix,
2443 .{},
2444 );
2439 try writer.writeAll("; // ");2445 try writer.writeAll("; // ");
2440 try mod.declPtr(owner_decl).renderFullyQualifiedName(mod, writer);2446 try mod.declPtr(owner_decl).renderFullyQualifiedName(mod, writer);
2441 try writer.writeByte('\n');2447 try writer.writeByte('\n');
...@@ -2552,7 +2558,7 @@ fn genExports(o: *Object) !void {...@@ -2552,7 +2558,7 @@ fn genExports(o: *Object) !void {
25522558
2553 const mod = o.dg.module;2559 const mod = o.dg.module;
2554 const ip = &mod.intern_pool;2560 const ip = &mod.intern_pool;
2555 const decl_index = o.dg.decl_index.unwrap().?;2561 const decl_index = o.dg.pass.decl;
2556 const decl = mod.declPtr(decl_index);2562 const decl = mod.declPtr(decl_index);
2557 const tv: TypedValue = .{ .ty = decl.ty, .val = (try decl.internValue(mod)).toValue() };2563 const tv: TypedValue = .{ .ty = decl.ty, .val = (try decl.internValue(mod)).toValue() };
2558 const fwd = o.dg.fwd_decl.writer();2564 const fwd = o.dg.fwd_decl.writer();
...@@ -2692,7 +2698,7 @@ pub fn genFunc(f: *Function) !void {...@@ -2692,7 +2698,7 @@ pub fn genFunc(f: *Function) !void {
2692 const o = &f.object;2698 const o = &f.object;
2693 const mod = o.dg.module;2699 const mod = o.dg.module;
2694 const gpa = o.dg.gpa;2700 const gpa = o.dg.gpa;
2695 const decl_index = o.dg.decl_index.unwrap().?;2701 const decl_index = o.dg.pass.decl;
2696 const decl = mod.declPtr(decl_index);2702 const decl = mod.declPtr(decl_index);
2697 const tv: TypedValue = .{2703 const tv: TypedValue = .{
2698 .ty = decl.ty,2704 .ty = decl.ty,
...@@ -2779,7 +2785,7 @@ pub fn genDecl(o: *Object) !void {...@@ -2779,7 +2785,7 @@ pub fn genDecl(o: *Object) !void {
2779 defer tracy.end();2785 defer tracy.end();
27802786
2781 const mod = o.dg.module;2787 const mod = o.dg.module;
2782 const decl_index = o.dg.decl_index.unwrap().?;2788 const decl_index = o.dg.pass.decl;
2783 const decl = mod.declPtr(decl_index);2789 const decl = mod.declPtr(decl_index);
2784 const tv: TypedValue = .{ .ty = decl.ty, .val = (try decl.internValue(mod)).toValue() };2790 const tv: TypedValue = .{ .ty = decl.ty, .val = (try decl.internValue(mod)).toValue() };
27852791
...@@ -2825,13 +2831,13 @@ pub fn genDeclValue(...@@ -2825,13 +2831,13 @@ pub fn genDeclValue(
2825 alignment: Alignment,2831 alignment: Alignment,
2826 link_section: InternPool.OptionalNullTerminatedString,2832 link_section: InternPool.OptionalNullTerminatedString,
2827) !void {2833) !void {
2834 const mod = o.dg.module;
2828 const fwd_decl_writer = o.dg.fwd_decl.writer();2835 const fwd_decl_writer = o.dg.fwd_decl.writer();
28292836
2830 try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static ");2837 try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static ");
2831 try o.dg.renderTypeAndName(fwd_decl_writer, tv.ty, decl_c_value, Const, alignment, .complete);2838 try o.dg.renderTypeAndName(fwd_decl_writer, tv.ty, decl_c_value, Const, alignment, .complete);
2832 try fwd_decl_writer.writeAll(";\n");2839 try fwd_decl_writer.writeAll(";\n");
28332840
2834 const mod = o.dg.module;
2835 const w = o.writer();2841 const w = o.writer();
2836 if (!is_global) try w.writeAll("static ");2842 if (!is_global) try w.writeAll("static ");
2837 if (mod.intern_pool.stringToSliceUnwrap(link_section)) |s|2843 if (mod.intern_pool.stringToSliceUnwrap(link_section)) |s|
...@@ -2848,7 +2854,7 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void {...@@ -2848,7 +2854,7 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void {
2848 defer tracy.end();2854 defer tracy.end();
28492855
2850 const mod = dg.module;2856 const mod = dg.module;
2851 const decl_index = dg.decl_index.unwrap().?;2857 const decl_index = dg.pass.decl;
2852 const decl = mod.declPtr(decl_index);2858 const decl = mod.declPtr(decl_index);
2853 const tv: TypedValue = .{2859 const tv: TypedValue = .{
2854 .ty = decl.ty,2860 .ty = decl.ty,
...@@ -2861,7 +2867,7 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void {...@@ -2861,7 +2867,7 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void {
2861 const is_global = dg.declIsGlobal(tv);2867 const is_global = dg.declIsGlobal(tv);
2862 if (is_global) {2868 if (is_global) {
2863 try writer.writeAll("zig_extern ");2869 try writer.writeAll("zig_extern ");
2864 try dg.renderFunctionSignature(writer, dg.decl_index.unwrap().?, .complete, .{ .export_index = 0 });2870 try dg.renderFunctionSignature(writer, dg.pass.decl, .complete, .{ .export_index = 0 });
2865 try dg.fwd_decl.appendSlice(";\n");2871 try dg.fwd_decl.appendSlice(";\n");
2866 }2872 }
2867 },2873 },
...@@ -7279,7 +7285,7 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7279,7 +7285,7 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
7279fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue {7285fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue {
7280 const mod = f.object.dg.module;7286 const mod = f.object.dg.module;
7281 const inst_ty = f.typeOfIndex(inst);7287 const inst_ty = f.typeOfIndex(inst);
7282 const decl_index = f.object.dg.decl_index.unwrap().?;7288 const decl_index = f.object.dg.pass.decl;
7283 const decl = mod.declPtr(decl_index);7289 const decl = mod.declPtr(decl_index);
7284 const fn_cty = try f.typeToCType(decl.ty, .complete);7290 const fn_cty = try f.typeToCType(decl.ty, .complete);
7285 const param_len = fn_cty.castTag(.varargs_function).?.data.param_types.len;7291 const param_len = fn_cty.castTag(.varargs_function).?.data.param_types.len;
src/link/C.zig+12-14
...@@ -158,9 +158,7 @@ pub fn updateFunc(...@@ -158,9 +158,7 @@ pub fn updateFunc(
158 const decl_index = func.owner_decl;158 const decl_index = func.owner_decl;
159 const decl = module.declPtr(decl_index);159 const decl = module.declPtr(decl_index);
160 const gop = try self.decl_table.getOrPut(gpa, decl_index);160 const gop = try self.decl_table.getOrPut(gpa, decl_index);
161 if (!gop.found_existing) {161 if (!gop.found_existing) gop.value_ptr.* = .{};
162 gop.value_ptr.* = .{};
163 }
164 const ctypes = &gop.value_ptr.ctypes;162 const ctypes = &gop.value_ptr.ctypes;
165 const lazy_fns = &gop.value_ptr.lazy_fns;163 const lazy_fns = &gop.value_ptr.lazy_fns;
166 const fwd_decl = &self.fwd_decl_buf;164 const fwd_decl = &self.fwd_decl_buf;
...@@ -180,7 +178,7 @@ pub fn updateFunc(...@@ -180,7 +178,7 @@ pub fn updateFunc(
180 .gpa = gpa,178 .gpa = gpa,
181 .module = module,179 .module = module,
182 .error_msg = null,180 .error_msg = null,
183 .decl_index = decl_index.toOptional(),181 .pass = .{ .decl = decl_index },
184 .is_naked_fn = decl.ty.fnCallingConvention(module) == .Naked,182 .is_naked_fn = decl.ty.fnCallingConvention(module) == .Naked,
185 .fwd_decl = fwd_decl.toManaged(gpa),183 .fwd_decl = fwd_decl.toManaged(gpa),
186 .ctypes = ctypes.*,184 .ctypes = ctypes.*,
...@@ -235,7 +233,7 @@ fn updateAnonDecl(self: *C, module: *Module, i: usize) !void {...@@ -235,7 +233,7 @@ fn updateAnonDecl(self: *C, module: *Module, i: usize) !void {
235 .gpa = gpa,233 .gpa = gpa,
236 .module = module,234 .module = module,
237 .error_msg = null,235 .error_msg = null,
238 .decl_index = .none,236 .pass = .{ .anon = anon_decl },
239 .is_naked_fn = false,237 .is_naked_fn = false,
240 .fwd_decl = fwd_decl.toManaged(gpa),238 .fwd_decl = fwd_decl.toManaged(gpa),
241 .ctypes = .{},239 .ctypes = .{},
...@@ -302,7 +300,7 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi...@@ -302,7 +300,7 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi
302 .gpa = gpa,300 .gpa = gpa,
303 .module = module,301 .module = module,
304 .error_msg = null,302 .error_msg = null,
305 .decl_index = decl_index.toOptional(),303 .pass = .{ .decl = decl_index },
306 .is_naked_fn = false,304 .is_naked_fn = false,
307 .fwd_decl = fwd_decl.toManaged(gpa),305 .fwd_decl = fwd_decl.toManaged(gpa),
308 .ctypes = ctypes.*,306 .ctypes = ctypes.*,
...@@ -438,14 +436,14 @@ pub fn flushModule(self: *C, _: *Compilation, prog_node: *std.Progress.Node) !vo...@@ -438,14 +436,14 @@ pub fn flushModule(self: *C, _: *Compilation, prog_node: *std.Progress.Node) !vo
438 // We need to flush lazy ctypes after flushing all decls but before flushing any decl ctypes.436 // We need to flush lazy ctypes after flushing all decls but before flushing any decl ctypes.
439 // This ensures that every lazy CType.Index exactly matches the global CType.Index.437 // This ensures that every lazy CType.Index exactly matches the global CType.Index.
440 assert(f.ctypes.count() == 0);438 assert(f.ctypes.count() == 0);
441 try self.flushCTypes(&f, .none, f.lazy_ctypes);439 try self.flushCTypes(&f, .flush, f.lazy_ctypes);
442440
443 for (self.anon_decls.values()) |decl_block| {441 for (self.anon_decls.keys(), self.anon_decls.values()) |anon_decl, decl_block| {
444 try self.flushCTypes(&f, .none, decl_block.ctypes);442 try self.flushCTypes(&f, .{ .anon = anon_decl }, decl_block.ctypes);
445 }443 }
446444
447 for (self.decl_table.keys(), self.decl_table.values()) |decl_index, decl_block| {445 for (self.decl_table.keys(), self.decl_table.values()) |decl_index, decl_block| {
448 try self.flushCTypes(&f, decl_index.toOptional(), decl_block.ctypes);446 try self.flushCTypes(&f, .{ .decl = decl_index }, decl_block.ctypes);
449 }447 }
450 }448 }
451449
...@@ -516,7 +514,7 @@ const FlushDeclError = error{...@@ -516,7 +514,7 @@ const FlushDeclError = error{
516fn flushCTypes(514fn flushCTypes(
517 self: *C,515 self: *C,
518 f: *Flush,516 f: *Flush,
519 decl_index: Module.Decl.OptionalIndex,517 pass: codegen.DeclGen.Pass,
520 decl_ctypes: codegen.CType.Store,518 decl_ctypes: codegen.CType.Store,
521) FlushDeclError!void {519) FlushDeclError!void {
522 const gpa = self.base.allocator;520 const gpa = self.base.allocator;
...@@ -591,7 +589,7 @@ fn flushCTypes(...@@ -591,7 +589,7 @@ fn flushCTypes(
591 writer,589 writer,
592 global_ctypes.set,590 global_ctypes.set,
593 global_idx,591 global_idx,
594 decl_index,592 pass,
595 decl_ctypes.set,593 decl_ctypes.set,
596 decl_idx,594 decl_idx,
597 gop.found_existing,595 gop.found_existing,
...@@ -610,7 +608,7 @@ fn flushErrDecls(self: *C, ctypes: *codegen.CType.Store) FlushDeclError!void {...@@ -610,7 +608,7 @@ fn flushErrDecls(self: *C, ctypes: *codegen.CType.Store) FlushDeclError!void {
610 .gpa = gpa,608 .gpa = gpa,
611 .module = self.base.options.module.?,609 .module = self.base.options.module.?,
612 .error_msg = null,610 .error_msg = null,
613 .decl_index = .none,611 .pass = .flush,
614 .is_naked_fn = false,612 .is_naked_fn = false,
615 .fwd_decl = fwd_decl.toManaged(gpa),613 .fwd_decl = fwd_decl.toManaged(gpa),
616 .ctypes = ctypes.*,614 .ctypes = ctypes.*,
...@@ -652,7 +650,7 @@ fn flushLazyFn(...@@ -652,7 +650,7 @@ fn flushLazyFn(
652 .gpa = gpa,650 .gpa = gpa,
653 .module = self.base.options.module.?,651 .module = self.base.options.module.?,
654 .error_msg = null,652 .error_msg = null,
655 .decl_index = .none,653 .pass = .flush,
656 .is_naked_fn = false,654 .is_naked_fn = false,
657 .fwd_decl = fwd_decl.toManaged(gpa),655 .fwd_decl = fwd_decl.toManaged(gpa),
658 .ctypes = ctypes.*,656 .ctypes = ctypes.*,
src/link/Coff.zig+40-35
...@@ -1737,46 +1737,51 @@ pub fn getDeclVAddr(self: *Coff, decl_index: Module.Decl.Index, reloc_info: link...@@ -1737,46 +1737,51 @@ pub fn getDeclVAddr(self: *Coff, decl_index: Module.Decl.Index, reloc_info: link
1737 return 0;1737 return 0;
1738}1738}
17391739
1740pub fn lowerAnonDecl(self: *Coff, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !codegen.Result {1740pub fn lowerAnonDecl(
1741 // This is basically the same as lowerUnnamedConst.1741 self: *Coff,
1742 // example:1742 decl_val: InternPool.Index,
1743 // const ty = mod.intern_pool.typeOf(decl_val).toType();1743 explicit_alignment: InternPool.Alignment,
1744 // const val = decl_val.toValue();1744 src_loc: Module.SrcLoc,
1745 // The symbol name can be something like `__anon_{d}` with `@intFromEnum(decl_val)`.1745) !codegen.Result {
1746 // It doesn't have an owner decl because it's just an unnamed constant that might
1747 // be used by more than one function, however, its address is being used so we need
1748 // to put it in some location.
1749 // ...
1750 const gpa = self.base.allocator;1746 const gpa = self.base.allocator;
1751 const mod = self.base.options.module.?;1747 const mod = self.base.options.module.?;
1752 const ty = mod.intern_pool.typeOf(decl_val).toType();1748 const ty = mod.intern_pool.typeOf(decl_val).toType();
1753 const gop = try self.anon_decls.getOrPut(gpa, decl_val);1749 const decl_alignment = switch (explicit_alignment) {
1754 const required_alignment = switch (decl_align) {
1755 .none => ty.abiAlignment(mod),1750 .none => ty.abiAlignment(mod),
1756 else => decl_align,1751 else => explicit_alignment,
1757 };1752 };
1758 if (!gop.found_existing or1753 if (self.anon_decls.get(decl_val)) |atom_index| {
1759 !required_alignment.check(self.getAtom(gop.value_ptr.*).getSymbol(self).value))1754 const existing_addr = self.getAtom(atom_index).getSymbol(self).value;
1760 {1755 if (decl_alignment.check(existing_addr))
1761 const val = decl_val.toValue();1756 return .ok;
1762 const tv = TypedValue{ .ty = ty, .val = val };1757 }
1763 const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)});1758
1764 defer gpa.free(name);1759 const val = decl_val.toValue();
1765 const res = self.lowerConst(name, tv, required_alignment, self.rdata_section_index.?, src_loc) catch |err| switch (err) {1760 const tv = TypedValue{ .ty = ty, .val = val };
1766 else => {1761 var name_buf: [32]u8 = undefined;
1767 // TODO improve error message1762 const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{
1768 const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{1763 @intFromEnum(decl_val),
1769 @errorName(err),1764 }) catch unreachable;
1770 });1765 const res = self.lowerConst(
1771 return .{ .fail = em };1766 name,
1772 },1767 tv,
1773 };1768 decl_alignment,
1774 const atom_index = switch (res) {1769 self.rdata_section_index.?,
1775 .ok => |atom_index| atom_index,1770 src_loc,
1776 .fail => |em| return .{ .fail = em },1771 ) catch |err| switch (err) {
1777 };1772 error.OutOfMemory => return error.OutOfMemory,
1778 gop.value_ptr.* = atom_index;1773 else => |e| return .{ .fail = try Module.ErrorMsg.create(
1779 }1774 gpa,
1775 src_loc,
1776 "lowerAnonDecl failed with error: {s}",
1777 .{@errorName(e)},
1778 ) },
1779 };
1780 const atom_index = switch (res) {
1781 .ok => |atom_index| atom_index,
1782 .fail => |em| return .{ .fail = em },
1783 };
1784 try self.anon_decls.put(gpa, decl_val, atom_index);
1780 return .ok;1785 return .ok;
1781}1786}
17821787
src/link/Elf.zig+40-35
...@@ -484,46 +484,51 @@ pub fn getDeclVAddr(self: *Elf, decl_index: Module.Decl.Index, reloc_info: link....@@ -484,46 +484,51 @@ pub fn getDeclVAddr(self: *Elf, decl_index: Module.Decl.Index, reloc_info: link.
484 return vaddr;484 return vaddr;
485}485}
486486
487pub fn lowerAnonDecl(self: *Elf, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !codegen.Result {487pub fn lowerAnonDecl(
488 // This is basically the same as lowerUnnamedConst.488 self: *Elf,
489 // example:489 decl_val: InternPool.Index,
490 // const ty = mod.intern_pool.typeOf(decl_val).toType();490 explicit_alignment: InternPool.Alignment,
491 // const val = decl_val.toValue();491 src_loc: Module.SrcLoc,
492 // The symbol name can be something like `__anon_{d}` with `@intFromEnum(decl_val)`.492) !codegen.Result {
493 // It doesn't have an owner decl because it's just an unnamed constant that might
494 // be used by more than one function, however, its address is being used so we need
495 // to put it in some location.
496 // ...
497 const gpa = self.base.allocator;493 const gpa = self.base.allocator;
498 const mod = self.base.options.module.?;494 const mod = self.base.options.module.?;
499 const ty = mod.intern_pool.typeOf(decl_val).toType();495 const ty = mod.intern_pool.typeOf(decl_val).toType();
500 const gop = try self.anon_decls.getOrPut(gpa, decl_val);496 const decl_alignment = switch (explicit_alignment) {
501 const required_alignment = switch (decl_align) {
502 .none => ty.abiAlignment(mod),497 .none => ty.abiAlignment(mod),
503 else => decl_align,498 else => explicit_alignment,
504 };499 };
505 if (!gop.found_existing or500 if (self.anon_decls.get(decl_val)) |sym_index| {
506 required_alignment.order(self.symbol(gop.value_ptr.*).atom(self).?.alignment).compare(.gt))501 const existing_alignment = self.symbol(sym_index).atom(self).?.alignment;
507 {502 if (decl_alignment.order(existing_alignment).compare(.lte))
508 const val = decl_val.toValue();503 return .ok;
509 const tv = TypedValue{ .ty = ty, .val = val };504 }
510 const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)});505
511 defer gpa.free(name);506 const val = decl_val.toValue();
512 const res = self.lowerConst(name, tv, required_alignment, self.zig_rodata_section_index.?, src_loc) catch |err| switch (err) {507 const tv = TypedValue{ .ty = ty, .val = val };
513 else => {508 var name_buf: [32]u8 = undefined;
514 // TODO improve error message509 const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{
515 const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{510 @intFromEnum(decl_val),
516 @errorName(err),511 }) catch unreachable;
517 });512 const res = self.lowerConst(
518 return .{ .fail = em };513 name,
519 },514 tv,
520 };515 decl_alignment,
521 const sym_index = switch (res) {516 self.zig_rodata_section_index.?,
522 .ok => |sym_index| sym_index,517 src_loc,
523 .fail => |em| return .{ .fail = em },518 ) catch |err| switch (err) {
524 };519 error.OutOfMemory => return error.OutOfMemory,
525 gop.value_ptr.* = sym_index;520 else => |e| return .{ .fail = try Module.ErrorMsg.create(
526 }521 gpa,
522 src_loc,
523 "unable to lower constant value: {s}",
524 .{@errorName(e)},
525 ) },
526 };
527 const sym_index = switch (res) {
528 .ok => |sym_index| sym_index,
529 .fail => |em| return .{ .fail = em },
530 };
531 try self.anon_decls.put(gpa, decl_val, sym_index);
527 return .ok;532 return .ok;
528}533}
529534
src/link/MachO.zig+40-35
...@@ -2866,46 +2866,51 @@ pub fn getDeclVAddr(self: *MachO, decl_index: Module.Decl.Index, reloc_info: Fil...@@ -2866,46 +2866,51 @@ pub fn getDeclVAddr(self: *MachO, decl_index: Module.Decl.Index, reloc_info: Fil
2866 return 0;2866 return 0;
2867}2867}
28682868
2869pub fn lowerAnonDecl(self: *MachO, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !codegen.Result {2869pub fn lowerAnonDecl(
2870 // This is basically the same as lowerUnnamedConst.2870 self: *MachO,
2871 // example:2871 decl_val: InternPool.Index,
2872 // const ty = mod.intern_pool.typeOf(decl_val).toType();2872 explicit_alignment: InternPool.Alignment,
2873 // const val = decl_val.toValue();2873 src_loc: Module.SrcLoc,
2874 // The symbol name can be something like `__anon_{d}` with `@intFromEnum(decl_val)`.2874) !codegen.Result {
2875 // It doesn't have an owner decl because it's just an unnamed constant that might
2876 // be used by more than one function, however, its address is being used so we need
2877 // to put it in some location.
2878 // ...
2879 const gpa = self.base.allocator;2875 const gpa = self.base.allocator;
2880 const mod = self.base.options.module.?;2876 const mod = self.base.options.module.?;
2881 const ty = mod.intern_pool.typeOf(decl_val).toType();2877 const ty = mod.intern_pool.typeOf(decl_val).toType();
2882 const gop = try self.anon_decls.getOrPut(gpa, decl_val);2878 const decl_alignment = switch (explicit_alignment) {
2883 const required_alignment = switch (decl_align) {
2884 .none => ty.abiAlignment(mod),2879 .none => ty.abiAlignment(mod),
2885 else => decl_align,2880 else => explicit_alignment,
2886 };2881 };
2887 if (!gop.found_existing or2882 if (self.anon_decls.get(decl_val)) |atom_index| {
2888 !required_alignment.check(self.getAtom(gop.value_ptr.*).getSymbol(self).n_value))2883 const existing_addr = self.getAtom(atom_index).getSymbol(self).n_value;
2889 {2884 if (decl_alignment.check(existing_addr))
2890 const val = decl_val.toValue();2885 return .ok;
2891 const tv = TypedValue{ .ty = ty, .val = val };2886 }
2892 const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)});2887
2893 defer gpa.free(name);2888 const val = decl_val.toValue();
2894 const res = self.lowerConst(name, tv, required_alignment, self.data_const_section_index.?, src_loc) catch |err| switch (err) {2889 const tv = TypedValue{ .ty = ty, .val = val };
2895 else => {2890 var name_buf: [32]u8 = undefined;
2896 // TODO improve error message2891 const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{
2897 const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{2892 @intFromEnum(decl_val),
2898 @errorName(err),2893 }) catch unreachable;
2899 });2894 const res = self.lowerConst(
2900 return .{ .fail = em };2895 name,
2901 },2896 tv,
2902 };2897 decl_alignment,
2903 const atom_index = switch (res) {2898 self.data_const_section_index.?,
2904 .ok => |atom_index| atom_index,2899 src_loc,
2905 .fail => |em| return .{ .fail = em },2900 ) catch |err| switch (err) {
2906 };2901 error.OutOfMemory => return error.OutOfMemory,
2907 gop.value_ptr.* = atom_index;2902 else => |e| return .{ .fail = try Module.ErrorMsg.create(
2908 }2903 gpa,
2904 src_loc,
2905 "unable to lower constant value: {s}",
2906 .{@errorName(e)},
2907 ) },
2908 };
2909 const atom_index = switch (res) {
2910 .ok => |atom_index| atom_index,
2911 .fail => |em| return .{ .fail = em },
2912 };
2913 try self.anon_decls.put(gpa, decl_val, atom_index);
2909 return .ok;2914 return .ok;
2910}2915}
29112916
src/link/Wasm.zig+15-8
...@@ -1702,27 +1702,34 @@ pub fn getDeclVAddr(...@@ -1702,27 +1702,34 @@ pub fn getDeclVAddr(
1702 return target_symbol_index;1702 return target_symbol_index;
1703}1703}
17041704
1705pub fn lowerAnonDecl(wasm: *Wasm, decl_val: InternPool.Index, decl_align: Alignment, src_loc: Module.SrcLoc) !codegen.Result {1705pub fn lowerAnonDecl(
1706 wasm: *Wasm,
1707 decl_val: InternPool.Index,
1708 explicit_alignment: Alignment,
1709 src_loc: Module.SrcLoc,
1710) !codegen.Result {
1706 const gop = try wasm.anon_decls.getOrPut(wasm.base.allocator, decl_val);1711 const gop = try wasm.anon_decls.getOrPut(wasm.base.allocator, decl_val);
1707 if (!gop.found_existing) {1712 if (!gop.found_existing) {
1708 const mod = wasm.base.options.module.?;1713 const mod = wasm.base.options.module.?;
1709 const ty = mod.intern_pool.typeOf(decl_val).toType();1714 const ty = mod.intern_pool.typeOf(decl_val).toType();
1710 const tv: TypedValue = .{ .ty = ty, .val = decl_val.toValue() };1715 const tv: TypedValue = .{ .ty = ty, .val = decl_val.toValue() };
1711 const name = try std.fmt.allocPrintZ(wasm.base.allocator, "__anon_{d}", .{@intFromEnum(decl_val)});1716 var name_buf: [32]u8 = undefined;
1712 defer wasm.base.allocator.free(name);1717 const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{
1718 @intFromEnum(decl_val),
1719 }) catch unreachable;
17131720
1714 switch (try wasm.lowerConst(name, tv, src_loc)) {1721 switch (try wasm.lowerConst(name, tv, src_loc)) {
1715 .ok => |atom_index| gop.value_ptr.* = atom_index,1722 .ok => |atom_index| wasm.anon_decls.values()[gop.index] = atom_index,
1716 .fail => |em| return .{ .fail = em },1723 .fail => |em| return .{ .fail = em },
1717 }1724 }
1718 }1725 }
17191726
1720 const atom = wasm.getAtomPtr(gop.value_ptr.*);1727 const atom = wasm.getAtomPtr(wasm.anon_decls.values()[gop.index]);
1721 atom.alignment = switch (atom.alignment) {1728 atom.alignment = switch (atom.alignment) {
1722 .none => decl_align,1729 .none => explicit_alignment,
1723 else => switch (decl_align) {1730 else => switch (explicit_alignment) {
1724 .none => atom.alignment,1731 .none => atom.alignment,
1725 else => atom.alignment.maxStrict(decl_align),1732 else => atom.alignment.maxStrict(explicit_alignment),
1726 },1733 },
1727 };1734 };
1728 return .ok;1735 return .ok;