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
signaturebadge-question-mark 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
35563556 .gpa = gpa,
35573557 .module = module,
35583558 .error_msg = null,
3559 .decl_index = decl_index.toOptional(),
3559 .pass = .{ .decl = decl_index },
35603560 .is_naked_fn = false,
35613561 .fwd_decl = fwd_decl.toManaged(gpa),
35623562 .ctypes = .{},
src/Sema.zig+216-339
......@@ -5466,21 +5466,30 @@ fn addStrLitNoAlias(sema: *Sema, bytes: []const u8) CompileError!Air.Inst.Ref {
54665466 .ty = array_ty.toIntern(),
54675467 .storage = .{ .bytes = bytes },
54685468 } });
5469 const ptr_ty = try sema.ptrType(.{
5470 .child = array_ty.toIntern(),
5469 return anonDeclRef(sema, val);
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),
54715480 .flags = .{
54725481 .alignment = .none,
54735482 .is_const = true,
54745483 .address_space = .generic,
54755484 },
5476 });
5477 return Air.internedToRef((try mod.intern(.{ .ptr = .{
5478 .ty = ptr_ty.toIntern(),
5485 })).toIntern();
5486 return mod.intern(.{ .ptr = .{
5487 .ty = ptr_ty,
54795488 .addr = .{ .anon_decl = .{
54805489 .val = val,
5481 .orig_ty = ptr_ty.toIntern(),
5490 .orig_ty = ptr_ty,
54825491 } },
5483 } })));
5492 } });
54845493}
54855494
54865495fn zirInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -10740,7 +10749,7 @@ const SwitchProngAnalysis = struct {
1074010749 return block.addStructFieldVal(spa.operand, field_index, field_ty);
1074110750 }
1074210751 } else if (capture_byref) {
10743 return sema.addConstantMaybeRef(block, operand_ty, item_val, true);
10752 return anonDeclRef(sema, item_val.toIntern());
1074410753 } else {
1074510754 return inline_case_capture;
1074610755 }
......@@ -13765,10 +13774,10 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1376513774 const coerced_elem_val = try sema.resolveConstValue(block, .unneeded, coerced_elem_val_inst, undefined);
1376613775 element_vals[elem_i] = try coerced_elem_val.intern(resolved_elem_ty, mod);
1376713776 }
13768 return sema.addConstantMaybeRef(block, result_ty, (try mod.intern(.{ .aggregate = .{
13777 return sema.addConstantMaybeRef(try mod.intern(.{ .aggregate = .{
1376913778 .ty = result_ty.toIntern(),
1377013779 .storage = .{ .elems = element_vals },
13771 } })).toValue(), ptr_addrspace != null);
13780 } }), ptr_addrspace != null);
1377213781 } else break :rs rhs_src;
1377313782 } else lhs_src;
1377413783
......@@ -14034,7 +14043,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1403414043 .storage = .{ .elems = element_vals },
1403514044 } });
1403614045 };
14037 return sema.addConstantMaybeRef(block, result_ty, val.toValue(), ptr_addrspace != null);
14046 return sema.addConstantMaybeRef(val, ptr_addrspace != null);
1403814047 }
1403914048
1404014049 try sema.requireRuntimeBlock(block, src, lhs_src);
......@@ -16724,54 +16733,49 @@ fn zirBuiltinSrc(
1672416733 const src = LazySrcLoc.nodeOffset(extra.node);
1672516734 if (sema.func_index == .none) return sema.fail(block, src, "@src outside function", .{});
1672616735 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: {
16729 var anon_decl = try block.startAnonDecl();
16730 defer anon_decl.deinit();
16731 // TODO: write something like getCoercedInts to avoid needing to dupe
16732 const name = try sema.arena.dupe(u8, mod.intern_pool.stringToSlice(fn_owner_decl.name));
16733 const new_decl_ty = try mod.arrayType(.{
16734 .len = name.len,
16739 const func_name_val = v: {
16740 // This dupe prevents InternPool string pool memory from being reallocated
16741 // while a reference exists.
16742 const bytes = try sema.arena.dupe(u8, ip.stringToSlice(fn_owner_decl.name));
16743 const array_ty = try ip.get(gpa, .{ .array_type = .{
16744 .len = bytes.len,
1673516745 .sentinel = .zero_u8,
1673616746 .child = .u8_type,
16737 });
16738 const new_decl = try anon_decl.finish(
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 } });
16748 break :v try ip.get(gpa, .{ .ptr = .{
1674716749 .ty = .slice_const_u8_sentinel_0_type,
16748 .addr = .{ .decl = new_decl },
16749 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),
16750 .len = (try mod.intValue(Type.usize, bytes.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 } },
1675016758 } });
1675116759 };
1675216760
16753 const file_name_val = blk: {
16754 var anon_decl = try block.startAnonDecl();
16755 defer anon_decl.deinit();
16761 const file_name_val = v: {
1675616762 // The compiler must not call realpath anywhere.
16757 const name = try fn_owner_decl.getFileScope(mod).fullPathZ(sema.arena);
16758 const new_decl_ty = try mod.arrayType(.{
16759 .len = name.len,
16763 const bytes = try fn_owner_decl.getFileScope(mod).fullPathZ(sema.arena);
16764 const array_ty = try ip.get(gpa, .{ .array_type = .{
16765 .len = bytes.len,
1676016766 .sentinel = .zero_u8,
1676116767 .child = .u8_type,
16762 });
16763 const new_decl = try anon_decl.finish(
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 = .{
16768 } });
16769 break :v try ip.get(gpa, .{ .ptr = .{
1677216770 .ty = .slice_const_u8_sentinel_0_type,
16773 .addr = .{ .decl = new_decl },
16774 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),
16771 .len = (try mod.intValue(Type.usize, bytes.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 } },
1677516779 } });
1677616780 };
1677716781
......@@ -16818,10 +16822,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1681816822 .val = .void_value,
1681916823 } }))),
1682016824 .Fn => {
16821 // TODO: look into memoizing this result.
16822 var params_anon_decl = try block.startAnonDecl();
16823 defer params_anon_decl.deinit();
16824
1682516825 const fn_info_decl_index = (try sema.namespaceLookup(
1682616826 block,
1682716827 src,
......@@ -16878,23 +16878,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1687816878 .len = param_vals.len,
1687916879 .child = param_info_ty.toIntern(),
1688016880 });
16881 const new_decl = try params_anon_decl.finish(
16882 new_decl_ty,
16883 (try mod.intern(.{ .aggregate = .{
16884 .ty = new_decl_ty.toIntern(),
16885 .storage = .{ .elems = param_vals },
16886 } })).toValue(),
16887 .none, // default alignment
16888 );
16881 const new_decl_val = try mod.intern(.{ .aggregate = .{
16882 .ty = new_decl_ty.toIntern(),
16883 .storage = .{ .elems = param_vals },
16884 } });
16885 const ptr_ty = (try sema.ptrType(.{
16886 .child = param_info_ty.toIntern(),
16887 .flags = .{
16888 .size = .Slice,
16889 .is_const = true,
16890 },
16891 })).toIntern();
1688916892 break :v try mod.intern(.{ .ptr = .{
16890 .ty = (try sema.ptrType(.{
16891 .child = param_info_ty.toIntern(),
16892 .flags = .{
16893 .size = .Slice,
16894 .is_const = true,
16895 },
16896 })).toIntern(),
16897 .addr = .{ .decl = new_decl },
16893 .ty = ptr_ty,
16894 .addr = .{ .anon_decl = .{
16895 .orig_ty = ptr_ty,
16896 .val = new_decl_val,
16897 } },
1689816898 .len = (try mod.intValue(Type.usize, param_vals.len)).toIntern(),
1689916899 } });
1690016900 };
......@@ -17035,7 +17035,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1703517035 // is_allowzero: bool,
1703617036 Value.makeBool(info.flags.is_allowzero).toIntern(),
1703717037 // sentinel: ?*const anyopaque,
17038 (try sema.optRefValue(block, info.child.toType(), switch (info.sentinel) {
17038 (try sema.optRefValue(switch (info.sentinel) {
1703917039 .none => null,
1704017040 else => info.sentinel.toValue(),
1704117041 })).toIntern(),
......@@ -17070,7 +17070,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1707017070 // child: type,
1707117071 info.elem_type.toIntern(),
1707217072 // sentinel: ?*const anyopaque,
17073 (try sema.optRefValue(block, info.elem_type, info.sentinel)).toIntern(),
17073 (try sema.optRefValue(info.sentinel)).toIntern(),
1707417074 };
1707517075 return Air.internedToRef((try mod.intern(.{ .un = .{
1707617076 .ty = type_info_ty.toIntern(),
......@@ -17139,9 +17139,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1713917139 } })));
1714017140 },
1714117141 .ErrorSet => {
17142 var fields_anon_decl = try block.startAnonDecl();
17143 defer fields_anon_decl.deinit();
17144
1714517142 // Get the Error type
1714617143 const error_field_ty = t: {
1714717144 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
1717017167 // TODO: write something like getCoercedInts to avoid needing to dupe
1717117168 const name = try sema.arena.dupe(u8, ip.stringToSlice(names.get(ip)[i]));
1717217169 const name_val = v: {
17173 var anon_decl = try block.startAnonDecl();
17174 defer anon_decl.deinit();
1717517170 const new_decl_ty = try mod.arrayType(.{
1717617171 .len = name.len,
1717717172 .child = .u8_type,
1717817173 });
17179 const new_decl = try anon_decl.finish(
17180 new_decl_ty,
17181 (try mod.intern(.{ .aggregate = .{
17182 .ty = new_decl_ty.toIntern(),
17183 .storage = .{ .bytes = name },
17184 } })).toValue(),
17185 .none, // default alignment
17186 );
17174 const new_decl_val = try mod.intern(.{ .aggregate = .{
17175 .ty = new_decl_ty.toIntern(),
17176 .storage = .{ .bytes = name },
17177 } });
1718717178 break :v try mod.intern(.{ .ptr = .{
1718817179 .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 } },
1719017184 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),
1719117185 } });
1719217186 };
......@@ -17219,17 +17213,16 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1721917213 .len = vals.len,
1722017214 .child = error_field_ty.toIntern(),
1722117215 });
17222 const new_decl = try fields_anon_decl.finish(
17223 array_errors_ty,
17224 (try mod.intern(.{ .aggregate = .{
17225 .ty = array_errors_ty.toIntern(),
17226 .storage = .{ .elems = vals },
17227 } })).toValue(),
17228 .none, // default alignment
17229 );
17216 const new_decl_val = try mod.intern(.{ .aggregate = .{
17217 .ty = array_errors_ty.toIntern(),
17218 .storage = .{ .elems = vals },
17219 } });
1723017220 break :v try mod.intern(.{ .ptr = .{
1723117221 .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 } },
1723317226 .len = (try mod.intValue(Type.usize, vals.len)).toIntern(),
1723417227 } });
1723517228 } else .none;
......@@ -17275,12 +17268,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1727517268 } })));
1727617269 },
1727717270 .Enum => {
17278 // TODO: look into memoizing this result.
1727917271 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
1728417273 const enum_field_ty = t: {
1728517274 const enum_field_ty_decl_index = (try sema.namespaceLookup(
1728617275 block,
......@@ -17308,23 +17297,20 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1730817297 // TODO: write something like getCoercedInts to avoid needing to dupe
1730917298 const name = try sema.arena.dupe(u8, ip.stringToSlice(enum_type.names.get(ip)[i]));
1731017299 const name_val = v: {
17311 var anon_decl = try block.startAnonDecl();
17312 defer anon_decl.deinit();
1731317300 const new_decl_ty = try mod.arrayType(.{
1731417301 .len = name.len,
1731517302 .child = .u8_type,
1731617303 });
17317 const new_decl = try anon_decl.finish(
17318 new_decl_ty,
17319 (try mod.intern(.{ .aggregate = .{
17320 .ty = new_decl_ty.toIntern(),
17321 .storage = .{ .bytes = name },
17322 } })).toValue(),
17323 .none, // default alignment
17324 );
17304 const new_decl_val = try mod.intern(.{ .aggregate = .{
17305 .ty = new_decl_ty.toIntern(),
17306 .storage = .{ .bytes = name },
17307 } });
1732517308 break :v try mod.intern(.{ .ptr = .{
1732617309 .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 } },
1732817314 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),
1732917315 } });
1733017316 };
......@@ -17346,23 +17332,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1734617332 .len = enum_field_vals.len,
1734717333 .child = enum_field_ty.toIntern(),
1734817334 });
17349 const new_decl = try fields_anon_decl.finish(
17350 fields_array_ty,
17351 (try mod.intern(.{ .aggregate = .{
17352 .ty = fields_array_ty.toIntern(),
17353 .storage = .{ .elems = enum_field_vals },
17354 } })).toValue(),
17355 .none, // default alignment
17356 );
17335 const new_decl_val = try mod.intern(.{ .aggregate = .{
17336 .ty = fields_array_ty.toIntern(),
17337 .storage = .{ .elems = enum_field_vals },
17338 } });
17339 const ptr_ty = (try sema.ptrType(.{
17340 .child = enum_field_ty.toIntern(),
17341 .flags = .{
17342 .size = .Slice,
17343 .is_const = true,
17344 },
17345 })).toIntern();
1735717346 break :v try mod.intern(.{ .ptr = .{
17358 .ty = (try sema.ptrType(.{
17359 .child = enum_field_ty.toIntern(),
17360 .flags = .{
17361 .size = .Slice,
17362 .is_const = true,
17363 },
17364 })).toIntern(),
17365 .addr = .{ .decl = new_decl },
17347 .ty = ptr_ty,
17348 .addr = .{ .anon_decl = .{
17349 .val = new_decl_val,
17350 .orig_ty = ptr_ty,
17351 } },
1736617352 .len = (try mod.intValue(Type.usize, enum_field_vals.len)).toIntern(),
1736717353 } });
1736817354 };
......@@ -17402,11 +17388,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1740217388 } })));
1740317389 },
1740417390 .Union => {
17405 // TODO: look into memoizing this result.
17406
17407 var fields_anon_decl = try block.startAnonDecl();
17408 defer fields_anon_decl.deinit();
17409
1741017391 const type_union_ty = t: {
1741117392 const type_union_ty_decl_index = (try sema.namespaceLookup(
1741217393 block,
......@@ -17444,23 +17425,20 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1744417425 // TODO: write something like getCoercedInts to avoid needing to dupe
1744517426 const name = try sema.arena.dupe(u8, ip.stringToSlice(union_obj.field_names.get(ip)[i]));
1744617427 const name_val = v: {
17447 var anon_decl = try block.startAnonDecl();
17448 defer anon_decl.deinit();
1744917428 const new_decl_ty = try mod.arrayType(.{
1745017429 .len = name.len,
1745117430 .child = .u8_type,
1745217431 });
17453 const new_decl = try anon_decl.finish(
17454 new_decl_ty,
17455 (try mod.intern(.{ .aggregate = .{
17456 .ty = new_decl_ty.toIntern(),
17457 .storage = .{ .bytes = name },
17458 } })).toValue(),
17459 .none, // default alignment
17460 );
17432 const new_decl_val = try mod.intern(.{ .aggregate = .{
17433 .ty = new_decl_ty.toIntern(),
17434 .storage = .{ .bytes = name },
17435 } });
1746117436 break :v try mod.intern(.{ .ptr = .{
1746217437 .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 } },
1746417442 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),
1746517443 } });
1746617444 };
......@@ -17490,23 +17468,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1749017468 .len = union_field_vals.len,
1749117469 .child = union_field_ty.toIntern(),
1749217470 });
17493 const new_decl = try fields_anon_decl.finish(
17494 array_fields_ty,
17495 (try mod.intern(.{ .aggregate = .{
17496 .ty = array_fields_ty.toIntern(),
17497 .storage = .{ .elems = union_field_vals },
17498 } })).toValue(),
17499 .none, // default alignment
17500 );
17471 const new_decl_val = try mod.intern(.{ .aggregate = .{
17472 .ty = array_fields_ty.toIntern(),
17473 .storage = .{ .elems = union_field_vals },
17474 } });
17475 const ptr_ty = (try sema.ptrType(.{
17476 .child = union_field_ty.toIntern(),
17477 .flags = .{
17478 .size = .Slice,
17479 .is_const = true,
17480 },
17481 })).toIntern();
1750117482 break :v try mod.intern(.{ .ptr = .{
17502 .ty = (try sema.ptrType(.{
17503 .child = union_field_ty.toIntern(),
17504 .flags = .{
17505 .size = .Slice,
17506 .is_const = true,
17507 },
17508 })).toIntern(),
17509 .addr = .{ .decl = new_decl },
17483 .ty = ptr_ty,
17484 .addr = .{ .anon_decl = .{
17485 .orig_ty = ptr_ty,
17486 .val = new_decl_val,
17487 } },
1751017488 .len = (try mod.intValue(Type.usize, union_field_vals.len)).toIntern(),
1751117489 } });
1751217490 };
......@@ -17552,11 +17530,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1755217530 } })));
1755317531 },
1755417532 .Struct => {
17555 // TODO: look into memoizing this result.
17556
17557 var fields_anon_decl = try block.startAnonDecl();
17558 defer fields_anon_decl.deinit();
17559
1756017533 const type_struct_ty = t: {
1756117534 const type_struct_ty_decl_index = (try sema.namespaceLookup(
1756217535 block,
......@@ -17596,8 +17569,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1759617569 const field_ty = anon_struct_type.types.get(ip)[i];
1759717570 const field_val = anon_struct_type.values.get(ip)[i];
1759817571 const name_val = v: {
17599 var anon_decl = try block.startAnonDecl();
17600 defer anon_decl.deinit();
1760117572 // TODO: write something like getCoercedInts to avoid needing to dupe
1760217573 const bytes = if (tuple.names.len != 0)
1760317574 // https://github.com/ziglang/zig/issues/15709
......@@ -17608,17 +17579,16 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1760817579 .len = bytes.len,
1760917580 .child = .u8_type,
1761017581 });
17611 const new_decl = try anon_decl.finish(
17612 new_decl_ty,
17613 (try mod.intern(.{ .aggregate = .{
17614 .ty = new_decl_ty.toIntern(),
17615 .storage = .{ .bytes = bytes },
17616 } })).toValue(),
17617 .none, // default alignment
17618 );
17582 const new_decl_val = try mod.intern(.{ .aggregate = .{
17583 .ty = new_decl_ty.toIntern(),
17584 .storage = .{ .bytes = bytes },
17585 } });
1761917586 break :v try mod.intern(.{ .ptr = .{
1762017587 .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 } },
1762217592 .len = (try mod.intValue(Type.usize, bytes.len)).toIntern(),
1762317593 } });
1762417594 };
......@@ -17627,7 +17597,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1762717597
1762817598 const is_comptime = field_val != .none;
1762917599 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);
1763117601 const struct_field_fields = .{
1763217602 // name: []const u8,
1763317603 name_val,
......@@ -17662,29 +17632,26 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1766217632 const field_init = struct_type.fieldInit(ip, i);
1766317633 const field_is_comptime = struct_type.fieldIsComptime(ip, i);
1766417634 const name_val = v: {
17665 var anon_decl = try block.startAnonDecl();
17666 defer anon_decl.deinit();
1766717635 const new_decl_ty = try mod.arrayType(.{
1766817636 .len = name.len,
1766917637 .child = .u8_type,
1767017638 });
17671 const new_decl = try anon_decl.finish(
17672 new_decl_ty,
17673 (try mod.intern(.{ .aggregate = .{
17674 .ty = new_decl_ty.toIntern(),
17675 .storage = .{ .bytes = name },
17676 } })).toValue(),
17677 .none, // default alignment
17678 );
17639 const new_decl_val = try mod.intern(.{ .aggregate = .{
17640 .ty = new_decl_ty.toIntern(),
17641 .storage = .{ .bytes = name },
17642 } });
1767917643 break :v try mod.intern(.{ .ptr = .{
1768017644 .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 } },
1768217649 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),
1768317650 } });
1768417651 };
1768517652
1768617653 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);
1768817655 const alignment = switch (struct_type.layout) {
1768917656 .Packed => .none,
1769017657 else => try sema.structFieldAlignment(
......@@ -17718,23 +17685,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1771817685 .len = struct_field_vals.len,
1771917686 .child = struct_field_ty.toIntern(),
1772017687 });
17721 const new_decl = try fields_anon_decl.finish(
17722 array_fields_ty,
17723 (try mod.intern(.{ .aggregate = .{
17724 .ty = array_fields_ty.toIntern(),
17725 .storage = .{ .elems = struct_field_vals },
17726 } })).toValue(),
17727 .none, // default alignment
17728 );
17688 const new_decl_val = try mod.intern(.{ .aggregate = .{
17689 .ty = array_fields_ty.toIntern(),
17690 .storage = .{ .elems = struct_field_vals },
17691 } });
17692 const ptr_ty = (try sema.ptrType(.{
17693 .child = struct_field_ty.toIntern(),
17694 .flags = .{
17695 .size = .Slice,
17696 .is_const = true,
17697 },
17698 })).toIntern();
1772917699 break :v try mod.intern(.{ .ptr = .{
17730 .ty = (try sema.ptrType(.{
17731 .child = struct_field_ty.toIntern(),
17732 .flags = .{
17733 .size = .Slice,
17734 .is_const = true,
17735 },
17736 })).toIntern(),
17737 .addr = .{ .decl = new_decl },
17700 .ty = ptr_ty,
17701 .addr = .{ .anon_decl = .{
17702 .orig_ty = ptr_ty,
17703 .val = new_decl_val,
17704 } },
1773817705 .len = (try mod.intValue(Type.usize, struct_field_vals.len)).toIntern(),
1773917706 } });
1774017707 };
......@@ -17786,8 +17753,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1778617753 } })));
1778717754 },
1778817755 .Opaque => {
17789 // TODO: look into memoizing this result.
17790
1779117756 const type_opaque_ty = t: {
1779217757 const type_opaque_ty_decl_index = (try sema.namespaceLookup(
1779317758 block,
......@@ -17832,9 +17797,6 @@ fn typeInfoDecls(
1783217797 const mod = sema.mod;
1783317798 const gpa = sema.gpa;
1783417799
17835 var decls_anon_decl = try block.startAnonDecl();
17836 defer decls_anon_decl.deinit();
17837
1783817800 const declaration_ty = t: {
1783917801 const declaration_ty_decl_index = (try sema.namespaceLookup(
1784017802 block,
......@@ -17864,23 +17826,23 @@ fn typeInfoDecls(
1786417826 .len = decl_vals.items.len,
1786517827 .child = declaration_ty.toIntern(),
1786617828 });
17867 const new_decl = try decls_anon_decl.finish(
17868 array_decl_ty,
17869 (try mod.intern(.{ .aggregate = .{
17870 .ty = array_decl_ty.toIntern(),
17871 .storage = .{ .elems = decl_vals.items },
17872 } })).toValue(),
17873 .none, // default alignment
17874 );
17829 const new_decl_val = try mod.intern(.{ .aggregate = .{
17830 .ty = array_decl_ty.toIntern(),
17831 .storage = .{ .elems = decl_vals.items },
17832 } });
17833 const ptr_ty = (try sema.ptrType(.{
17834 .child = declaration_ty.toIntern(),
17835 .flags = .{
17836 .size = .Slice,
17837 .is_const = true,
17838 },
17839 })).toIntern();
1787517840 return try mod.intern(.{ .ptr = .{
17876 .ty = (try sema.ptrType(.{
17877 .child = declaration_ty.toIntern(),
17878 .flags = .{
17879 .size = .Slice,
17880 .is_const = true,
17881 },
17882 })).toIntern(),
17883 .addr = .{ .decl = new_decl },
17841 .ty = ptr_ty,
17842 .addr = .{ .anon_decl = .{
17843 .orig_ty = ptr_ty,
17844 .val = new_decl_val,
17845 } },
1788417846 .len = (try mod.intValue(Type.usize, decl_vals.items.len)).toIntern(),
1788517847 } });
1788617848}
......@@ -17909,25 +17871,22 @@ fn typeInfoNamespaceDecls(
1790917871 }
1791017872 if (decl.kind != .named or !decl.is_pub) continue;
1791117873 const name_val = v: {
17912 var anon_decl = try block.startAnonDecl();
17913 defer anon_decl.deinit();
1791417874 // TODO: write something like getCoercedInts to avoid needing to dupe
1791517875 const name = try sema.arena.dupe(u8, ip.stringToSlice(decl.name));
1791617876 const new_decl_ty = try mod.arrayType(.{
1791717877 .len = name.len,
1791817878 .child = .u8_type,
1791917879 });
17920 const new_decl = try anon_decl.finish(
17921 new_decl_ty,
17922 (try mod.intern(.{ .aggregate = .{
17923 .ty = new_decl_ty.toIntern(),
17924 .storage = .{ .bytes = name },
17925 } })).toValue(),
17926 .none, // default alignment
17927 );
17880 const new_decl_val = try mod.intern(.{ .aggregate = .{
17881 .ty = new_decl_ty.toIntern(),
17882 .storage = .{ .bytes = name },
17883 } });
1792817884 break :v try mod.intern(.{ .ptr = .{
1792917885 .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 } },
1793117890 .len = (try mod.intValue(Type.usize, name.len)).toIntern(),
1793217891 } });
1793317892 };
......@@ -19072,10 +19031,7 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is
1907219031
1907319032 if (is_byref) {
1907419033 const init_val = (try sema.resolveValue(init_ref)).?;
19075 var anon_decl = try block.startAnonDecl();
19076 defer anon_decl.deinit();
19077 const decl = try anon_decl.finish(init_ty, init_val, .none);
19078 return sema.analyzeDeclRef(decl);
19034 return anonDeclRef(sema, init_val.toIntern());
1907919035 } else {
1908019036 return init_ref;
1908119037 }
......@@ -19298,7 +19254,7 @@ fn zirStructInit(
1929819254 } })).toValue();
1929919255 const final_val_inst = try sema.coerce(block, result_ty, Air.internedToRef(struct_val.toIntern()), src);
1930019256 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);
1930219258 }
1930319259
1930419260 if (try sema.typeRequiresComptime(resolved_ty)) {
......@@ -19458,7 +19414,7 @@ fn finishStructInit(
1945819414 } });
1945919415 const final_val_inst = try sema.coerce(block, result_ty, Air.internedToRef(struct_val), init_src);
1946019416 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);
1946219418 };
1946319419
1946419420 if (try sema.typeRequiresComptime(struct_ty)) {
......@@ -19611,7 +19567,7 @@ fn structInitAnon(
1961119567 .ty = tuple_ty,
1961219568 .storage = .{ .elems = values },
1961319569 } });
19614 return sema.addConstantMaybeRef(block, tuple_ty.toType(), tuple_val.toValue(), is_ref);
19570 return sema.addConstantMaybeRef(tuple_val, is_ref);
1961519571 };
1961619572
1961719573 sema.requireRuntimeBlock(block, .unneeded, null) catch |err| switch (err) {
......@@ -19777,7 +19733,8 @@ fn zirArrayInit(
1977719733 .storage = .{ .elems = elem_vals },
1977819734 } });
1977919735 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);
1978119738 };
1978219739
1978319740 sema.requireRuntimeBlock(block, .unneeded, null) catch |err| switch (err) {
......@@ -19896,7 +19853,7 @@ fn arrayInitAnon(
1989619853 .ty = tuple_ty,
1989719854 .storage = .{ .elems = values },
1989819855 } });
19899 return sema.addConstantMaybeRef(block, tuple_ty.toType(), tuple_val.toValue(), is_ref);
19856 return sema.addConstantMaybeRef(tuple_val, is_ref);
1990019857 };
1990119858
1990219859 try sema.requireRuntimeBlock(block, src, runtime_src);
......@@ -19931,23 +19888,8 @@ fn arrayInitAnon(
1993119888 return block.addAggregateInit(tuple_ty.toType(), element_refs);
1993219889}
1993319890
19934fn addConstantMaybeRef(
19935 sema: *Sema,
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);
19891fn addConstantMaybeRef(sema: *Sema, val: InternPool.Index, is_ref: bool) !Air.Inst.Ref {
19892 return if (is_ref) anonDeclRef(sema, val) else Air.internedToRef(val);
1995119893}
1995219894
1995319895fn 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
2142921371 const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
2143021372 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
2143521374 var bytes = std.ArrayList(u8).init(sema.arena);
21436 defer bytes.deinit();
2143721375 try ty.print(bytes.writer(), mod);
21438
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);
21376 return addStrLitNoAlias(sema, bytes.items);
2145421377}
2145521378
2145621379fn zirFrameType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -26333,13 +26256,8 @@ fn fieldPtr(
2633326256 switch (inner_ty.zigTypeTag(mod)) {
2633426257 .Array => {
2633526258 if (ip.stringEqlSlice(field_name, "len")) {
26336 var anon_decl = try block.startAnonDecl();
26337 defer anon_decl.deinit();
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 ));
26259 const int_val = try mod.intValue(Type.usize, inner_ty.arrayLen(mod));
26260 return anonDeclRef(sema, int_val.toIntern());
2634326261 } else {
2634426262 return sema.fail(
2634526263 block,
......@@ -26448,20 +26366,14 @@ fn fieldPtr(
2644826366 else => unreachable,
2644926367 }
2645026368
26451 var anon_decl = try block.startAnonDecl();
26452 defer anon_decl.deinit();
2645326369 const error_set_type = if (!child_type.isAnyError(mod))
2645426370 child_type
2645526371 else
2645626372 try mod.singleErrorSetType(field_name);
26457 return sema.analyzeDeclRef(try anon_decl.finish(
26458 error_set_type,
26459 (try mod.intern(.{ .err = .{
26460 .ty = error_set_type.toIntern(),
26461 .name = field_name,
26462 } })).toValue(),
26463 .none, // default alignment
26464 ));
26373 return anonDeclRef(sema, try mod.intern(.{ .err = .{
26374 .ty = error_set_type.toIntern(),
26375 .name = field_name,
26376 } }));
2646526377 },
2646626378 .Union => {
2646726379 if (child_type.getNamespaceIndex(mod).unwrap()) |namespace| {
......@@ -26473,13 +26385,8 @@ fn fieldPtr(
2647326385 if (child_type.unionTagType(mod)) |enum_ty| {
2647426386 if (enum_ty.enumFieldIndex(field_name, mod)) |field_index| {
2647526387 const field_index_u32: u32 = @intCast(field_index);
26476 var anon_decl = try block.startAnonDecl();
26477 defer anon_decl.deinit();
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 ));
26388 const idx_val = try mod.enumValueFieldIndex(enum_ty, field_index_u32);
26389 return anonDeclRef(sema, idx_val.toIntern());
2648326390 }
2648426391 }
2648526392 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
......@@ -26494,13 +26401,8 @@ fn fieldPtr(
2649426401 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
2649526402 };
2649626403 const field_index_u32: u32 = @intCast(field_index);
26497 var anon_decl = try block.startAnonDecl();
26498 defer anon_decl.deinit();
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 ));
26404 const idx_val = try mod.enumValueFieldIndex(child_type, field_index_u32);
26405 return anonDeclRef(sema, idx_val.toIntern());
2650426406 },
2650526407 .Struct, .Opaque => {
2650626408 if (child_type.getNamespaceIndex(mod).unwrap()) |namespace| {
......@@ -31669,31 +31571,13 @@ fn ensureFuncBodyAnalyzed(sema: *Sema, func: InternPool.Index) CompileError!void
3166931571 };
3167031572}
3167131573
31672fn refValue(sema: *Sema, block: *Block, ty: Type, 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 {
31574fn optRefValue(sema: *Sema, opt_val: ?Value) !Value {
3169131575 const mod = sema.mod;
3169231576 const ptr_anyopaque_ty = try mod.singleConstPtrType(Type.anyopaque);
3169331577 return (try mod.intern(.{ .opt = .{
3169431578 .ty = (try mod.optionalType(ptr_anyopaque_ty.toIntern())).toIntern(),
3169531579 .val = if (opt_val) |val| (try mod.getCoerced(
31696 try sema.refValue(block, ty, val),
31580 (try sema.refValue(val.toIntern())).toValue(),
3169731581 ptr_anyopaque_ty,
3169831582 )).toIntern() else .none,
3169931583 } })).toValue();
......@@ -31755,15 +31639,8 @@ fn analyzeRef(
3175531639 switch (mod.intern_pool.indexToKey(val.toIntern())) {
3175631640 .extern_func => |extern_func| return sema.analyzeDeclRef(extern_func.decl),
3175731641 .func => |func| return sema.analyzeDeclRef(func.owner_decl),
31758 else => {},
31642 else => return anonDeclRef(sema, val.toIntern()),
3175931643 }
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 ));
3176731644 }
3176831645
3176931646 try sema.requireRuntimeBlock(block, src, null);
......@@ -36848,7 +36725,7 @@ fn analyzeComptimeAlloc(
3684836725 },
3684936726 });
3685036727
36851 var anon_decl = try block.startAnonDecl();
36728 var anon_decl = try block.startAnonDecl(); // TODO: comptime value mutation without Decl
3685236729 defer anon_decl.deinit();
3685336730
3685436731 const decl_index = try anon_decl.finish(
src/codegen/c.zig+64-58
......@@ -522,7 +522,7 @@ pub const Object = struct {
522522pub const DeclGen = struct {
523523 gpa: mem.Allocator,
524524 module: *Module,
525 decl_index: Decl.OptionalIndex,
525 pass: Pass,
526526 is_naked_fn: bool,
527527 /// This is a borrowed reference from `link.C`.
528528 fwd_decl: std.ArrayList(u8),
......@@ -533,10 +533,16 @@ pub const DeclGen = struct {
533533 anon_decl_deps: std.AutoArrayHashMapUnmanaged(InternPool.Index, C.DeclBlock),
534534 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
536542 fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {
537543 @setCold(true);
538544 const mod = dg.module;
539 const decl_index = dg.decl_index.unwrap().?;
545 const decl_index = dg.pass.decl;
540546 const decl = mod.declPtr(decl_index);
541547 const src = LazySrcLoc.nodeOffset(0);
542548 const src_loc = src.toSrcLoc(decl, mod);
......@@ -1284,11 +1290,14 @@ pub const DeclGen = struct {
12841290 var index: usize = 0;
12851291 while (index < ai.len) : (index += 1) {
12861292 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));
12881297 try literal.writeChar(elem_val_u8);
12891298 }
12901299 if (ai.sentinel) |s| {
1291 const s_u8 = @as(u8, @intCast(s.toUnsignedInt(mod)));
1300 const s_u8: u8 = @intCast(s.toUnsignedInt(mod));
12921301 if (s_u8 != 0) try literal.writeChar(s_u8);
12931302 }
12941303 try literal.end();
......@@ -1298,7 +1307,10 @@ pub const DeclGen = struct {
12981307 while (index < ai.len) : (index += 1) {
12991308 if (index != 0) try writer.writeByte(',');
13001309 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));
13021314 try writer.print("'\\x{x}'", .{elem_val_u8});
13031315 }
13041316 if (ai.sentinel) |s| {
......@@ -1566,18 +1578,11 @@ pub const DeclGen = struct {
15661578 else => unreachable,
15671579 }
15681580 }
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 ");
15701583 if (fn_info.return_type == .noreturn_type) try w.writeAll("zig_noreturn ");
15711584
1572 const trailing = try renderTypePrefix(
1573 dg.decl_index,
1574 store.*,
1575 mod,
1576 w,
1577 fn_cty_idx,
1578 .suffix,
1579 .{},
1580 );
1585 const trailing = try renderTypePrefix(dg.pass, store.*, mod, w, fn_cty_idx, .suffix, .{});
15811586 try w.print("{}", .{trailing});
15821587
15831588 if (toCallingConvention(fn_info.cc)) |call_conv| {
......@@ -1597,7 +1602,7 @@ pub const DeclGen = struct {
15971602 }
15981603
15991604 try renderTypeSuffix(
1600 dg.decl_index,
1605 dg.pass,
16011606 store.*,
16021607 mod,
16031608 w,
......@@ -1652,8 +1657,8 @@ pub const DeclGen = struct {
16521657 fn renderCType(dg: *DeclGen, w: anytype, idx: CType.Index) error{ OutOfMemory, AnalysisFail }!void {
16531658 const store = &dg.ctypes.set;
16541659 const mod = dg.module;
1655 _ = try renderTypePrefix(dg.decl_index, store.*, mod, w, idx, .suffix, .{});
1656 try renderTypeSuffix(dg.decl_index, store.*, mod, w, idx, .suffix, .{});
1660 _ = try renderTypePrefix(dg.pass, store.*, mod, w, idx, .suffix, .{});
1661 try renderTypeSuffix(dg.pass, store.*, mod, w, idx, .suffix, .{});
16571662 }
16581663
16591664 const IntCastContext = union(enum) {
......@@ -1799,11 +1804,10 @@ pub const DeclGen = struct {
17991804 .gt => try w.print("zig_align({}) ", .{alignas.toByteUnits()}),
18001805 }
18011806
1802 const trailing =
1803 try renderTypePrefix(dg.decl_index, store.*, mod, w, cty_idx, .suffix, qualifiers);
1807 const trailing = try renderTypePrefix(dg.pass, store.*, mod, w, cty_idx, .suffix, qualifiers);
18041808 try w.print("{}", .{trailing});
18051809 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, .{});
18071811 }
18081812
18091813 fn declIsGlobal(dg: *DeclGen, tv: TypedValue) bool {
......@@ -2070,7 +2074,7 @@ fn renderTypeName(
20702074 }
20712075}
20722076fn renderTypePrefix(
2073 decl: Decl.OptionalIndex,
2077 pass: DeclGen.Pass,
20742078 store: CType.Store.Set,
20752079 mod: *Module,
20762080 w: anytype,
......@@ -2128,7 +2132,7 @@ fn renderTypePrefix(
21282132 => |tag| {
21292133 const child_idx = cty.cast(CType.Payload.Child).?.data;
21302134 const child_trailing = try renderTypePrefix(
2131 decl,
2135 pass,
21322136 store,
21332137 mod,
21342138 w,
......@@ -2152,15 +2156,8 @@ fn renderTypePrefix(
21522156 .vector,
21532157 => {
21542158 const child_idx = cty.cast(CType.Payload.Sequence).?.data.elem_type;
2155 const child_trailing = try renderTypePrefix(
2156 decl,
2157 store,
2158 mod,
2159 w,
2160 child_idx,
2161 .suffix,
2162 qualifiers,
2163 );
2159 const child_trailing =
2160 try renderTypePrefix(pass, store, mod, w, child_idx, .suffix, qualifiers);
21642161 switch (parent_fix) {
21652162 .prefix => {
21662163 try w.print("{}(", .{child_trailing});
......@@ -2172,10 +2169,11 @@ fn renderTypePrefix(
21722169
21732170 .fwd_anon_struct,
21742171 .fwd_anon_union,
2175 => if (decl.unwrap()) |decl_index|
2176 try w.print("anon__{d}_{d}", .{ @intFromEnum(decl_index), idx })
2177 else
2178 try renderTypeName(mod, w, idx, cty, ""),
2172 => switch (pass) {
2173 .decl => |decl_index| try w.print("decl__{d}_{d}", .{ @intFromEnum(decl_index), idx }),
2174 .anon => |anon_decl| try w.print("anon__{d}_{d}", .{ @intFromEnum(anon_decl), idx }),
2175 .flush => try renderTypeName(mod, w, idx, cty, ""),
2176 },
21792177
21802178 .fwd_struct,
21812179 .fwd_union,
......@@ -2201,7 +2199,7 @@ fn renderTypePrefix(
22012199 .packed_struct,
22022200 .packed_union,
22032201 => return renderTypePrefix(
2204 decl,
2202 pass,
22052203 store,
22062204 mod,
22072205 w,
......@@ -2214,7 +2212,7 @@ fn renderTypePrefix(
22142212 .varargs_function,
22152213 => {
22162214 const child_trailing = try renderTypePrefix(
2217 decl,
2215 pass,
22182216 store,
22192217 mod,
22202218 w,
......@@ -2241,7 +2239,7 @@ fn renderTypePrefix(
22412239 return trailing;
22422240}
22432241fn renderTypeSuffix(
2244 decl: Decl.OptionalIndex,
2242 pass: DeclGen.Pass,
22452243 store: CType.Store.Set,
22462244 mod: *Module,
22472245 w: anytype,
......@@ -2295,7 +2293,7 @@ fn renderTypeSuffix(
22952293 .pointer_volatile,
22962294 .pointer_const_volatile,
22972295 => try renderTypeSuffix(
2298 decl,
2296 pass,
22992297 store,
23002298 mod,
23012299 w,
......@@ -2314,7 +2312,7 @@ fn renderTypeSuffix(
23142312
23152313 try w.print("[{}]", .{cty.cast(CType.Payload.Sequence).?.data.len});
23162314 try renderTypeSuffix(
2317 decl,
2315 pass,
23182316 store,
23192317 mod,
23202318 w,
......@@ -2356,9 +2354,9 @@ fn renderTypeSuffix(
23562354 if (need_comma) try w.writeAll(", ");
23572355 need_comma = true;
23582356 const trailing =
2359 try renderTypePrefix(decl, store, mod, w, param_type, .suffix, qualifiers);
2357 try renderTypePrefix(pass, store, mod, w, param_type, .suffix, qualifiers);
23602358 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, .{});
23622360 }
23632361 switch (tag) {
23642362 .function => {},
......@@ -2372,7 +2370,7 @@ fn renderTypeSuffix(
23722370 if (!need_comma) try w.writeAll("void");
23732371 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, .{});
23762374 },
23772375 }
23782376}
......@@ -2392,9 +2390,9 @@ fn renderAggregateFields(
23922390 .eq => {},
23932391 .gt => try writer.print("zig_align({}) ", .{field.alignas.toByteUnits()}),
23942392 }
2395 const trailing = try renderTypePrefix(.none, store, mod, writer, field.type, .suffix, .{});
2393 const trailing = try renderTypePrefix(.flush, store, mod, writer, field.type, .suffix, .{});
23962394 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, .{});
23982396 try writer.writeAll(";\n");
23992397 }
24002398 try writer.writeByteNTimes(' ', indent);
......@@ -2406,18 +2404,18 @@ pub fn genTypeDecl(
24062404 writer: anytype,
24072405 global_store: CType.Store.Set,
24082406 global_idx: CType.Index,
2409 decl: Decl.OptionalIndex,
2407 pass: DeclGen.Pass,
24102408 decl_store: CType.Store.Set,
24112409 decl_idx: CType.Index,
24122410 found_existing: bool,
24132411) !void {
24142412 const global_cty = global_store.indexToCType(global_idx);
24152413 switch (global_cty.tag()) {
2416 .fwd_anon_struct => if (decl != .none) {
2414 .fwd_anon_struct => if (pass != .flush) {
24172415 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, .{});
24192417 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, .{});
24212419 try writer.writeAll(";\n");
24222420 },
24232421
......@@ -2435,7 +2433,15 @@ pub fn genTypeDecl(
24352433 .fwd_union,
24362434 => {
24372435 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 );
24392445 try writer.writeAll("; // ");
24402446 try mod.declPtr(owner_decl).renderFullyQualifiedName(mod, writer);
24412447 try writer.writeByte('\n');
......@@ -2552,7 +2558,7 @@ fn genExports(o: *Object) !void {
25522558
25532559 const mod = o.dg.module;
25542560 const ip = &mod.intern_pool;
2555 const decl_index = o.dg.decl_index.unwrap().?;
2561 const decl_index = o.dg.pass.decl;
25562562 const decl = mod.declPtr(decl_index);
25572563 const tv: TypedValue = .{ .ty = decl.ty, .val = (try decl.internValue(mod)).toValue() };
25582564 const fwd = o.dg.fwd_decl.writer();
......@@ -2692,7 +2698,7 @@ pub fn genFunc(f: *Function) !void {
26922698 const o = &f.object;
26932699 const mod = o.dg.module;
26942700 const gpa = o.dg.gpa;
2695 const decl_index = o.dg.decl_index.unwrap().?;
2701 const decl_index = o.dg.pass.decl;
26962702 const decl = mod.declPtr(decl_index);
26972703 const tv: TypedValue = .{
26982704 .ty = decl.ty,
......@@ -2779,7 +2785,7 @@ pub fn genDecl(o: *Object) !void {
27792785 defer tracy.end();
27802786
27812787 const mod = o.dg.module;
2782 const decl_index = o.dg.decl_index.unwrap().?;
2788 const decl_index = o.dg.pass.decl;
27832789 const decl = mod.declPtr(decl_index);
27842790 const tv: TypedValue = .{ .ty = decl.ty, .val = (try decl.internValue(mod)).toValue() };
27852791
......@@ -2825,13 +2831,13 @@ pub fn genDeclValue(
28252831 alignment: Alignment,
28262832 link_section: InternPool.OptionalNullTerminatedString,
28272833) !void {
2834 const mod = o.dg.module;
28282835 const fwd_decl_writer = o.dg.fwd_decl.writer();
28292836
28302837 try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static ");
28312838 try o.dg.renderTypeAndName(fwd_decl_writer, tv.ty, decl_c_value, Const, alignment, .complete);
28322839 try fwd_decl_writer.writeAll(";\n");
28332840
2834 const mod = o.dg.module;
28352841 const w = o.writer();
28362842 if (!is_global) try w.writeAll("static ");
28372843 if (mod.intern_pool.stringToSliceUnwrap(link_section)) |s|
......@@ -2848,7 +2854,7 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void {
28482854 defer tracy.end();
28492855
28502856 const mod = dg.module;
2851 const decl_index = dg.decl_index.unwrap().?;
2857 const decl_index = dg.pass.decl;
28522858 const decl = mod.declPtr(decl_index);
28532859 const tv: TypedValue = .{
28542860 .ty = decl.ty,
......@@ -2861,7 +2867,7 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void {
28612867 const is_global = dg.declIsGlobal(tv);
28622868 if (is_global) {
28632869 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 });
28652871 try dg.fwd_decl.appendSlice(";\n");
28662872 }
28672873 },
......@@ -7279,7 +7285,7 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
72797285fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue {
72807286 const mod = f.object.dg.module;
72817287 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;
72837289 const decl = mod.declPtr(decl_index);
72847290 const fn_cty = try f.typeToCType(decl.ty, .complete);
72857291 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(
158158 const decl_index = func.owner_decl;
159159 const decl = module.declPtr(decl_index);
160160 const gop = try self.decl_table.getOrPut(gpa, decl_index);
161 if (!gop.found_existing) {
162 gop.value_ptr.* = .{};
163 }
161 if (!gop.found_existing) gop.value_ptr.* = .{};
164162 const ctypes = &gop.value_ptr.ctypes;
165163 const lazy_fns = &gop.value_ptr.lazy_fns;
166164 const fwd_decl = &self.fwd_decl_buf;
......@@ -180,7 +178,7 @@ pub fn updateFunc(
180178 .gpa = gpa,
181179 .module = module,
182180 .error_msg = null,
183 .decl_index = decl_index.toOptional(),
181 .pass = .{ .decl = decl_index },
184182 .is_naked_fn = decl.ty.fnCallingConvention(module) == .Naked,
185183 .fwd_decl = fwd_decl.toManaged(gpa),
186184 .ctypes = ctypes.*,
......@@ -235,7 +233,7 @@ fn updateAnonDecl(self: *C, module: *Module, i: usize) !void {
235233 .gpa = gpa,
236234 .module = module,
237235 .error_msg = null,
238 .decl_index = .none,
236 .pass = .{ .anon = anon_decl },
239237 .is_naked_fn = false,
240238 .fwd_decl = fwd_decl.toManaged(gpa),
241239 .ctypes = .{},
......@@ -302,7 +300,7 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi
302300 .gpa = gpa,
303301 .module = module,
304302 .error_msg = null,
305 .decl_index = decl_index.toOptional(),
303 .pass = .{ .decl = decl_index },
306304 .is_naked_fn = false,
307305 .fwd_decl = fwd_decl.toManaged(gpa),
308306 .ctypes = ctypes.*,
......@@ -438,14 +436,14 @@ pub fn flushModule(self: *C, _: *Compilation, prog_node: *std.Progress.Node) !vo
438436 // We need to flush lazy ctypes after flushing all decls but before flushing any decl ctypes.
439437 // This ensures that every lazy CType.Index exactly matches the global CType.Index.
440438 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| {
444 try self.flushCTypes(&f, .none, decl_block.ctypes);
441 for (self.anon_decls.keys(), self.anon_decls.values()) |anon_decl, decl_block| {
442 try self.flushCTypes(&f, .{ .anon = anon_decl }, decl_block.ctypes);
445443 }
446444
447445 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);
449447 }
450448 }
451449
......@@ -516,7 +514,7 @@ const FlushDeclError = error{
516514fn flushCTypes(
517515 self: *C,
518516 f: *Flush,
519 decl_index: Module.Decl.OptionalIndex,
517 pass: codegen.DeclGen.Pass,
520518 decl_ctypes: codegen.CType.Store,
521519) FlushDeclError!void {
522520 const gpa = self.base.allocator;
......@@ -591,7 +589,7 @@ fn flushCTypes(
591589 writer,
592590 global_ctypes.set,
593591 global_idx,
594 decl_index,
592 pass,
595593 decl_ctypes.set,
596594 decl_idx,
597595 gop.found_existing,
......@@ -610,7 +608,7 @@ fn flushErrDecls(self: *C, ctypes: *codegen.CType.Store) FlushDeclError!void {
610608 .gpa = gpa,
611609 .module = self.base.options.module.?,
612610 .error_msg = null,
613 .decl_index = .none,
611 .pass = .flush,
614612 .is_naked_fn = false,
615613 .fwd_decl = fwd_decl.toManaged(gpa),
616614 .ctypes = ctypes.*,
......@@ -652,7 +650,7 @@ fn flushLazyFn(
652650 .gpa = gpa,
653651 .module = self.base.options.module.?,
654652 .error_msg = null,
655 .decl_index = .none,
653 .pass = .flush,
656654 .is_naked_fn = false,
657655 .fwd_decl = fwd_decl.toManaged(gpa),
658656 .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
17371737 return 0;
17381738}
17391739
1740pub fn lowerAnonDecl(self: *Coff, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !codegen.Result {
1741 // This is basically the same as lowerUnnamedConst.
1742 // example:
1743 // const ty = mod.intern_pool.typeOf(decl_val).toType();
1744 // const val = decl_val.toValue();
1745 // The symbol name can be something like `__anon_{d}` with `@intFromEnum(decl_val)`.
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 // ...
1740pub fn lowerAnonDecl(
1741 self: *Coff,
1742 decl_val: InternPool.Index,
1743 explicit_alignment: InternPool.Alignment,
1744 src_loc: Module.SrcLoc,
1745) !codegen.Result {
17501746 const gpa = self.base.allocator;
17511747 const mod = self.base.options.module.?;
17521748 const ty = mod.intern_pool.typeOf(decl_val).toType();
1753 const gop = try self.anon_decls.getOrPut(gpa, decl_val);
1754 const required_alignment = switch (decl_align) {
1749 const decl_alignment = switch (explicit_alignment) {
17551750 .none => ty.abiAlignment(mod),
1756 else => decl_align,
1751 else => explicit_alignment,
17571752 };
1758 if (!gop.found_existing or
1759 !required_alignment.check(self.getAtom(gop.value_ptr.*).getSymbol(self).value))
1760 {
1761 const val = decl_val.toValue();
1762 const tv = TypedValue{ .ty = ty, .val = val };
1763 const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)});
1764 defer gpa.free(name);
1765 const res = self.lowerConst(name, tv, required_alignment, self.rdata_section_index.?, src_loc) catch |err| switch (err) {
1766 else => {
1767 // TODO improve error message
1768 const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{
1769 @errorName(err),
1770 });
1771 return .{ .fail = em };
1772 },
1773 };
1774 const atom_index = switch (res) {
1775 .ok => |atom_index| atom_index,
1776 .fail => |em| return .{ .fail = em },
1777 };
1778 gop.value_ptr.* = atom_index;
1779 }
1753 if (self.anon_decls.get(decl_val)) |atom_index| {
1754 const existing_addr = self.getAtom(atom_index).getSymbol(self).value;
1755 if (decl_alignment.check(existing_addr))
1756 return .ok;
1757 }
1758
1759 const val = decl_val.toValue();
1760 const tv = TypedValue{ .ty = ty, .val = val };
1761 var name_buf: [32]u8 = undefined;
1762 const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{
1763 @intFromEnum(decl_val),
1764 }) catch unreachable;
1765 const res = self.lowerConst(
1766 name,
1767 tv,
1768 decl_alignment,
1769 self.rdata_section_index.?,
1770 src_loc,
1771 ) catch |err| switch (err) {
1772 error.OutOfMemory => return error.OutOfMemory,
1773 else => |e| return .{ .fail = try Module.ErrorMsg.create(
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);
17801785 return .ok;
17811786}
17821787
src/link/Elf.zig+40-35
......@@ -484,46 +484,51 @@ pub fn getDeclVAddr(self: *Elf, decl_index: Module.Decl.Index, reloc_info: link.
484484 return vaddr;
485485}
486486
487pub fn lowerAnonDecl(self: *Elf, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !codegen.Result {
488 // This is basically the same as lowerUnnamedConst.
489 // example:
490 // const ty = mod.intern_pool.typeOf(decl_val).toType();
491 // const val = decl_val.toValue();
492 // The symbol name can be something like `__anon_{d}` with `@intFromEnum(decl_val)`.
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 // ...
487pub fn lowerAnonDecl(
488 self: *Elf,
489 decl_val: InternPool.Index,
490 explicit_alignment: InternPool.Alignment,
491 src_loc: Module.SrcLoc,
492) !codegen.Result {
497493 const gpa = self.base.allocator;
498494 const mod = self.base.options.module.?;
499495 const ty = mod.intern_pool.typeOf(decl_val).toType();
500 const gop = try self.anon_decls.getOrPut(gpa, decl_val);
501 const required_alignment = switch (decl_align) {
496 const decl_alignment = switch (explicit_alignment) {
502497 .none => ty.abiAlignment(mod),
503 else => decl_align,
498 else => explicit_alignment,
504499 };
505 if (!gop.found_existing or
506 required_alignment.order(self.symbol(gop.value_ptr.*).atom(self).?.alignment).compare(.gt))
507 {
508 const val = decl_val.toValue();
509 const tv = TypedValue{ .ty = ty, .val = val };
510 const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)});
511 defer gpa.free(name);
512 const res = self.lowerConst(name, tv, required_alignment, self.zig_rodata_section_index.?, src_loc) catch |err| switch (err) {
513 else => {
514 // TODO improve error message
515 const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{
516 @errorName(err),
517 });
518 return .{ .fail = em };
519 },
520 };
521 const sym_index = switch (res) {
522 .ok => |sym_index| sym_index,
523 .fail => |em| return .{ .fail = em },
524 };
525 gop.value_ptr.* = sym_index;
526 }
500 if (self.anon_decls.get(decl_val)) |sym_index| {
501 const existing_alignment = self.symbol(sym_index).atom(self).?.alignment;
502 if (decl_alignment.order(existing_alignment).compare(.lte))
503 return .ok;
504 }
505
506 const val = decl_val.toValue();
507 const tv = TypedValue{ .ty = ty, .val = val };
508 var name_buf: [32]u8 = undefined;
509 const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{
510 @intFromEnum(decl_val),
511 }) catch unreachable;
512 const res = self.lowerConst(
513 name,
514 tv,
515 decl_alignment,
516 self.zig_rodata_section_index.?,
517 src_loc,
518 ) catch |err| switch (err) {
519 error.OutOfMemory => return error.OutOfMemory,
520 else => |e| return .{ .fail = try Module.ErrorMsg.create(
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);
527532 return .ok;
528533}
529534
src/link/MachO.zig+40-35
......@@ -2866,46 +2866,51 @@ pub fn getDeclVAddr(self: *MachO, decl_index: Module.Decl.Index, reloc_info: Fil
28662866 return 0;
28672867}
28682868
2869pub fn lowerAnonDecl(self: *MachO, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !codegen.Result {
2870 // This is basically the same as lowerUnnamedConst.
2871 // example:
2872 // const ty = mod.intern_pool.typeOf(decl_val).toType();
2873 // const val = decl_val.toValue();
2874 // The symbol name can be something like `__anon_{d}` with `@intFromEnum(decl_val)`.
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 // ...
2869pub fn lowerAnonDecl(
2870 self: *MachO,
2871 decl_val: InternPool.Index,
2872 explicit_alignment: InternPool.Alignment,
2873 src_loc: Module.SrcLoc,
2874) !codegen.Result {
28792875 const gpa = self.base.allocator;
28802876 const mod = self.base.options.module.?;
28812877 const ty = mod.intern_pool.typeOf(decl_val).toType();
2882 const gop = try self.anon_decls.getOrPut(gpa, decl_val);
2883 const required_alignment = switch (decl_align) {
2878 const decl_alignment = switch (explicit_alignment) {
28842879 .none => ty.abiAlignment(mod),
2885 else => decl_align,
2880 else => explicit_alignment,
28862881 };
2887 if (!gop.found_existing or
2888 !required_alignment.check(self.getAtom(gop.value_ptr.*).getSymbol(self).n_value))
2889 {
2890 const val = decl_val.toValue();
2891 const tv = TypedValue{ .ty = ty, .val = val };
2892 const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)});
2893 defer gpa.free(name);
2894 const res = self.lowerConst(name, tv, required_alignment, self.data_const_section_index.?, src_loc) catch |err| switch (err) {
2895 else => {
2896 // TODO improve error message
2897 const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{
2898 @errorName(err),
2899 });
2900 return .{ .fail = em };
2901 },
2902 };
2903 const atom_index = switch (res) {
2904 .ok => |atom_index| atom_index,
2905 .fail => |em| return .{ .fail = em },
2906 };
2907 gop.value_ptr.* = atom_index;
2908 }
2882 if (self.anon_decls.get(decl_val)) |atom_index| {
2883 const existing_addr = self.getAtom(atom_index).getSymbol(self).n_value;
2884 if (decl_alignment.check(existing_addr))
2885 return .ok;
2886 }
2887
2888 const val = decl_val.toValue();
2889 const tv = TypedValue{ .ty = ty, .val = val };
2890 var name_buf: [32]u8 = undefined;
2891 const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{
2892 @intFromEnum(decl_val),
2893 }) catch unreachable;
2894 const res = self.lowerConst(
2895 name,
2896 tv,
2897 decl_alignment,
2898 self.data_const_section_index.?,
2899 src_loc,
2900 ) catch |err| switch (err) {
2901 error.OutOfMemory => return error.OutOfMemory,
2902 else => |e| return .{ .fail = try Module.ErrorMsg.create(
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);
29092914 return .ok;
29102915}
29112916
src/link/Wasm.zig+15-8
......@@ -1702,27 +1702,34 @@ pub fn getDeclVAddr(
17021702 return target_symbol_index;
17031703}
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 {
17061711 const gop = try wasm.anon_decls.getOrPut(wasm.base.allocator, decl_val);
17071712 if (!gop.found_existing) {
17081713 const mod = wasm.base.options.module.?;
17091714 const ty = mod.intern_pool.typeOf(decl_val).toType();
17101715 const tv: TypedValue = .{ .ty = ty, .val = decl_val.toValue() };
1711 const name = try std.fmt.allocPrintZ(wasm.base.allocator, "__anon_{d}", .{@intFromEnum(decl_val)});
1712 defer wasm.base.allocator.free(name);
1716 var name_buf: [32]u8 = undefined;
1717 const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{
1718 @intFromEnum(decl_val),
1719 }) catch unreachable;
17131720
17141721 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,
17161723 .fail => |em| return .{ .fail = em },
17171724 }
17181725 }
17191726
1720 const atom = wasm.getAtomPtr(gop.value_ptr.*);
1727 const atom = wasm.getAtomPtr(wasm.anon_decls.values()[gop.index]);
17211728 atom.alignment = switch (atom.alignment) {
1722 .none => decl_align,
1723 else => switch (decl_align) {
1729 .none => explicit_alignment,
1730 else => switch (explicit_alignment) {
17241731 .none => atom.alignment,
1725 else => atom.alignment.maxStrict(decl_align),
1732 else => atom.alignment.maxStrict(explicit_alignment),
17261733 },
17271734 };
17281735 return .ok;