sema: fix ZIR→IP signedness inversion, resolve Signedness/AddressSpace types

ZIR uses the Zig Signedness enum convention (signed=0, unsigned=1) while
the InternPool uses the inverted convention (unsigned=0, signed=1). Fix
both places that read signedness from ZIR: resolveEnumDeclFromZir (for
explicit enum tag types) and zirIntType (for int_type instructions).

Add resolveBuiltinDeclTypes() to resolve BuiltinDecl types from
std.builtin in order, matching Sema.zig's analyzeMemoizedState. Currently
resolves Signedness and AddressSpace, creating IP entries $213-$251.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-26 05:21:49 +00:00
parent 2b10f3bee3
commit e95f46eeff

View File

@@ -2775,13 +2775,16 @@ static InternPoolIndex resolveEnumDeclFromZir(
if (tt_inst < zir->inst_len
&& zir->inst_tags[tt_inst] == ZIR_INST_INT_TYPE) {
uint16_t bits = zir->inst_datas[tt_inst].int_type.bit_count;
uint8_t signedness
// ZIR uses Zig Signedness enum: signed=0, unsigned=1.
// IP uses: unsigned=0, signed=1. Invert.
uint8_t zir_sign
= zir->inst_datas[tt_inst].int_type.signedness;
uint8_t ip_sign = (zir_sign == 0) ? 1 : 0;
InternPoolKey itk;
memset(&itk, 0, sizeof(itk));
itk.tag = IP_KEY_INT_TYPE;
itk.data.int_type.bits = bits;
itk.data.int_type.signedness = signedness;
itk.data.int_type.signedness = ip_sign;
int_tag_type = ipIntern(s_module_ip, itk);
}
}
@@ -3073,6 +3076,28 @@ static void internStringLiteral(const char* str) {
(void)ipIntern(s_module_ip, bytes2_key);
}
// --- resolveBuiltinDeclTypes ---
// Resolve BuiltinDecl types from std.builtin namespace.
// Ported from Sema.zig analyzeMemoizedState (main stage).
// This resolves types in BuiltinDecl order: Signedness, AddressSpace,
// CallingConvention, etc.
static void resolveBuiltinDeclTypes(uint32_t builtin_ns_idx) {
// BuiltinDecl types in order (main stage only).
// Each is looked up in std.builtin and resolved.
static const char* const builtin_type_names[] = {
"Signedness",
"AddressSpace",
};
uint32_t n_types
= sizeof(builtin_type_names) / sizeof(builtin_type_names[0]);
for (uint32_t i = 0; i < n_types; i++) {
uint32_t nav
= findNavInNamespace(builtin_ns_idx, builtin_type_names[i]);
if (nav != UINT32_MAX)
(void)ensureNavValUpToDate(nav);
}
}
// --- resolveStartComptimePreamble ---
// Create the IP entries that the Zig compiler generates when processing
// start.zig's comptime block. This block evaluates builtin.zig_backend
@@ -3194,6 +3219,12 @@ static void resolveStartComptimePreamble(void) {
// start.zig's else branch evaluates @hasDecl(root, "main") which
// triggers interning of the string literal "main".
internStringLiteral("main");
// --- $213+: BuiltinDecl type resolution ---
// The Zig compiler calls analyzeMemoizedState which resolves types
// from std.builtin in BuiltinDecl order. Port this by resolving each
// declaration via ensureNavValUpToDate.
resolveBuiltinDeclTypes(builtin_ns_idx);
}
// --- findDeclImportPathFromZir ---
@@ -9142,13 +9173,16 @@ static void zirUnreachable(Sema* sema, SemaBlock* block, uint32_t inst) {
// --- zirIntType ---
// Ported from src/Sema.zig zirIntType.
static AirInstRef zirIntType(Sema* sema, uint32_t inst) {
uint8_t signedness = sema->code.inst_datas[inst].int_type.signedness;
// ZIR uses Zig Signedness enum: signed=0, unsigned=1.
// IP uses: unsigned=0, signed=1. Invert.
uint8_t zir_sign = sema->code.inst_datas[inst].int_type.signedness;
uint8_t ip_sign = (zir_sign == 0) ? 1 : 0;
uint16_t bit_count = sema->code.inst_datas[inst].int_type.bit_count;
InternPoolKey key;
memset(&key, 0, sizeof(key));
key.tag = IP_KEY_INT_TYPE;
key.data.int_type.bits = bit_count;
key.data.int_type.signedness = signedness;
key.data.int_type.signedness = ip_sign;
return AIR_REF_FROM_IP(ipIntern(sema->ip, key));
}