mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 16:54:52 +00:00
AstGen: support struct init with ref result location
This commit is contained in:
parent
d2b06c2612
commit
27fa4bc2be
@ -1300,40 +1300,28 @@ pub fn structInitExpr(
|
||||
}
|
||||
return Zir.Inst.Ref.void_value;
|
||||
},
|
||||
.ref => {
|
||||
if (struct_init.ast.type_expr != 0) {
|
||||
const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);
|
||||
return structInitExprRlTy(gz, scope, rl, node, struct_init, ty_inst, .struct_init_ref);
|
||||
} else {
|
||||
return structInitExprRlNone(gz, scope, rl, node, struct_init, .struct_init_anon_ref);
|
||||
}
|
||||
},
|
||||
.none, .none_or_ref => {
|
||||
if (struct_init.ast.type_expr != 0) {
|
||||
const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);
|
||||
return structInitExprRlTy(gz, scope, rl, node, struct_init, ty_inst);
|
||||
return structInitExprRlTy(gz, scope, rl, node, struct_init, ty_inst, .struct_init);
|
||||
} else {
|
||||
return structInitExprRlNone(gz, scope, rl, node, struct_init, .struct_init_anon);
|
||||
}
|
||||
const fields_list = try gpa.alloc(Zir.Inst.StructInitAnon.Item, struct_init.ast.fields.len);
|
||||
defer gpa.free(fields_list);
|
||||
|
||||
for (struct_init.ast.fields) |field_init, i| {
|
||||
const name_token = tree.firstToken(field_init) - 2;
|
||||
const str_index = try gz.identAsString(name_token);
|
||||
|
||||
fields_list[i] = .{
|
||||
.field_name = str_index,
|
||||
.init = try expr(gz, scope, .none, field_init),
|
||||
};
|
||||
}
|
||||
const init_inst = try gz.addPlNode(.struct_init_anon, node, Zir.Inst.StructInitAnon{
|
||||
.fields_len = @intCast(u32, fields_list.len),
|
||||
});
|
||||
try astgen.extra.ensureCapacity(gpa, astgen.extra.items.len +
|
||||
fields_list.len * @typeInfo(Zir.Inst.StructInitAnon.Item).Struct.fields.len);
|
||||
for (fields_list) |field| {
|
||||
_ = gz.astgen.addExtraAssumeCapacity(field);
|
||||
}
|
||||
return init_inst;
|
||||
},
|
||||
.ref => return astgen.failNode(node, "cannot take address of struct literal", .{}),
|
||||
.ty => |ty_inst| {
|
||||
if (struct_init.ast.type_expr == 0) {
|
||||
return structInitExprRlTy(gz, scope, rl, node, struct_init, ty_inst);
|
||||
return structInitExprRlTy(gz, scope, rl, node, struct_init, ty_inst, .struct_init);
|
||||
}
|
||||
const inner_ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);
|
||||
const result = try structInitExprRlTy(gz, scope, rl, node, struct_init, inner_ty_inst);
|
||||
const result = try structInitExprRlTy(gz, scope, rl, node, struct_init, inner_ty_inst, .struct_init);
|
||||
return rvalue(gz, scope, rl, result, node);
|
||||
},
|
||||
.ptr, .inferred_ptr => |ptr_inst| return structInitExprRlPtr(gz, scope, rl, node, struct_init, ptr_inst),
|
||||
@ -1341,6 +1329,41 @@ pub fn structInitExpr(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn structInitExprRlNone(
|
||||
gz: *GenZir,
|
||||
scope: *Scope,
|
||||
rl: ResultLoc,
|
||||
node: ast.Node.Index,
|
||||
struct_init: ast.full.StructInit,
|
||||
tag: Zir.Inst.Tag,
|
||||
) InnerError!Zir.Inst.Ref {
|
||||
const astgen = gz.astgen;
|
||||
const gpa = astgen.gpa;
|
||||
const tree = &astgen.file.tree;
|
||||
|
||||
const fields_list = try gpa.alloc(Zir.Inst.StructInitAnon.Item, struct_init.ast.fields.len);
|
||||
defer gpa.free(fields_list);
|
||||
|
||||
for (struct_init.ast.fields) |field_init, i| {
|
||||
const name_token = tree.firstToken(field_init) - 2;
|
||||
const str_index = try gz.identAsString(name_token);
|
||||
|
||||
fields_list[i] = .{
|
||||
.field_name = str_index,
|
||||
.init = try expr(gz, scope, .none, field_init),
|
||||
};
|
||||
}
|
||||
const init_inst = try gz.addPlNode(tag, node, Zir.Inst.StructInitAnon{
|
||||
.fields_len = @intCast(u32, fields_list.len),
|
||||
});
|
||||
try astgen.extra.ensureCapacity(gpa, astgen.extra.items.len +
|
||||
fields_list.len * @typeInfo(Zir.Inst.StructInitAnon.Item).Struct.fields.len);
|
||||
for (fields_list) |field| {
|
||||
_ = gz.astgen.addExtraAssumeCapacity(field);
|
||||
}
|
||||
return init_inst;
|
||||
}
|
||||
|
||||
pub fn structInitExprRlPtr(
|
||||
gz: *GenZir,
|
||||
scope: *Scope,
|
||||
@ -1380,6 +1403,7 @@ pub fn structInitExprRlTy(
|
||||
node: ast.Node.Index,
|
||||
struct_init: ast.full.StructInit,
|
||||
ty_inst: Zir.Inst.Ref,
|
||||
tag: Zir.Inst.Tag,
|
||||
) InnerError!Zir.Inst.Ref {
|
||||
const astgen = gz.astgen;
|
||||
const gpa = astgen.gpa;
|
||||
@ -1401,7 +1425,7 @@ pub fn structInitExprRlTy(
|
||||
.init = try expr(gz, scope, .{ .ty = field_ty_inst }, field_init),
|
||||
};
|
||||
}
|
||||
const init_inst = try gz.addPlNode(.struct_init, node, Zir.Inst.StructInit{
|
||||
const init_inst = try gz.addPlNode(tag, node, Zir.Inst.StructInit{
|
||||
.fields_len = @intCast(u32, fields_list.len),
|
||||
});
|
||||
try astgen.extra.ensureCapacity(gpa, astgen.extra.items.len +
|
||||
@ -1886,7 +1910,9 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner
|
||||
.switch_capture_else_ref,
|
||||
.struct_init_empty,
|
||||
.struct_init,
|
||||
.struct_init_ref,
|
||||
.struct_init_anon,
|
||||
.struct_init_anon_ref,
|
||||
.array_init,
|
||||
.array_init_anon,
|
||||
.array_init_ref,
|
||||
|
||||
12
src/Sema.zig
12
src/Sema.zig
@ -256,11 +256,13 @@ pub fn analyzeBody(
|
||||
.typeof_log2_int_type => try sema.zirTypeofLog2IntType(block, inst),
|
||||
.xor => try sema.zirBitwise(block, inst, .xor),
|
||||
.struct_init_empty => try sema.zirStructInitEmpty(block, inst),
|
||||
.struct_init => try sema.zirStructInit(block, inst),
|
||||
.struct_init_anon => try sema.zirStructInitAnon(block, inst),
|
||||
.struct_init => try sema.zirStructInit(block, inst, false),
|
||||
.struct_init_ref => try sema.zirStructInit(block, inst, true),
|
||||
.struct_init_anon => try sema.zirStructInitAnon(block, inst, false),
|
||||
.struct_init_anon_ref => try sema.zirStructInitAnon(block, inst, true),
|
||||
.array_init => try sema.zirArrayInit(block, inst, false),
|
||||
.array_init_anon => try sema.zirArrayInitAnon(block, inst, false),
|
||||
.array_init_ref => try sema.zirArrayInit(block, inst, true),
|
||||
.array_init_anon => try sema.zirArrayInitAnon(block, inst, false),
|
||||
.array_init_anon_ref => try sema.zirArrayInitAnon(block, inst, true),
|
||||
.union_init_ptr => try sema.zirUnionInitPtr(block, inst),
|
||||
.field_type => try sema.zirFieldType(block, inst),
|
||||
@ -5078,13 +5080,13 @@ fn zirUnionInitPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inner
|
||||
return sema.mod.fail(&block.base, src, "TODO: Sema.zirUnionInitPtr", .{});
|
||||
}
|
||||
|
||||
fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
|
||||
fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: bool) InnerError!*Inst {
|
||||
const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
|
||||
const src = inst_data.src();
|
||||
return sema.mod.fail(&block.base, src, "TODO: Sema.zirStructInit", .{});
|
||||
}
|
||||
|
||||
fn zirStructInitAnon(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
|
||||
fn zirStructInitAnon(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: bool) InnerError!*Inst {
|
||||
const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
|
||||
const src = inst_data.src();
|
||||
return sema.mod.fail(&block.base, src, "TODO: Sema.zirStructInitAnon", .{});
|
||||
|
||||
10
src/Zir.zig
10
src/Zir.zig
@ -660,9 +660,15 @@ pub const Inst = struct {
|
||||
/// struct value.
|
||||
/// Uses the `pl_node` field. Payload is `StructInit`.
|
||||
struct_init,
|
||||
/// Struct initialization syntax, make the result a pointer.
|
||||
/// Uses the `pl_node` field. Payload is `StructInit`.
|
||||
struct_init_ref,
|
||||
/// Struct initialization without a type.
|
||||
/// Uses the `pl_node` field. Payload is `StructInitAnon`.
|
||||
struct_init_anon,
|
||||
/// Anonymous struct initialization syntax, make the result a pointer.
|
||||
/// Uses the `pl_node` field. Payload is `StructInitAnon`.
|
||||
struct_init_anon_ref,
|
||||
/// Array initialization syntax.
|
||||
/// Uses the `pl_node` field. Payload is `MultiOp`.
|
||||
array_init,
|
||||
@ -1093,7 +1099,9 @@ pub const Inst = struct {
|
||||
.validate_array_init_ptr,
|
||||
.struct_init_empty,
|
||||
.struct_init,
|
||||
.struct_init_ref,
|
||||
.struct_init_anon,
|
||||
.struct_init_anon_ref,
|
||||
.array_init,
|
||||
.array_init_anon,
|
||||
.array_init_ref,
|
||||
@ -2442,7 +2450,9 @@ const Writer = struct {
|
||||
.slice_end,
|
||||
.slice_sentinel,
|
||||
.struct_init,
|
||||
.struct_init_ref,
|
||||
.struct_init_anon,
|
||||
.struct_init_anon_ref,
|
||||
.array_init,
|
||||
.array_init_anon,
|
||||
.array_init_ref,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user