astgen: add unionDeclInner, @hasDecl, @hasField, bitBuiltins
Implement unionDeclInner (AstGen.zig:5289-5466) to properly handle union container declarations instead of falling through to structDeclInner. This fixes tupleDecl errors for void union fields (A, B, Compiled, x86_64) and resolves localVarRef failures for union field identifiers. Add builtins: @hasDecl, @hasField (@hasDeclOrField pattern), @clz, @ctz, @popCount, @byteSwap, @bitReverse (bitBuiltin pattern). Add setUnion with UnionDeclSmall packing for ZIR_EXT_UNION_DECL. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
436
stage0/astgen.c
436
stage0/astgen.c
@@ -2069,6 +2069,79 @@ static void setStruct(AstGenCtx* ag, uint32_t inst, uint32_t src_node,
|
||||
ag->inst_datas[inst] = data;
|
||||
}
|
||||
|
||||
// --- setUnion (AstGen.zig:12999) ---
|
||||
|
||||
// UnionDecl.Small bit packing (Zir.zig:3573-3590).
|
||||
typedef struct {
|
||||
bool has_tag_type;
|
||||
bool has_captures_len;
|
||||
bool has_body_len;
|
||||
bool has_fields_len;
|
||||
bool has_decls_len;
|
||||
uint8_t name_strategy; // 2 bits
|
||||
uint8_t layout; // 2 bits
|
||||
bool auto_enum_tag;
|
||||
bool any_aligned_fields;
|
||||
} UnionDeclSmall;
|
||||
|
||||
static uint16_t packUnionDeclSmall(UnionDeclSmall s) {
|
||||
uint16_t r = 0;
|
||||
if (s.has_tag_type)
|
||||
r |= (1u << 0);
|
||||
if (s.has_captures_len)
|
||||
r |= (1u << 1);
|
||||
if (s.has_body_len)
|
||||
r |= (1u << 2);
|
||||
if (s.has_fields_len)
|
||||
r |= (1u << 3);
|
||||
if (s.has_decls_len)
|
||||
r |= (1u << 4);
|
||||
r |= (uint16_t)(s.name_strategy & 0x3u) << 5;
|
||||
r |= (uint16_t)(s.layout & 0x3u) << 7;
|
||||
if (s.auto_enum_tag)
|
||||
r |= (1u << 9);
|
||||
if (s.any_aligned_fields)
|
||||
r |= (1u << 10);
|
||||
return r;
|
||||
}
|
||||
|
||||
// Mirrors GenZir.setUnion (AstGen.zig:12999-13062).
|
||||
static void setUnion(AstGenCtx* ag, uint32_t inst, uint32_t src_node,
|
||||
UnionDeclSmall small, uint32_t tag_type, uint32_t captures_len,
|
||||
uint32_t body_len, uint32_t fields_len, uint32_t decls_len) {
|
||||
ensureExtraCapacity(ag, 6 + 5);
|
||||
|
||||
uint32_t payload_index = ag->extra_len;
|
||||
|
||||
// fields_hash (4 words): zero-filled; hash comparison skipped in tests.
|
||||
ag->extra[ag->extra_len++] = 0;
|
||||
ag->extra[ag->extra_len++] = 0;
|
||||
ag->extra[ag->extra_len++] = 0;
|
||||
ag->extra[ag->extra_len++] = 0;
|
||||
|
||||
ag->extra[ag->extra_len++] = ag->source_line;
|
||||
ag->extra[ag->extra_len++] = src_node;
|
||||
|
||||
if (small.has_tag_type)
|
||||
ag->extra[ag->extra_len++] = tag_type;
|
||||
if (small.has_captures_len)
|
||||
ag->extra[ag->extra_len++] = captures_len;
|
||||
if (small.has_body_len)
|
||||
ag->extra[ag->extra_len++] = body_len;
|
||||
if (small.has_fields_len)
|
||||
ag->extra[ag->extra_len++] = fields_len;
|
||||
if (small.has_decls_len)
|
||||
ag->extra[ag->extra_len++] = decls_len;
|
||||
|
||||
ag->inst_tags[inst] = ZIR_INST_EXTENDED;
|
||||
ZirInstData data;
|
||||
memset(&data, 0, sizeof(data));
|
||||
data.extended.opcode = (uint16_t)ZIR_EXT_UNION_DECL;
|
||||
data.extended.small = packUnionDeclSmall(small);
|
||||
data.extended.operand = payload_index;
|
||||
ag->inst_datas[inst] = data;
|
||||
}
|
||||
|
||||
// --- scanContainer (AstGen.zig:13384) ---
|
||||
|
||||
// Mirrors scanContainer (AstGen.zig:13384).
|
||||
@@ -2619,6 +2692,10 @@ static uint32_t structDeclInner(AstGenCtx* ag, GenZir* gz, Scope* scope,
|
||||
static uint32_t tupleDecl(AstGenCtx* ag, GenZir* gz, Scope* scope,
|
||||
uint32_t node, const uint32_t* members, uint32_t members_len,
|
||||
uint8_t layout, uint32_t backing_int_node);
|
||||
static uint32_t unionDeclInner(AstGenCtx* ag, GenZir* gz, Scope* scope,
|
||||
uint32_t node, const uint32_t* members, uint32_t members_len,
|
||||
uint8_t layout, uint32_t arg_node, bool auto_enum_tag,
|
||||
uint8_t name_strategy);
|
||||
static uint32_t enumDeclInner(AstGenCtx* ag, GenZir* gz, Scope* scope,
|
||||
uint32_t node, const uint32_t* members, uint32_t members_len,
|
||||
uint32_t arg_node, uint8_t name_strategy);
|
||||
@@ -2793,6 +2870,7 @@ static uint32_t tryResolvePrimitiveIdent(GenZir* gz, uint32_t node);
|
||||
#define COMPTIME_REASON_EXPORT_OPTIONS 15
|
||||
#define COMPTIME_REASON_CALL_MODIFIER 18
|
||||
#define COMPTIME_REASON_SHUFFLE_MASK 11
|
||||
#define COMPTIME_REASON_DECL_NAME 41
|
||||
|
||||
// Mirrors comptimeExpr2 (AstGen.zig:1982).
|
||||
// Evaluates a node in a comptime block_comptime scope.
|
||||
@@ -4007,6 +4085,45 @@ static uint32_t builtinCall(
|
||||
= addPlNodeBin(gz, ZIR_INST_DIV_EXACT, node, lhs, rhs);
|
||||
return rvalue(gz, rl, result, node);
|
||||
}
|
||||
// @clz — bitBuiltin (AstGen.zig:9475, 9907-9918).
|
||||
if (name_len == 3 && memcmp(source + name_start, "clz", 3) == 0) {
|
||||
AstData nd = tree->nodes.datas[node];
|
||||
uint32_t operand = expr(gz, scope, nd.lhs);
|
||||
uint32_t result = addUnNode(gz, ZIR_INST_CLZ, operand, node);
|
||||
return rvalue(gz, rl, result, node);
|
||||
}
|
||||
// @ctz — bitBuiltin (AstGen.zig:9476, 9907-9918).
|
||||
if (name_len == 3 && memcmp(source + name_start, "ctz", 3) == 0) {
|
||||
AstData nd = tree->nodes.datas[node];
|
||||
uint32_t operand = expr(gz, scope, nd.lhs);
|
||||
uint32_t result = addUnNode(gz, ZIR_INST_CTZ, operand, node);
|
||||
return rvalue(gz, rl, result, node);
|
||||
}
|
||||
// @popCount — bitBuiltin (AstGen.zig:9477, 9907-9918).
|
||||
if (name_len == 8
|
||||
&& memcmp(source + name_start, "popCount", 8) == 0) {
|
||||
AstData nd = tree->nodes.datas[node];
|
||||
uint32_t operand = expr(gz, scope, nd.lhs);
|
||||
uint32_t result = addUnNode(gz, ZIR_INST_POP_COUNT, operand, node);
|
||||
return rvalue(gz, rl, result, node);
|
||||
}
|
||||
// @byteSwap — bitBuiltin (AstGen.zig:9478, 9907-9918).
|
||||
if (name_len == 8
|
||||
&& memcmp(source + name_start, "byteSwap", 8) == 0) {
|
||||
AstData nd = tree->nodes.datas[node];
|
||||
uint32_t operand = expr(gz, scope, nd.lhs);
|
||||
uint32_t result = addUnNode(gz, ZIR_INST_BYTE_SWAP, operand, node);
|
||||
return rvalue(gz, rl, result, node);
|
||||
}
|
||||
// @bitReverse — bitBuiltin (AstGen.zig:9479, 9907-9918).
|
||||
if (name_len == 10
|
||||
&& memcmp(source + name_start, "bitReverse", 10) == 0) {
|
||||
AstData nd = tree->nodes.datas[node];
|
||||
uint32_t operand = expr(gz, scope, nd.lhs);
|
||||
uint32_t result
|
||||
= addUnNode(gz, ZIR_INST_BIT_REVERSE, operand, node);
|
||||
return rvalue(gz, rl, result, node);
|
||||
}
|
||||
// @bitOffsetOf — AstGen.zig:9490, 9962-9978.
|
||||
if (name_len == 11
|
||||
&& memcmp(source + name_start, "bitOffsetOf", 11) == 0) {
|
||||
@@ -4044,6 +4161,34 @@ static uint32_t builtinCall(
|
||||
addInstruction(gz, ZIR_INST_EXPORT, data);
|
||||
return rvalue(gz, rl, ZIR_REF_VOID_VALUE, node);
|
||||
}
|
||||
// @hasDecl — hasDeclOrField (AstGen.zig:9472, 9783-9805).
|
||||
if (name_len == 7
|
||||
&& memcmp(source + name_start, "hasDecl", 7) == 0) {
|
||||
AstData nd = tree->nodes.datas[node];
|
||||
uint32_t container_type = typeExpr(gz, scope, nd.lhs);
|
||||
ResultLoc name_rl = { .tag = RL_COERCED_TY,
|
||||
.data = ZIR_REF_SLICE_CONST_U8_TYPE,
|
||||
.src_node = 0, .ctx = RI_CTX_NONE };
|
||||
uint32_t name_inst = comptimeExpr(
|
||||
gz, scope, name_rl, nd.rhs, COMPTIME_REASON_DECL_NAME);
|
||||
uint32_t result = addPlNodeBin(
|
||||
gz, ZIR_INST_HAS_DECL, node, container_type, name_inst);
|
||||
return rvalue(gz, rl, result, node);
|
||||
}
|
||||
// @hasField — hasDeclOrField (AstGen.zig:9473, 9783-9805).
|
||||
if (name_len == 8
|
||||
&& memcmp(source + name_start, "hasField", 8) == 0) {
|
||||
AstData nd = tree->nodes.datas[node];
|
||||
uint32_t container_type = typeExpr(gz, scope, nd.lhs);
|
||||
ResultLoc name_rl = { .tag = RL_COERCED_TY,
|
||||
.data = ZIR_REF_SLICE_CONST_U8_TYPE,
|
||||
.src_node = 0, .ctx = RI_CTX_NONE };
|
||||
uint32_t name_inst = comptimeExpr(
|
||||
gz, scope, name_rl, nd.rhs, COMPTIME_REASON_FIELD_NAME);
|
||||
uint32_t result = addPlNodeBin(
|
||||
gz, ZIR_INST_HAS_FIELD, node, container_type, name_inst);
|
||||
return rvalue(gz, rl, result, node);
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
// TODO: handle other builtins.
|
||||
@@ -14093,8 +14238,36 @@ static uint32_t containerDecl(
|
||||
decl_inst = enumDeclInner(ag, gz, scope, node, members, members_len,
|
||||
arg_node, name_strategy);
|
||||
break;
|
||||
case TOKEN_KEYWORD_UNION: {
|
||||
// Extract layout (AstGen.zig:5499-5503).
|
||||
uint8_t layout = 0; // auto
|
||||
if (main_token > 0) {
|
||||
TokenizerTag prev_tag = tree->tokens.tags[main_token - 1];
|
||||
if (prev_tag == TOKEN_KEYWORD_PACKED)
|
||||
layout = 2;
|
||||
else if (prev_tag == TOKEN_KEYWORD_EXTERN)
|
||||
layout = 1;
|
||||
}
|
||||
// Determine auto_enum_tag from node type (AstGen.zig:5505).
|
||||
bool auto_enum_tag = false;
|
||||
switch (tag) {
|
||||
case AST_NODE_TAGGED_UNION:
|
||||
case AST_NODE_TAGGED_UNION_TRAILING:
|
||||
case AST_NODE_TAGGED_UNION_TWO:
|
||||
case AST_NODE_TAGGED_UNION_TWO_TRAILING:
|
||||
case AST_NODE_TAGGED_UNION_ENUM_TAG:
|
||||
case AST_NODE_TAGGED_UNION_ENUM_TAG_TRAILING:
|
||||
auto_enum_tag = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
decl_inst = unionDeclInner(ag, gz, scope, node, members, members_len,
|
||||
layout, arg_node, auto_enum_tag, name_strategy);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// union/opaque: fall back to struct for now.
|
||||
// opaque: fall back to struct for now.
|
||||
decl_inst = structDeclInner(
|
||||
ag, gz, scope, node, members, members_len, 0, 0, name_strategy);
|
||||
break;
|
||||
@@ -14545,6 +14718,267 @@ static uint32_t tupleDecl(AstGenCtx* ag, GenZir* gz, Scope* scope,
|
||||
return idx;
|
||||
}
|
||||
|
||||
// --- unionDeclInner (AstGen.zig:5289) ---
|
||||
|
||||
static uint32_t unionDeclInner(AstGenCtx* ag, GenZir* gz, Scope* scope,
|
||||
uint32_t node, const uint32_t* members, uint32_t members_len,
|
||||
uint8_t layout, uint32_t arg_node, bool auto_enum_tag,
|
||||
uint8_t name_strategy) {
|
||||
const Ast* tree = ag->tree;
|
||||
|
||||
uint32_t decl_inst = reserveInstructionIndex(ag);
|
||||
gzAppendInstruction(gz, decl_inst);
|
||||
|
||||
// Create namespace scope (AstGen.zig:5304-5310).
|
||||
ScopeNamespace namespace;
|
||||
scopeNamespaceInit(&namespace, scope, node, decl_inst, gz, ag->within_fn);
|
||||
|
||||
// Create block scope (AstGen.zig:5317-5325).
|
||||
advanceSourceCursorToNode(ag, node);
|
||||
GenZir block_scope;
|
||||
memset(&block_scope, 0, sizeof(block_scope));
|
||||
block_scope.base.tag = SCOPE_GEN_ZIR;
|
||||
block_scope.parent = &namespace.base;
|
||||
block_scope.astgen = ag;
|
||||
block_scope.decl_node_index = node;
|
||||
block_scope.decl_line = gz->decl_line;
|
||||
block_scope.is_comptime = true;
|
||||
block_scope.instructions_top = ag->scratch_inst_len;
|
||||
block_scope.any_defer_node = UINT32_MAX;
|
||||
|
||||
// Scan container (AstGen.zig:5328).
|
||||
uint32_t decl_count = scanContainer(ag, &namespace, members, members_len);
|
||||
uint32_t field_count = members_len - decl_count;
|
||||
|
||||
// Layout validation (AstGen.zig:5331-5337).
|
||||
if (layout != 0 && (auto_enum_tag || arg_node != 0)) {
|
||||
SET_ERROR(ag);
|
||||
}
|
||||
|
||||
// Process arg instruction (AstGen.zig:5339-5342).
|
||||
uint32_t arg_inst = ZIR_REF_NONE;
|
||||
if (arg_node != 0) {
|
||||
arg_inst = typeExpr(&block_scope, &namespace.base, arg_node);
|
||||
}
|
||||
|
||||
// WipMembers with bits_per_field=4, max_field_size=4 (AstGen.zig:5347).
|
||||
WipMembers wm = wipMembersInitEx(decl_count, field_count, 4, 4);
|
||||
|
||||
bool any_aligned_fields = false;
|
||||
|
||||
// Process each member (AstGen.zig:5359-5428).
|
||||
for (uint32_t i = 0; i < members_len; i++) {
|
||||
uint32_t member_node = members[i];
|
||||
AstNodeTag mtag = tree->nodes.tags[member_node];
|
||||
|
||||
switch (mtag) {
|
||||
// Declarations (containerMember AstGen.zig:5809-5901).
|
||||
case AST_NODE_COMPTIME:
|
||||
comptimeDecl(ag, gz, &namespace.base, wm.payload, &wm.decl_index,
|
||||
member_node);
|
||||
break;
|
||||
case AST_NODE_SIMPLE_VAR_DECL:
|
||||
globalVarDecl(ag, gz, &namespace.base, wm.payload, &wm.decl_index,
|
||||
member_node);
|
||||
break;
|
||||
case AST_NODE_TEST_DECL:
|
||||
testDecl(ag, gz, &namespace.base, wm.payload, &wm.decl_index,
|
||||
member_node);
|
||||
break;
|
||||
case AST_NODE_FN_DECL:
|
||||
case AST_NODE_FN_PROTO_SIMPLE:
|
||||
case AST_NODE_FN_PROTO_MULTI:
|
||||
case AST_NODE_FN_PROTO_ONE:
|
||||
case AST_NODE_FN_PROTO:
|
||||
fnDecl(ag, gz, &namespace.base, wm.payload, &wm.decl_index,
|
||||
member_node);
|
||||
break;
|
||||
case AST_NODE_USINGNAMESPACE:
|
||||
case AST_NODE_GLOBAL_VAR_DECL:
|
||||
case AST_NODE_LOCAL_VAR_DECL:
|
||||
case AST_NODE_ALIGNED_VAR_DECL:
|
||||
globalVarDecl(ag, gz, &namespace.base, wm.payload, &wm.decl_index,
|
||||
member_node);
|
||||
break;
|
||||
|
||||
// Fields (AstGen.zig:5359-5427).
|
||||
case AST_NODE_CONTAINER_FIELD_INIT:
|
||||
case AST_NODE_CONTAINER_FIELD_ALIGN:
|
||||
case AST_NODE_CONTAINER_FIELD: {
|
||||
uint32_t main_token = tree->nodes.main_tokens[member_node];
|
||||
AstData nd = tree->nodes.datas[member_node];
|
||||
uint32_t type_node = nd.lhs;
|
||||
uint32_t align_node = 0;
|
||||
uint32_t value_node = 0;
|
||||
|
||||
switch (mtag) {
|
||||
case AST_NODE_CONTAINER_FIELD_INIT:
|
||||
value_node = nd.rhs;
|
||||
break;
|
||||
case AST_NODE_CONTAINER_FIELD_ALIGN:
|
||||
align_node = nd.rhs;
|
||||
break;
|
||||
case AST_NODE_CONTAINER_FIELD:
|
||||
if (nd.rhs != 0) {
|
||||
align_node = tree->extra_data.arr[nd.rhs];
|
||||
value_node = tree->extra_data.arr[nd.rhs + 1];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// convertToNonTupleLike (AstGen.zig:5365, Ast.zig:2635-2641).
|
||||
bool tuple_like = tree->tokens.tags[main_token] != TOKEN_IDENTIFIER
|
||||
|| tree->tokens.tags[main_token + 1] != TOKEN_COLON;
|
||||
if (tuple_like && type_node != 0
|
||||
&& tree->nodes.tags[type_node] == AST_NODE_IDENTIFIER) {
|
||||
type_node = 0;
|
||||
tuple_like = false;
|
||||
}
|
||||
|
||||
// Still tuple-like after conversion: error (AstGen.zig:5366-5368).
|
||||
if (tuple_like) {
|
||||
SET_ERROR(ag);
|
||||
break;
|
||||
}
|
||||
|
||||
// Comptime check (AstGen.zig:5369-5371).
|
||||
if (main_token > 0
|
||||
&& tree->tokens.tags[main_token - 1]
|
||||
== TOKEN_KEYWORD_COMPTIME) {
|
||||
SET_ERROR(ag); // union fields cannot be marked comptime
|
||||
break;
|
||||
}
|
||||
|
||||
// Field name (AstGen.zig:5373).
|
||||
uint32_t field_name = identAsString(ag, main_token);
|
||||
wipMembersAppendToField(&wm, field_name);
|
||||
|
||||
bool have_type = (type_node != 0);
|
||||
bool have_align = (align_node != 0);
|
||||
bool have_value = (value_node != 0);
|
||||
bool field_bits[4] = { have_type, have_align, have_value, false };
|
||||
wipMembersNextField(&wm, field_bits);
|
||||
|
||||
// Type expression (AstGen.zig:5382-5387).
|
||||
if (have_type) {
|
||||
uint32_t field_type
|
||||
= typeExpr(&block_scope, &namespace.base, type_node);
|
||||
wipMembersAppendToField(&wm, field_type);
|
||||
} else if (arg_inst == ZIR_REF_NONE && !auto_enum_tag) {
|
||||
SET_ERROR(ag); // union field missing type
|
||||
break;
|
||||
}
|
||||
|
||||
// Alignment (AstGen.zig:5388-5395).
|
||||
if (have_align) {
|
||||
if (layout == 2) { // packed
|
||||
SET_ERROR(ag);
|
||||
break;
|
||||
}
|
||||
ResultLoc align_rl = { .tag = RL_COERCED_TY,
|
||||
.data = ZIR_REF_U29_TYPE,
|
||||
.src_node = 0,
|
||||
.ctx = RI_CTX_NONE };
|
||||
uint32_t align_ref = exprRl(
|
||||
&block_scope, &block_scope.base, align_rl, align_node);
|
||||
wipMembersAppendToField(&wm, align_ref);
|
||||
any_aligned_fields = true;
|
||||
}
|
||||
|
||||
// Value expression / tag value (AstGen.zig:5396-5427).
|
||||
if (have_value) {
|
||||
if (arg_inst == ZIR_REF_NONE) {
|
||||
SET_ERROR(ag);
|
||||
break;
|
||||
}
|
||||
if (!auto_enum_tag) {
|
||||
SET_ERROR(ag);
|
||||
break;
|
||||
}
|
||||
ResultLoc val_rl = { .tag = RL_COERCED_TY,
|
||||
.data = arg_inst,
|
||||
.src_node = 0,
|
||||
.ctx = RI_CTX_NONE };
|
||||
uint32_t tag_value = exprRl(
|
||||
&block_scope, &block_scope.base, val_rl, value_node);
|
||||
wipMembersAppendToField(&wm, tag_value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
SET_ERROR(ag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
wipMembersFinishBits(&wm);
|
||||
|
||||
// Handle block scope body (AstGen.zig:5433-5438).
|
||||
uint32_t body_len = 0;
|
||||
if (gzInstructionsLen(&block_scope) > 0) {
|
||||
if (!endsWithNoReturn(&block_scope)) {
|
||||
makeBreakInline(&block_scope, decl_inst, ZIR_REF_VOID_VALUE,
|
||||
AST_NODE_OFFSET_NONE);
|
||||
}
|
||||
uint32_t raw_len = gzInstructionsLen(&block_scope);
|
||||
const uint32_t* body_slice = gzInstructionsSlice(&block_scope);
|
||||
body_len = countBodyLenAfterFixups(ag, body_slice, raw_len);
|
||||
}
|
||||
|
||||
// setUnion (AstGen.zig:5440-5452).
|
||||
UnionDeclSmall small;
|
||||
memset(&small, 0, sizeof(small));
|
||||
small.has_tag_type = (arg_inst != ZIR_REF_NONE);
|
||||
small.has_captures_len = (namespace.captures_len > 0);
|
||||
small.has_body_len = (body_len > 0);
|
||||
small.has_fields_len = (field_count > 0);
|
||||
small.has_decls_len = (decl_count > 0);
|
||||
small.name_strategy = name_strategy;
|
||||
small.layout = layout;
|
||||
small.auto_enum_tag = auto_enum_tag;
|
||||
small.any_aligned_fields = any_aligned_fields;
|
||||
setUnion(ag, decl_inst, node, small, arg_inst, namespace.captures_len,
|
||||
body_len, field_count, decl_count);
|
||||
|
||||
// Append trailing data (AstGen.zig:5454-5462).
|
||||
uint32_t decls_len;
|
||||
const uint32_t* decls_slice = wipMembersDeclsSlice(&wm, &decls_len);
|
||||
uint32_t fields_len;
|
||||
const uint32_t* fields_slice = wipMembersFieldsSlice(&wm, &fields_len);
|
||||
|
||||
ensureExtraCapacity(
|
||||
ag, namespace.captures_len * 2 + decls_len + body_len + fields_len);
|
||||
|
||||
// Captures (AstGen.zig:5458-5459).
|
||||
for (uint32_t j = 0; j < namespace.captures_len; j++)
|
||||
ag->extra[ag->extra_len++] = namespace.capture_keys[j];
|
||||
for (uint32_t j = 0; j < namespace.captures_len; j++)
|
||||
ag->extra[ag->extra_len++] = namespace.capture_vals[j];
|
||||
|
||||
// Decls (AstGen.zig:5460).
|
||||
for (uint32_t j = 0; j < decls_len; j++)
|
||||
ag->extra[ag->extra_len++] = decls_slice[j];
|
||||
|
||||
// Body (AstGen.zig:5461).
|
||||
if (body_len > 0) {
|
||||
uint32_t raw_len = gzInstructionsLen(&block_scope);
|
||||
const uint32_t* body_data = gzInstructionsSlice(&block_scope);
|
||||
for (uint32_t j = 0; j < raw_len; j++)
|
||||
appendPossiblyRefdBodyInst(ag, body_data[j]);
|
||||
}
|
||||
|
||||
// Fields (AstGen.zig:5462).
|
||||
for (uint32_t j = 0; j < fields_len; j++)
|
||||
ag->extra[ag->extra_len++] = fields_slice[j];
|
||||
|
||||
gzUnstack(&block_scope);
|
||||
wipMembersDeinit(&wm);
|
||||
scopeNamespaceDeinit(&namespace);
|
||||
return decl_inst;
|
||||
}
|
||||
|
||||
// --- structDeclInner (AstGen.zig:4926) ---
|
||||
|
||||
static uint32_t structDeclInner(AstGenCtx* ag, GenZir* gz, Scope* scope,
|
||||
|
||||
Reference in New Issue
Block a user