astgen: rewrite enumDeclInner to match upstream enum handling
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
262
astgen.c
262
astgen.c
@@ -2221,7 +2221,7 @@ static uint32_t containerDecl(GenZir* gz, Scope* scope, uint32_t node);
|
|||||||
static uint32_t structDeclInner(AstGenCtx* ag, GenZir* gz, uint32_t node,
|
static uint32_t structDeclInner(AstGenCtx* ag, GenZir* gz, uint32_t node,
|
||||||
const uint32_t* members, uint32_t members_len);
|
const uint32_t* members, uint32_t members_len);
|
||||||
static uint32_t enumDeclInner(AstGenCtx* ag, GenZir* gz, uint32_t node,
|
static uint32_t enumDeclInner(AstGenCtx* ag, GenZir* gz, uint32_t node,
|
||||||
const uint32_t* members, uint32_t members_len);
|
const uint32_t* members, uint32_t members_len, uint32_t arg_node);
|
||||||
static uint32_t blockExprExpr(
|
static uint32_t blockExprExpr(
|
||||||
GenZir* gz, Scope* scope, ResultLoc rl, uint32_t node);
|
GenZir* gz, Scope* scope, ResultLoc rl, uint32_t node);
|
||||||
static uint32_t ifExpr(GenZir* gz, Scope* scope, ResultLoc rl, uint32_t node);
|
static uint32_t ifExpr(GenZir* gz, Scope* scope, ResultLoc rl, uint32_t node);
|
||||||
@@ -9235,15 +9235,16 @@ typedef struct {
|
|||||||
uint32_t bodies_cap;
|
uint32_t bodies_cap;
|
||||||
} WipMembers;
|
} WipMembers;
|
||||||
|
|
||||||
static WipMembers wipMembersInit(uint32_t decl_count, uint32_t field_count) {
|
// Parameterized init (AstGen.zig:3989 WipMembers.init).
|
||||||
// bits_per_field = 4, max_field_size = 5
|
static WipMembers wipMembersInitEx(uint32_t decl_count, uint32_t field_count,
|
||||||
uint32_t fields_per_u32 = 8; // 32 / 4
|
uint32_t bits_per_field, uint32_t max_field_size) {
|
||||||
|
uint32_t fields_per_u32 = bits_per_field > 0 ? 32 / bits_per_field : 0;
|
||||||
uint32_t field_bits_start = decl_count;
|
uint32_t field_bits_start = decl_count;
|
||||||
uint32_t bit_words = field_count > 0
|
uint32_t bit_words = (field_count > 0 && fields_per_u32 > 0)
|
||||||
? (field_count + fields_per_u32 - 1) / fields_per_u32
|
? (field_count + fields_per_u32 - 1) / fields_per_u32
|
||||||
: 0;
|
: 0;
|
||||||
uint32_t fields_start = field_bits_start + bit_words;
|
uint32_t fields_start = field_bits_start + bit_words;
|
||||||
uint32_t payload_end = fields_start + field_count * 5;
|
uint32_t payload_end = fields_start + field_count * max_field_size;
|
||||||
uint32_t alloc_size = payload_end > 0 ? payload_end : 1;
|
uint32_t alloc_size = payload_end > 0 ? payload_end : 1;
|
||||||
uint32_t* payload = calloc(alloc_size, sizeof(uint32_t));
|
uint32_t* payload = calloc(alloc_size, sizeof(uint32_t));
|
||||||
if (!payload)
|
if (!payload)
|
||||||
@@ -9263,6 +9264,11 @@ static WipMembers wipMembersInit(uint32_t decl_count, uint32_t field_count) {
|
|||||||
return wm;
|
return wm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static WipMembers wipMembersInit(uint32_t decl_count, uint32_t field_count) {
|
||||||
|
// bits_per_field = 4, max_field_size = 5
|
||||||
|
return wipMembersInitEx(decl_count, field_count, 4, 5);
|
||||||
|
}
|
||||||
|
|
||||||
static void wipMembersDeinit(WipMembers* wm) {
|
static void wipMembersDeinit(WipMembers* wm) {
|
||||||
free(wm->payload);
|
free(wm->payload);
|
||||||
free(wm->bodies);
|
free(wm->bodies);
|
||||||
@@ -9304,6 +9310,29 @@ static void wipMembersFinishBits(WipMembers* wm) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bits_per_field = 1: bits[0]=have_value (for enum fields).
|
||||||
|
static void wipMembersNextFieldEnum(WipMembers* wm, bool have_value) {
|
||||||
|
uint32_t fields_per_u32 = 32; // 32 / 1
|
||||||
|
uint32_t index = wm->field_bits_start + wm->field_index / fields_per_u32;
|
||||||
|
uint32_t bit_bag
|
||||||
|
= (wm->field_index % fields_per_u32 == 0) ? 0 : wm->payload[index];
|
||||||
|
bit_bag >>= 1;
|
||||||
|
bit_bag |= ((uint32_t)(have_value ? 1 : 0)) << 31;
|
||||||
|
wm->payload[index] = bit_bag;
|
||||||
|
wm->field_index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wipMembersFinishBitsEnum(WipMembers* wm) {
|
||||||
|
uint32_t fields_per_u32 = 32; // 32 / 1
|
||||||
|
uint32_t empty_field_slots
|
||||||
|
= fields_per_u32 - (wm->field_index % fields_per_u32);
|
||||||
|
if (wm->field_index > 0 && empty_field_slots < fields_per_u32) {
|
||||||
|
uint32_t index
|
||||||
|
= wm->field_bits_start + wm->field_index / fields_per_u32;
|
||||||
|
wm->payload[index] >>= empty_field_slots;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Returns pointer to decls region and its length.
|
// Returns pointer to decls region and its length.
|
||||||
static const uint32_t* wipMembersDeclsSlice(
|
static const uint32_t* wipMembersDeclsSlice(
|
||||||
const WipMembers* wm, uint32_t* out_len) {
|
const WipMembers* wm, uint32_t* out_len) {
|
||||||
@@ -9421,6 +9450,20 @@ static uint32_t containerDecl(GenZir* gz, Scope* scope, uint32_t node) {
|
|||||||
void* prev_fn_block = ag->fn_block;
|
void* prev_fn_block = ag->fn_block;
|
||||||
ag->fn_block = NULL;
|
ag->fn_block = NULL;
|
||||||
|
|
||||||
|
// Extract arg node for container_decl_arg variants (AstGen.zig:5638).
|
||||||
|
// For enum(u8), lhs is the arg node.
|
||||||
|
uint32_t arg_node = 0; // 0 = none
|
||||||
|
switch (tag) {
|
||||||
|
case AST_NODE_CONTAINER_DECL_ARG:
|
||||||
|
case AST_NODE_CONTAINER_DECL_ARG_TRAILING:
|
||||||
|
case AST_NODE_TAGGED_UNION_ENUM_TAG:
|
||||||
|
case AST_NODE_TAGGED_UNION_ENUM_TAG_TRAILING:
|
||||||
|
arg_node = nd.lhs;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Dispatch based on container keyword (AstGen.zig:5485-5536).
|
// Dispatch based on container keyword (AstGen.zig:5485-5536).
|
||||||
uint32_t main_token = tree->nodes.main_tokens[node];
|
uint32_t main_token = tree->nodes.main_tokens[node];
|
||||||
TokenizerTag kw_tag = tree->tokens.tags[main_token];
|
TokenizerTag kw_tag = tree->tokens.tags[main_token];
|
||||||
@@ -9430,7 +9473,8 @@ static uint32_t containerDecl(GenZir* gz, Scope* scope, uint32_t node) {
|
|||||||
decl_inst = structDeclInner(ag, gz, node, members, members_len);
|
decl_inst = structDeclInner(ag, gz, node, members, members_len);
|
||||||
break;
|
break;
|
||||||
case TOKEN_KEYWORD_ENUM:
|
case TOKEN_KEYWORD_ENUM:
|
||||||
decl_inst = enumDeclInner(ag, gz, node, members, members_len);
|
decl_inst
|
||||||
|
= enumDeclInner(ag, gz, node, members, members_len, arg_node);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// union/opaque: fall back to struct for now.
|
// union/opaque: fall back to struct for now.
|
||||||
@@ -9473,14 +9517,26 @@ static uint16_t packEnumDeclSmall(EnumDeclSmall s) {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mirrors GenZir.setEnum (AstGen.zig:13080).
|
// Mirrors GenZir.setEnum (AstGen.zig:13064-13123).
|
||||||
static void setEnum(AstGenCtx* ag, uint32_t inst, uint32_t src_node,
|
static void setEnum(AstGenCtx* ag, uint32_t inst, uint32_t src_node,
|
||||||
EnumDeclSmall small, uint32_t fields_len, uint32_t decls_len) {
|
uint32_t tag_type, uint32_t captures_len, uint32_t body_len,
|
||||||
ensureExtraCapacity(ag, 6 + 3);
|
uint32_t fields_len, uint32_t decls_len, bool nonexhaustive,
|
||||||
|
uint8_t name_strategy) {
|
||||||
|
EnumDeclSmall small;
|
||||||
|
memset(&small, 0, sizeof(small));
|
||||||
|
small.has_tag_type = (tag_type != ZIR_REF_NONE);
|
||||||
|
small.has_captures_len = (captures_len != 0);
|
||||||
|
small.has_body_len = (body_len != 0);
|
||||||
|
small.has_fields_len = (fields_len != 0);
|
||||||
|
small.has_decls_len = (decls_len != 0);
|
||||||
|
small.name_strategy = name_strategy;
|
||||||
|
small.nonexhaustive = nonexhaustive;
|
||||||
|
|
||||||
|
ensureExtraCapacity(ag, 6 + 5);
|
||||||
|
|
||||||
uint32_t payload_index = ag->extra_len;
|
uint32_t payload_index = ag->extra_len;
|
||||||
|
|
||||||
// fields_hash (4 words): zero-filled.
|
// 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++] = 0;
|
ag->extra[ag->extra_len++] = 0;
|
||||||
@@ -9489,6 +9545,13 @@ static void setEnum(AstGenCtx* ag, uint32_t inst, uint32_t src_node,
|
|||||||
ag->extra[ag->extra_len++] = ag->source_line;
|
ag->extra[ag->extra_len++] = ag->source_line;
|
||||||
ag->extra[ag->extra_len++] = src_node;
|
ag->extra[ag->extra_len++] = src_node;
|
||||||
|
|
||||||
|
// Trailing data in upstream order (AstGen.zig:13092-13106).
|
||||||
|
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)
|
if (small.has_fields_len)
|
||||||
ag->extra[ag->extra_len++] = fields_len;
|
ag->extra[ag->extra_len++] = fields_len;
|
||||||
if (small.has_decls_len)
|
if (small.has_decls_len)
|
||||||
@@ -9503,42 +9566,91 @@ static void setEnum(AstGenCtx* ag, uint32_t inst, uint32_t src_node,
|
|||||||
ag->inst_datas[inst] = data;
|
ag->inst_datas[inst] = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- enumDeclInner (AstGen.zig:5508) ---
|
// Returns true if the identifier token at `ident_token` is "_".
|
||||||
|
static bool tokenIsUnderscore(const Ast* tree, uint32_t ident_token) {
|
||||||
|
uint32_t start = tree->tokens.starts[ident_token];
|
||||||
|
const char* src = tree->source;
|
||||||
|
if (src[start] != '_')
|
||||||
|
return false;
|
||||||
|
// Check that the next character is not alphanumeric/underscore
|
||||||
|
// (i.e., the identifier is exactly "_").
|
||||||
|
char next = src[start + 1];
|
||||||
|
if ((next >= 'a' && next <= 'z') || (next >= 'A' && next <= 'Z')
|
||||||
|
|| (next >= '0' && next <= '9') || next == '_')
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- enumDeclInner (AstGen.zig:5508-5728) ---
|
||||||
|
// Handles enum container declarations.
|
||||||
|
// arg_node: the tag type expression node (e.g. u8 in enum(u8)), 0 if none.
|
||||||
|
|
||||||
static uint32_t enumDeclInner(AstGenCtx* ag, GenZir* gz, uint32_t node,
|
static uint32_t enumDeclInner(AstGenCtx* ag, GenZir* gz, uint32_t node,
|
||||||
const uint32_t* members, uint32_t members_len) {
|
const uint32_t* members, uint32_t members_len, uint32_t arg_node) {
|
||||||
const Ast* tree = ag->tree;
|
const Ast* tree = ag->tree;
|
||||||
|
|
||||||
|
// --- First pass: count fields, values, decls, detect nonexhaustive ---
|
||||||
|
// (AstGen.zig:5513-5590)
|
||||||
|
uint32_t total_fields = 0;
|
||||||
|
uint32_t decl_count = 0;
|
||||||
|
uint32_t nonexhaustive_index = UINT32_MAX; // index into members[]
|
||||||
|
for (uint32_t i = 0; i < members_len; i++) {
|
||||||
|
uint32_t member_node = members[i];
|
||||||
|
AstNodeTag mtag = tree->nodes.tags[member_node];
|
||||||
|
switch (mtag) {
|
||||||
|
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];
|
||||||
|
// Check for "_" (nonexhaustive marker).
|
||||||
|
if (tokenIsUnderscore(tree, main_token)) {
|
||||||
|
nonexhaustive_index = i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
total_fields++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
decl_count++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool nonexhaustive = (nonexhaustive_index != UINT32_MAX);
|
||||||
|
|
||||||
uint32_t decl_inst = reserveInstructionIndex(ag);
|
uint32_t decl_inst = reserveInstructionIndex(ag);
|
||||||
gzAppendInstruction(gz, decl_inst);
|
gzAppendInstruction(gz, decl_inst);
|
||||||
|
|
||||||
if (members_len == 0) {
|
|
||||||
EnumDeclSmall small;
|
|
||||||
memset(&small, 0, sizeof(small));
|
|
||||||
setEnum(ag, decl_inst, node, small, 0, 0);
|
|
||||||
return decl_inst;
|
|
||||||
}
|
|
||||||
|
|
||||||
advanceSourceCursorToNode(ag, node);
|
advanceSourceCursorToNode(ag, node);
|
||||||
|
|
||||||
uint32_t decl_count = scanContainer(ag, members, members_len);
|
// scanContainer to register names in string table (AstGen.zig:5635).
|
||||||
uint32_t field_count = members_len - decl_count;
|
scanContainer(ag, members, members_len);
|
||||||
|
|
||||||
// Use WipMembers for decls and field data.
|
// Set up block_scope for tag value expressions (AstGen.zig:5624-5632).
|
||||||
// Enum fields: 1 bit per field (has_value), max 2 words per field
|
GenZir block_scope;
|
||||||
// (name + value).
|
memset(&block_scope, 0, sizeof(block_scope));
|
||||||
WipMembers wm = wipMembersInit(decl_count, field_count);
|
block_scope.base.tag = SCOPE_GEN_ZIR;
|
||||||
|
block_scope.parent = NULL;
|
||||||
|
block_scope.astgen = ag;
|
||||||
|
block_scope.decl_node_index = node;
|
||||||
|
block_scope.decl_line = ag->source_line;
|
||||||
|
block_scope.is_comptime = true;
|
||||||
|
block_scope.instructions_top = ag->scratch_inst_len;
|
||||||
|
block_scope.any_defer_node = UINT32_MAX;
|
||||||
|
|
||||||
// Enum fields use 1 bit per field: has_value.
|
// Evaluate tag type argument if present (AstGen.zig:5638-5641).
|
||||||
// We use the same WipMembers but with 1-bit fields.
|
uint32_t arg_inst = ZIR_REF_NONE;
|
||||||
// Actually, upstream uses bits_per_field=1, max_field_size=2.
|
if (arg_node != 0)
|
||||||
// Re-init with correct params would be better but let's reuse.
|
arg_inst = typeExpr(&block_scope, &block_scope.base, arg_node);
|
||||||
// For simplicity: track field data manually.
|
|
||||||
uint32_t* field_names = NULL;
|
|
||||||
uint32_t field_names_len = 0;
|
|
||||||
uint32_t field_names_cap = 0;
|
|
||||||
|
|
||||||
|
// WipMembers with bits_per_field=1, max_field_size=2 (AstGen.zig:5645).
|
||||||
|
WipMembers wm = wipMembersInitEx(decl_count, total_fields, 1, 2);
|
||||||
|
|
||||||
|
// --- Second pass: process members (AstGen.zig:5656-5693) ---
|
||||||
for (uint32_t i = 0; i < members_len; i++) {
|
for (uint32_t i = 0; i < members_len; i++) {
|
||||||
uint32_t member_node = members[i];
|
uint32_t member_node = members[i];
|
||||||
|
// Skip nonexhaustive marker field (AstGen.zig:5657-5658).
|
||||||
|
if (i == nonexhaustive_index)
|
||||||
|
continue;
|
||||||
AstNodeTag mtag = tree->nodes.tags[member_node];
|
AstNodeTag mtag = tree->nodes.tags[member_node];
|
||||||
switch (mtag) {
|
switch (mtag) {
|
||||||
case AST_NODE_COMPTIME:
|
case AST_NODE_COMPTIME:
|
||||||
@@ -9559,19 +9671,33 @@ static uint32_t enumDeclInner(AstGenCtx* ag, GenZir* gz, uint32_t node,
|
|||||||
case AST_NODE_CONTAINER_FIELD_INIT:
|
case AST_NODE_CONTAINER_FIELD_INIT:
|
||||||
case AST_NODE_CONTAINER_FIELD_ALIGN:
|
case AST_NODE_CONTAINER_FIELD_ALIGN:
|
||||||
case AST_NODE_CONTAINER_FIELD: {
|
case AST_NODE_CONTAINER_FIELD: {
|
||||||
// Enum field: just a name (AstGen.zig:5617-5670).
|
// Enum field (AstGen.zig:5669-5692).
|
||||||
uint32_t main_token = tree->nodes.main_tokens[member_node];
|
uint32_t main_token = tree->nodes.main_tokens[member_node];
|
||||||
uint32_t field_name = identAsString(ag, main_token);
|
uint32_t field_name = identAsString(ag, main_token);
|
||||||
// Grow field_names array.
|
wipMembersAppendToField(&wm, field_name);
|
||||||
if (field_names_len >= field_names_cap) {
|
|
||||||
uint32_t new_cap
|
// Extract value expression.
|
||||||
= field_names_cap == 0 ? 8 : field_names_cap * 2;
|
AstData mnd = tree->nodes.datas[member_node];
|
||||||
field_names = realloc(field_names, new_cap * sizeof(uint32_t));
|
uint32_t value_node = 0;
|
||||||
if (!field_names)
|
if (mtag == AST_NODE_CONTAINER_FIELD_INIT) {
|
||||||
exit(1);
|
value_node = mnd.rhs;
|
||||||
field_names_cap = new_cap;
|
} else if (mtag == AST_NODE_CONTAINER_FIELD && mnd.rhs != 0) {
|
||||||
|
value_node = tree->extra_data.arr[mnd.rhs + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool have_value = (value_node != 0);
|
||||||
|
wipMembersNextFieldEnum(&wm, have_value);
|
||||||
|
|
||||||
|
// Evaluate tag value expression (AstGen.zig:5690-5691).
|
||||||
|
if (have_value) {
|
||||||
|
ResultLoc val_rl = { .tag = RL_COERCED_TY,
|
||||||
|
.data = arg_inst,
|
||||||
|
.src_node = 0,
|
||||||
|
.ctx = RI_CTX_NONE };
|
||||||
|
uint32_t tag_value_inst = exprRl(
|
||||||
|
&block_scope, &block_scope.base, val_rl, value_node);
|
||||||
|
wipMembersAppendToField(&wm, tag_value_inst);
|
||||||
}
|
}
|
||||||
field_names[field_names_len++] = field_name;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -9580,33 +9706,41 @@ static uint32_t enumDeclInner(AstGenCtx* ag, GenZir* gz, uint32_t node,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EnumDeclSmall small;
|
// Emit break_inline if block_scope has instructions
|
||||||
memset(&small, 0, sizeof(small));
|
// (AstGen.zig:5695-5697).
|
||||||
small.has_fields_len = (field_count > 0);
|
if (gzInstructionsLen(&block_scope) > 0) {
|
||||||
small.has_decls_len = (decl_count > 0);
|
addBreak(&block_scope, ZIR_INST_BREAK_INLINE, decl_inst,
|
||||||
setEnum(ag, decl_inst, node, small, field_count, decl_count);
|
ZIR_REF_VOID_VALUE, AST_NODE_OFFSET_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
// Append: decls, field_bits, field_names (AstGen.zig:5724-5729).
|
uint32_t raw_body_len = gzInstructionsLen(&block_scope);
|
||||||
|
const uint32_t* body = gzInstructionsSlice(&block_scope);
|
||||||
|
uint32_t body_len = countBodyLenAfterFixups(ag, body, raw_body_len);
|
||||||
|
|
||||||
|
// setEnum (AstGen.zig:5705-5715).
|
||||||
|
setEnum(ag, decl_inst, node, arg_inst, 0 /* captures_len */, body_len,
|
||||||
|
total_fields, decl_count, nonexhaustive, 0 /* name_strategy */);
|
||||||
|
|
||||||
|
wipMembersFinishBitsEnum(&wm);
|
||||||
|
|
||||||
|
// Append trailing data (AstGen.zig:5718-5725):
|
||||||
|
// captures (none), decls, body, fields.
|
||||||
uint32_t decls_len_out;
|
uint32_t decls_len_out;
|
||||||
const uint32_t* decls_slice = wipMembersDeclsSlice(&wm, &decls_len_out);
|
const uint32_t* decls_slice = wipMembersDeclsSlice(&wm, &decls_len_out);
|
||||||
|
uint32_t fields_len_out;
|
||||||
|
const uint32_t* fields_slice = wipMembersFieldsSlice(&wm, &fields_len_out);
|
||||||
|
|
||||||
// Field bits: 1 bit per field (has_value = false for simple enums).
|
ensureExtraCapacity(ag, decls_len_out + body_len + fields_len_out);
|
||||||
uint32_t fields_per_u32 = 32;
|
|
||||||
uint32_t bit_words = field_count > 0
|
|
||||||
? (field_count + fields_per_u32 - 1) / fields_per_u32
|
|
||||||
: 0;
|
|
||||||
|
|
||||||
ensureExtraCapacity(ag, decls_len_out + bit_words + field_names_len);
|
|
||||||
for (uint32_t i = 0; i < decls_len_out; i++)
|
for (uint32_t i = 0; i < decls_len_out; i++)
|
||||||
ag->extra[ag->extra_len++] = decls_slice[i];
|
ag->extra[ag->extra_len++] = decls_slice[i];
|
||||||
// Field bits: all zero (no values).
|
// Body instructions with fixups (AstGen.zig:5724).
|
||||||
for (uint32_t i = 0; i < bit_words; i++)
|
for (uint32_t i = 0; i < raw_body_len; i++)
|
||||||
ag->extra[ag->extra_len++] = 0;
|
appendPossiblyRefdBodyInst(ag, body[i]);
|
||||||
// Field names.
|
// Fields (bit bags + field data).
|
||||||
for (uint32_t i = 0; i < field_names_len; i++)
|
for (uint32_t i = 0; i < fields_len_out; i++)
|
||||||
ag->extra[ag->extra_len++] = field_names[i];
|
ag->extra[ag->extra_len++] = fields_slice[i];
|
||||||
|
|
||||||
free(field_names);
|
gzUnstack(&block_scope);
|
||||||
wipMembersDeinit(&wm);
|
wipMembersDeinit(&wm);
|
||||||
return decl_inst;
|
return decl_inst;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user