sema: port struct_init_field_type, enum field lookup (num_passing=5)
Port upstream struct_init_field_type (zirStructInitFieldType → fieldType)
for resolving field types in struct/union init expressions like @Type(.{
.int = .{ .signedness = .unsigned, .bits = 32 } }).
- Add lookupStructFieldTypeFromZir: re-parses struct ZIR declarations to
find field types by name (handles nested types like Type.Int)
- Add union_fields table in Zcu for union field name/type lookup
- Add enum_fields table in Zcu for enum field name/tag value lookup
- Extend zirDeclLiteralComptime with enum field value resolution
(fieldVal → enumFieldIndex → enumValueFieldIndex)
- Fix build.zig: track header files as inputs for gcc/clang/tcc builds
so struct layout changes in .h files properly invalidate cached .o files
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1871,6 +1871,8 @@ fn addZig0CSources(
|
||||
});
|
||||
cc1.addArg("-c");
|
||||
cc1.addFileArg(b.path(b.fmt("stage0/{s}", .{cfile})));
|
||||
// Track headers as extra inputs so changes invalidate the cache.
|
||||
for (zig0_headers) |h| cc1.addFileInput(b.path(b.fmt("stage0/{s}", .{h})));
|
||||
cc1.addArg("-o");
|
||||
mod.addObjectFile(cc1.addOutputFileArg(b.fmt("{s}.o", .{cfile[0 .. cfile.len - 2]})));
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/// `num_passing` controls how many files are tested and pre-generated.
|
||||
/// Both build.zig and stages_test.zig import this file.
|
||||
/// To enable more tests: just increment `num_passing`.
|
||||
pub const num_passing: usize = 4;
|
||||
pub const num_passing: usize = 5;
|
||||
|
||||
pub const files = [_][]const u8{
|
||||
"stage0/sema_tests/empty.zig",
|
||||
|
||||
320
stage0/sema.c
320
stage0/sema.c
@@ -3672,14 +3672,32 @@ InternPoolIndex resolveEnumDeclFromZir(
|
||||
// 1. Resolve value ref → comptime_int IP index
|
||||
// 2. Coerce to tag type → int_small IP index
|
||||
// Order: comptime_int first (if new entry), then int_small.
|
||||
// Set up enum field tracking for zirDeclLiteralComptime.
|
||||
uint32_t ef_idx = sema->zcu->num_enum_fields;
|
||||
bool track_ef
|
||||
= ef_idx < ZCU_MAX_ENUM_TYPES && fields_len <= ZCU_MAX_ENUM_FIELDS;
|
||||
if (track_ef) {
|
||||
sema->zcu->enum_fields[ef_idx].enum_ip = enum_ip;
|
||||
sema->zcu->enum_fields[ef_idx].field_count = fields_len;
|
||||
}
|
||||
|
||||
uint64_t auto_val = 0;
|
||||
for (uint32_t fi = 0; fi < fields_len; fi++) {
|
||||
uint32_t bag_idx = fi / 32;
|
||||
uint32_t bit_idx = fi % 32;
|
||||
bool has_value = (zir->extra[bit_bags_start + bag_idx] >> bit_idx) & 1;
|
||||
|
||||
extra_index++; // skip field_name
|
||||
// Read field name for enum field tracking.
|
||||
uint32_t field_name_zir = zir->extra[extra_index];
|
||||
extra_index++;
|
||||
if (track_ef && fi < ZCU_MAX_ENUM_FIELDS) {
|
||||
const char* fname
|
||||
= (const char*)&zir->string_bytes[field_name_zir];
|
||||
sema->zcu->enum_fields[ef_idx].field_names[fi]
|
||||
= ipGetOrPutString(sema->ip, fname);
|
||||
}
|
||||
|
||||
InternPoolIndex tag_int_ip = IP_INDEX_NONE;
|
||||
if (has_value) {
|
||||
uint32_t val_ref = zir->extra[extra_index++];
|
||||
|
||||
@@ -3697,7 +3715,8 @@ InternPoolIndex resolveEnumDeclFromZir(
|
||||
|
||||
// Step 2: coerce to tag type.
|
||||
if (int_tag_type != IP_INDEX_NONE)
|
||||
(void)coerceIntToTagType(sema, comptime_ip, int_tag_type);
|
||||
tag_int_ip
|
||||
= coerceIntToTagType(sema, comptime_ip, int_tag_type);
|
||||
} else {
|
||||
// Auto-increment: intern as typed int directly.
|
||||
if (int_tag_type != IP_INDEX_NONE && auto_val > 0) {
|
||||
@@ -3718,14 +3737,21 @@ InternPoolIndex resolveEnumDeclFromZir(
|
||||
ct_ip = ipIntern(sema->ip, ct);
|
||||
}
|
||||
// Then coerce to tag type.
|
||||
(void)coerceIntToTagType(sema, ct_ip, int_tag_type);
|
||||
tag_int_ip = coerceIntToTagType(sema, ct_ip, int_tag_type);
|
||||
} else if (int_tag_type != IP_INDEX_NONE) {
|
||||
// Value 0: comptime_int(0) is pre-interned.
|
||||
(void)coerceIntToTagType(sema, IP_INDEX_ZERO, int_tag_type);
|
||||
tag_int_ip
|
||||
= coerceIntToTagType(sema, IP_INDEX_ZERO, int_tag_type);
|
||||
}
|
||||
auto_val++;
|
||||
}
|
||||
|
||||
// Record the coerced tag int value for enum field lookup.
|
||||
if (track_ef && fi < ZCU_MAX_ENUM_FIELDS)
|
||||
sema->zcu->enum_fields[ef_idx].field_tag_ints[fi] = tag_int_ip;
|
||||
}
|
||||
if (track_ef)
|
||||
sema->zcu->num_enum_fields++;
|
||||
|
||||
// Set the Nav's resolved type and create ptr_nav.
|
||||
if (nav_idx != UINT32_MAX) {
|
||||
@@ -4377,7 +4403,161 @@ static void resolveStructFieldTypesC(Sema* sema, const Zir* zir,
|
||||
}
|
||||
}
|
||||
|
||||
// --- findStructFieldIndexFromZir ---
|
||||
// --- lookupStructFieldTypeFromZir ---
|
||||
// Find a struct field by name and return its resolved IP type.
|
||||
// Re-parses the struct's ZIR declaration to find field names and types.
|
||||
// Returns IP_INDEX_NONE if the struct or field is not found.
|
||||
// Ported from Sema.zig fieldType → loadStructType → nameIndex.
|
||||
static InternPoolIndex lookupStructFieldTypeFromZir(
|
||||
Sema* sema, InternPoolIndex struct_ip, const char* field_name) {
|
||||
// Find the nav that owns this struct type.
|
||||
uint32_t nav_idx = findNavForIPIndex(sema, struct_ip);
|
||||
if (nav_idx == UINT32_MAX)
|
||||
return IP_INDEX_NONE;
|
||||
const Nav* nav = ipGetNav(sema->ip, nav_idx);
|
||||
|
||||
// Find the struct's ZIR.
|
||||
uint32_t ns_idx = nav->namespace_idx;
|
||||
if (ns_idx == UINT32_MAX || ns_idx >= sema->zcu->num_namespaces)
|
||||
return IP_INDEX_NONE;
|
||||
uint32_t file_idx = sema->zcu->namespaces[ns_idx].file_idx;
|
||||
if (file_idx >= sema->zcu->num_files
|
||||
|| !sema->zcu->files[file_idx].has_zir)
|
||||
return IP_INDEX_NONE;
|
||||
const Zir* zir = &sema->zcu->files[file_idx].zir;
|
||||
|
||||
// Find the struct_decl instruction.
|
||||
const uint32_t* vbody = NULL;
|
||||
uint32_t vbody_len = 0;
|
||||
getValueBodyFromZir(zir, nav->zir_index, &vbody, &vbody_len);
|
||||
if (!vbody)
|
||||
return IP_INDEX_NONE;
|
||||
|
||||
uint32_t struct_inst = UINT32_MAX;
|
||||
for (uint32_t i = 0; i < vbody_len; i++) {
|
||||
uint32_t inst = vbody[i];
|
||||
if (inst < zir->inst_len && zir->inst_tags[inst] == ZIR_INST_EXTENDED
|
||||
&& zir->inst_datas[inst].extended.opcode == ZIR_EXT_STRUCT_DECL) {
|
||||
struct_inst = inst;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (struct_inst == UINT32_MAX)
|
||||
return IP_INDEX_NONE;
|
||||
|
||||
// Parse struct_decl to find field entries.
|
||||
uint16_t ssmall = zir->inst_datas[struct_inst].extended.small;
|
||||
uint32_t soperand = zir->inst_datas[struct_inst].extended.operand;
|
||||
uint32_t sei = soperand + 6; // skip header
|
||||
|
||||
bool s_has_captures = (ssmall & (1 << 0)) != 0;
|
||||
bool s_has_fields = (ssmall & (1 << 1)) != 0;
|
||||
bool s_has_decls = (ssmall & (1 << 2)) != 0;
|
||||
bool s_has_backing_int = (ssmall & (1 << 3)) != 0;
|
||||
|
||||
uint32_t s_captures_len = 0;
|
||||
uint32_t s_fields_len = 0;
|
||||
uint32_t s_decls_len = 0;
|
||||
if (s_has_captures)
|
||||
s_captures_len = zir->extra[sei++];
|
||||
if (s_has_fields)
|
||||
s_fields_len = zir->extra[sei++];
|
||||
if (s_has_decls)
|
||||
s_decls_len = zir->extra[sei++];
|
||||
|
||||
if (s_fields_len == 0)
|
||||
return IP_INDEX_NONE;
|
||||
|
||||
sei += s_captures_len * 2;
|
||||
if (s_has_backing_int) {
|
||||
uint32_t bi_body = zir->extra[sei++];
|
||||
sei += (bi_body == 0) ? 1 : bi_body;
|
||||
}
|
||||
sei += s_decls_len;
|
||||
|
||||
// Parse field bit bags and entries to find the matching field.
|
||||
uint32_t bags_start = sei;
|
||||
uint32_t bags_count = (s_fields_len + 7) / 8;
|
||||
sei += bags_count;
|
||||
bool any_default_inits = (ssmall & (1 << 10)) != 0;
|
||||
|
||||
uint32_t struct_ns = findNamespaceForType(sema, struct_ip);
|
||||
|
||||
// The ZIR struct_decl layout has all field headers first, then all
|
||||
// field bodies concatenated after. We need two passes: first scan
|
||||
// headers to find the matching field and accumulate body offsets,
|
||||
// then resolve the type from the bodies section.
|
||||
uint32_t match_type_ref = 0;
|
||||
uint32_t match_type_body_len = 0;
|
||||
bool match_has_type_body = false;
|
||||
bool found_match = false;
|
||||
uint32_t body_offset_before_match = 0;
|
||||
uint32_t total_bodies_len = 0;
|
||||
|
||||
for (uint32_t fi = 0; fi < s_fields_len; fi++) {
|
||||
uint32_t bag_i = fi / 8;
|
||||
uint32_t bit_off = (fi % 8) * 4;
|
||||
uint32_t bits = (zir->extra[bags_start + bag_i] >> bit_off) & 0xf;
|
||||
bool f_has_align = (bits & 1) != 0;
|
||||
bool f_has_init = ((bits >> 1) & 1) != 0;
|
||||
bool f_has_type_body = ((bits >> 3) & 1) != 0;
|
||||
|
||||
// Read field name.
|
||||
uint32_t fname_zir = zir->extra[sei++];
|
||||
const char* fname = (const char*)&zir->string_bytes[fname_zir];
|
||||
bool is_match = strcmp(fname, field_name) == 0;
|
||||
|
||||
// Read type ref or body len.
|
||||
uint32_t type_body_len = 0;
|
||||
uint32_t type_ref = 0;
|
||||
if (f_has_type_body) {
|
||||
type_body_len = zir->extra[sei];
|
||||
} else {
|
||||
type_ref = zir->extra[sei];
|
||||
}
|
||||
sei++;
|
||||
|
||||
uint32_t align_body_len = 0;
|
||||
if (f_has_align)
|
||||
align_body_len = zir->extra[sei++];
|
||||
uint32_t init_body_len = 0;
|
||||
if (f_has_init && any_default_inits)
|
||||
init_body_len = zir->extra[sei++];
|
||||
|
||||
if (is_match) {
|
||||
match_type_ref = type_ref;
|
||||
match_type_body_len = type_body_len;
|
||||
match_has_type_body = f_has_type_body;
|
||||
body_offset_before_match = total_bodies_len;
|
||||
found_match = true;
|
||||
}
|
||||
|
||||
total_bodies_len += type_body_len;
|
||||
total_bodies_len += align_body_len;
|
||||
total_bodies_len += init_body_len;
|
||||
}
|
||||
|
||||
if (!found_match)
|
||||
return IP_INDEX_NONE;
|
||||
|
||||
// sei now points to the start of all bodies.
|
||||
if (match_has_type_body && match_type_body_len > 0) {
|
||||
uint32_t body_start = sei + body_offset_before_match;
|
||||
uint32_t last_zi = zir->extra[body_start + match_type_body_len - 1];
|
||||
if (last_zi < zir->inst_len
|
||||
&& zir->inst_tags[last_zi] == ZIR_INST_BREAK_INLINE) {
|
||||
ZirInstRef op = zir->inst_datas[last_zi].break_data.operand;
|
||||
return resolveZirTypeRef(sema, zir, op, struct_ns, file_idx);
|
||||
}
|
||||
} else if (!match_has_type_body && match_type_ref >= ZIR_REF_START_INDEX) {
|
||||
return resolveZirTypeRef(
|
||||
sema, zir, match_type_ref, struct_ns, file_idx);
|
||||
} else if (!match_has_type_body && match_type_ref < ZIR_REF_START_INDEX) {
|
||||
return match_type_ref; // pre-interned type
|
||||
}
|
||||
return IP_INDEX_NONE;
|
||||
}
|
||||
|
||||
// --- findEnumDeclForNav ---
|
||||
// Find the ZIR enum_decl instruction for an enum type nav.
|
||||
// Parses the nav's declaration value body to find the EXTENDED/ENUM_DECL.
|
||||
@@ -5129,8 +5309,18 @@ static void resolveUnionFullyC(Sema* sema, uint32_t nav_idx) {
|
||||
|
||||
// Phase 1: Resolve union field types in field order.
|
||||
// Store all resolved field type IP indices for Phase 3.
|
||||
// Also record field names and types in union_fields table for
|
||||
// zirStructInitFieldType (matches Zig's loadUnionType().field_types).
|
||||
InternPoolIndex resolved_field_types[128];
|
||||
memset(resolved_field_types, 0, sizeof(resolved_field_types));
|
||||
uint32_t num_resolved_fields = 0;
|
||||
uint32_t uf_idx = sema->zcu->num_union_fields;
|
||||
bool track_uf
|
||||
= uf_idx < ZCU_MAX_UNION_TYPES && fields_len <= ZCU_MAX_UNION_FIELDS;
|
||||
if (track_uf) {
|
||||
sema->zcu->union_fields[uf_idx].union_ip = nav->resolved_type;
|
||||
sema->zcu->union_fields[uf_idx].field_count = fields_len;
|
||||
}
|
||||
{
|
||||
uint32_t field_extra = extra_index + decls_len + body_len;
|
||||
uint32_t num_bit_bags = (fields_len + 7) / 8;
|
||||
@@ -5143,20 +5333,39 @@ static void resolveUnionFullyC(Sema* sema, uint32_t nav_idx) {
|
||||
bool ft_has_type = (bits & 1) != 0;
|
||||
bool ft_has_align = (bits & 2) != 0;
|
||||
bool ft_has_value = (bits & 4) != 0;
|
||||
cursor++; // skip field_name
|
||||
|
||||
// Read and record field name.
|
||||
uint32_t field_name_zir = zir->extra[cursor];
|
||||
cursor++;
|
||||
if (track_uf && fi < ZCU_MAX_UNION_FIELDS) {
|
||||
const char* fname
|
||||
= (const char*)&zir->string_bytes[field_name_zir];
|
||||
sema->zcu->union_fields[uf_idx].field_names[fi]
|
||||
= ipGetOrPutString(sema->ip, fname);
|
||||
}
|
||||
|
||||
InternPoolIndex field_type_ip = IP_INDEX_NONE;
|
||||
if (ft_has_type) {
|
||||
ZirInstRef type_ref = zir->extra[cursor++];
|
||||
InternPoolIndex resolved
|
||||
field_type_ip
|
||||
= resolveZirTypeRef(sema, zir, type_ref, ns_idx, file_idx);
|
||||
if (resolved != IP_INDEX_NONE && num_resolved_fields < 128)
|
||||
resolved_field_types[num_resolved_fields++] = resolved;
|
||||
if (field_type_ip != IP_INDEX_NONE
|
||||
&& num_resolved_fields < 128)
|
||||
resolved_field_types[num_resolved_fields++]
|
||||
= field_type_ip;
|
||||
}
|
||||
if (track_uf && fi < ZCU_MAX_UNION_FIELDS)
|
||||
sema->zcu->union_fields[uf_idx].field_types[fi]
|
||||
= field_type_ip;
|
||||
|
||||
if (ft_has_align)
|
||||
cursor++;
|
||||
if (ft_has_value)
|
||||
cursor++;
|
||||
}
|
||||
}
|
||||
if (track_uf)
|
||||
sema->zcu->num_union_fields++;
|
||||
|
||||
// Phase 2: Tag values and tag enum for tagged unions.
|
||||
if (auto_enum_tag || has_tag_type) {
|
||||
@@ -10664,13 +10873,14 @@ static AirInstRef zirDeclLiteralComptime(Sema* sema, uint32_t inst) {
|
||||
const char* field_name
|
||||
= (const char*)&sema->code.string_bytes[field_name_start];
|
||||
|
||||
// General case: resolve the LHS type and look up the field name
|
||||
// in its namespace. Ported from Sema.zig zirDeclLiteral →
|
||||
// namespaceLookupVal which evaluates the declaration.
|
||||
// Resolve the LHS type. Ported from Sema.zig zirDeclLiteral →
|
||||
// resolveTypeOrPoison → fieldVal.
|
||||
AirInstRef lhs_result = resolveInst(sema, lhs_ref);
|
||||
if (AIR_REF_IS_IP(lhs_result)) {
|
||||
InternPoolIndex lhs_ip = AIR_REF_TO_IP(lhs_result);
|
||||
// The LHS should be a type. Find its namespace.
|
||||
|
||||
// Try namespace lookup first (for declarations within the type).
|
||||
// Ported from Sema.zig fieldVal → namespaceLookupVal.
|
||||
uint32_t ns = findNamespaceForType(sema, lhs_ip);
|
||||
if (ns != UINT32_MAX) {
|
||||
uint32_t nav = findNavInNamespace(sema, ns, field_name);
|
||||
@@ -10680,6 +10890,34 @@ static AirInstRef zirDeclLiteralComptime(Sema* sema, uint32_t inst) {
|
||||
return AIR_REF_FROM_IP(val);
|
||||
}
|
||||
}
|
||||
|
||||
// For enum types: look up field name as enum tag value.
|
||||
// Ported from Sema.zig fieldVal .enum case →
|
||||
// enumFieldIndex + enumValueFieldIndex.
|
||||
InternPoolKey lhs_key = sema->ip->items[lhs_ip];
|
||||
if (lhs_key.tag == IP_KEY_ENUM_TYPE) {
|
||||
uint32_t name_ip = ipGetOrPutString(sema->ip, field_name);
|
||||
for (uint32_t ei = 0; ei < sema->zcu->num_enum_fields; ei++) {
|
||||
if (sema->zcu->enum_fields[ei].enum_ip != lhs_ip)
|
||||
continue;
|
||||
for (uint32_t fi = 0;
|
||||
fi < sema->zcu->enum_fields[ei].field_count; fi++) {
|
||||
if (sema->zcu->enum_fields[ei].field_names[fi] != name_ip)
|
||||
continue;
|
||||
// Found the field. Create enum_tag entry.
|
||||
// Ported from PerThread.zig enumValueFieldIndex.
|
||||
InternPoolIndex tag_int
|
||||
= sema->zcu->enum_fields[ei].field_tag_ints[fi];
|
||||
InternPoolKey ek;
|
||||
memset(&ek, 0, sizeof(ek));
|
||||
ek.tag = IP_KEY_ENUM_TAG;
|
||||
ek.data.enum_tag.ty = lhs_ip;
|
||||
ek.data.enum_tag.int_val = tag_int;
|
||||
return AIR_REF_FROM_IP(ipIntern(sema->ip, ek));
|
||||
}
|
||||
break; // found enum but not the field
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UNIMPLEMENTED("zirDeclLiteralComptime: field lookup failed");
|
||||
@@ -13233,12 +13471,66 @@ bool analyzeBodyInner(
|
||||
// Validation-only struct init instructions: no-op.
|
||||
case ZIR_INST_VALIDATE_STRUCT_INIT_TY:
|
||||
case ZIR_INST_VALIDATE_STRUCT_INIT_RESULT_TY:
|
||||
case ZIR_INST_STRUCT_INIT_FIELD_TYPE:
|
||||
instMapPut(
|
||||
&sema->inst_map, inst, AIR_REF_FROM_IP(IP_INDEX_VOID_TYPE));
|
||||
i++;
|
||||
continue;
|
||||
|
||||
// struct_init_field_type: resolve the type of a struct field.
|
||||
// Ported from Sema.zig zirStructInitFieldType → fieldType.
|
||||
case ZIR_INST_STRUCT_INIT_FIELD_TYPE: {
|
||||
uint32_t pi = sema->code.inst_datas[inst].pl_node.payload_index;
|
||||
ZirInstRef container_ref = sema->code.extra[pi];
|
||||
uint32_t name_start = sema->code.extra[pi + 1];
|
||||
const char* fname
|
||||
= (const char*)&sema->code.string_bytes[name_start];
|
||||
AirInstRef ctype = resolveInst(sema, container_ref);
|
||||
AirInstRef result = AIR_REF_FROM_IP(IP_INDEX_VOID_TYPE);
|
||||
if (AIR_REF_IS_IP(ctype)) {
|
||||
InternPoolIndex cip = AIR_REF_TO_IP(ctype);
|
||||
InternPoolKeyTag ctag = sema->ip->items[cip].tag;
|
||||
if (ctag == IP_KEY_STRUCT_TYPE) {
|
||||
// Struct: try sema->struct_info first, then ZIR.
|
||||
uint32_t fidx = 0;
|
||||
const StructFieldInfo* si
|
||||
= lookupStructField(sema, cip, fname, &fidx);
|
||||
if (si && si->fields[fidx].type != IP_INDEX_NONE) {
|
||||
result = AIR_REF_FROM_IP(si->fields[fidx].type);
|
||||
} else {
|
||||
InternPoolIndex ft
|
||||
= lookupStructFieldTypeFromZir(sema, cip, fname);
|
||||
if (ft != IP_INDEX_NONE)
|
||||
result = AIR_REF_FROM_IP(ft);
|
||||
}
|
||||
} else if (ctag == IP_KEY_UNION_TYPE) {
|
||||
// Union field type lookup.
|
||||
uint32_t name_ip = ipGetOrPutString(sema->ip, fname);
|
||||
for (uint32_t ui = 0; ui < sema->zcu->num_union_fields;
|
||||
ui++) {
|
||||
if (sema->zcu->union_fields[ui].union_ip != cip)
|
||||
continue;
|
||||
for (uint32_t uf = 0;
|
||||
uf < sema->zcu->union_fields[ui].field_count;
|
||||
uf++) {
|
||||
if (sema->zcu->union_fields[ui].field_names[uf]
|
||||
!= name_ip)
|
||||
continue;
|
||||
InternPoolIndex ft
|
||||
= sema->zcu->union_fields[ui].field_types[uf];
|
||||
if (ft != IP_INDEX_NONE)
|
||||
result = AIR_REF_FROM_IP(ft);
|
||||
goto sift_done;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
sift_done:
|
||||
instMapPut(&sema->inst_map, inst, result);
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
case ZIR_INST_VALIDATE_PTR_STRUCT_INIT:
|
||||
if (block->is_comptime) {
|
||||
zirValidatePtrStructInit(sema, inst);
|
||||
|
||||
28
stage0/zcu.h
28
stage0/zcu.h
@@ -100,6 +100,34 @@ typedef struct Zcu {
|
||||
// Zig's sharded IP where preamble and main shards use different nav IDs).
|
||||
bool preamble_skip_ptr_nav;
|
||||
|
||||
// --- Union field info (C-specific) ---
|
||||
// Stores field names and types for resolved union types so that
|
||||
// zirStructInitFieldType can look up union field types by name.
|
||||
// Ported equivalent: Zig's loadUnionType().field_types.
|
||||
#define ZCU_MAX_UNION_TYPES 64
|
||||
#define ZCU_MAX_UNION_FIELDS 256
|
||||
struct {
|
||||
InternPoolIndex union_ip; // union type IP index
|
||||
uint32_t field_count;
|
||||
uint32_t field_names[ZCU_MAX_UNION_FIELDS]; // IP string indices
|
||||
InternPoolIndex field_types[ZCU_MAX_UNION_FIELDS]; // field type IPs
|
||||
} union_fields[ZCU_MAX_UNION_TYPES];
|
||||
uint32_t num_union_fields;
|
||||
|
||||
// --- Enum field info (C-specific) ---
|
||||
// Stores field names and tag values for resolved enum types so that
|
||||
// zirDeclLiteralComptime can look up enum fields by name.
|
||||
// Ported equivalent: Zig's loadEnumType().nameIndex() + values.
|
||||
#define ZCU_MAX_ENUM_TYPES 256
|
||||
#define ZCU_MAX_ENUM_FIELDS 64
|
||||
struct {
|
||||
InternPoolIndex enum_ip; // enum type IP index
|
||||
uint32_t field_count;
|
||||
uint32_t field_names[ZCU_MAX_ENUM_FIELDS]; // IP string indices
|
||||
InternPoolIndex field_tag_ints[ZCU_MAX_ENUM_FIELDS];
|
||||
} enum_fields[ZCU_MAX_ENUM_TYPES];
|
||||
uint32_t num_enum_fields;
|
||||
|
||||
// --- Compilation config ---
|
||||
Compilation* comp; // back-pointer; matches Zcu.comp in Zig
|
||||
} Zcu;
|
||||
|
||||
Reference in New Issue
Block a user