authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-01 22:34:40-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-01 22:39:09-07:00
log8ebfdc14f68521ac129ee7d2c3f4e7250e4e7418
tree7a20ca7752b10da7e811a52927b6d1ba0869e893
parentc66b48194ff83eb5b1774a1428461f5fc94dcd7d

stage2: implement structs in the frontend

New ZIR instructions: * struct_decl_packed * struct_decl_extern New TZIR instruction: struct_field_ptr Introduce `Module.Struct`. It uses `Value` to store default values and abi alignments. Implemented Sema.analyzeStructFieldPtr and zirStructDecl. Some stuff I changed from `@panic("TODO")` to `log.warn("TODO")`. It's becoming more clear that we need the lazy value mechanism soon; Type is becoming unruly, and some of these functions have too much logic given that they don't have any context for memory management or error reporting.

8 files changed, 304 insertions(+), 16 deletions(-)

src/AstGen.zig+9-2
...@@ -1322,6 +1322,8 @@ fn blockExprStmts(...@@ -1322,6 +1322,8 @@ fn blockExprStmts(
1322 .switch_capture_else_ref,1322 .switch_capture_else_ref,
1323 .struct_init_empty,1323 .struct_init_empty,
1324 .struct_decl,1324 .struct_decl,
1325 .struct_decl_packed,
1326 .struct_decl_extern,
1325 .union_decl,1327 .union_decl,
1326 .enum_decl,1328 .enum_decl,
1327 .opaque_decl,1329 .opaque_decl,
...@@ -1789,8 +1791,13 @@ fn containerDecl(...@@ -1789,8 +1791,13 @@ fn containerDecl(
17891791
1790 switch (token_tags[container_decl.ast.main_token]) {1792 switch (token_tags[container_decl.ast.main_token]) {
1791 .keyword_struct => {1793 .keyword_struct => {
1794 const tag = if (container_decl.layout_token) |t| switch (token_tags[t]) {
1795 .keyword_packed => zir.Inst.Tag.struct_decl_packed,
1796 .keyword_extern => zir.Inst.Tag.struct_decl_extern,
1797 else => unreachable,
1798 } else zir.Inst.Tag.struct_decl;
1792 if (container_decl.ast.members.len == 0) {1799 if (container_decl.ast.members.len == 0) {
1793 const result = try gz.addPlNode(.struct_decl, node, zir.Inst.StructDecl{1800 const result = try gz.addPlNode(tag, node, zir.Inst.StructDecl{
1794 .fields_len = 0,1801 .fields_len = 0,
1795 });1802 });
1796 return rvalue(gz, scope, rl, result, node);1803 return rvalue(gz, scope, rl, result, node);
...@@ -1856,7 +1863,7 @@ fn containerDecl(...@@ -1856,7 +1863,7 @@ fn containerDecl(
1856 const empty_slot_count = 16 - ((member_index - 1) % 16);1863 const empty_slot_count = 16 - ((member_index - 1) % 16);
1857 cur_bit_bag >>= @intCast(u5, empty_slot_count * 2);1864 cur_bit_bag >>= @intCast(u5, empty_slot_count * 2);
18581865
1859 const result = try gz.addPlNode(.struct_decl, node, zir.Inst.StructDecl{1866 const result = try gz.addPlNode(tag, node, zir.Inst.StructDecl{
1860 .fields_len = @intCast(u32, container_decl.ast.members.len),1867 .fields_len = @intCast(u32, container_decl.ast.members.len),
1861 });1868 });
1862 try astgen.extra.ensureCapacity(gpa, astgen.extra.items.len +1869 try astgen.extra.ensureCapacity(gpa, astgen.extra.items.len +
src/Module.zig+41
...@@ -356,6 +356,25 @@ pub const ErrorSet = struct {...@@ -356,6 +356,25 @@ pub const ErrorSet = struct {
356 names_ptr: [*]const []const u8,356 names_ptr: [*]const []const u8,
357};357};
358358
359/// Represents the data that a struct declaration provides.
360pub const Struct = struct {
361 owner_decl: *Decl,
362 /// Set of field names in declaration order.
363 fields: std.StringArrayHashMapUnmanaged(Field),
364 /// Represents the declarations inside this struct.
365 container: Scope.Container,
366
367 /// Offset from Decl node index, points to the struct AST node.
368 node_offset: i32,
369
370 pub const Field = struct {
371 ty: Type,
372 abi_align: Value,
373 /// Uses `unreachable_value` to indicate no default.
374 default_val: Value,
375 };
376};
377
359/// Some Fn struct memory is owned by the Decl's TypedValue.Managed arena allocator.378/// Some Fn struct memory is owned by the Decl's TypedValue.Managed arena allocator.
360/// Extern functions do not have this data structure; they are represented by379/// Extern functions do not have this data structure; they are represented by
361/// the `Decl` only, with a `Value` tag of `extern_fn`.380/// the `Decl` only, with a `Value` tag of `extern_fn`.
...@@ -822,6 +841,7 @@ pub const Scope = struct {...@@ -822,6 +841,7 @@ pub const Scope = struct {
822 try block.instructions.append(block.sema.gpa, &inst.base);841 try block.instructions.append(block.sema.gpa, &inst.base);
823 return &inst.base;842 return &inst.base;
824 }843 }
844
825 pub fn addBr(845 pub fn addBr(
826 scope_block: *Scope.Block,846 scope_block: *Scope.Block,
827 src: LazySrcLoc,847 src: LazySrcLoc,
...@@ -920,6 +940,27 @@ pub const Scope = struct {...@@ -920,6 +940,27 @@ pub const Scope = struct {
920 try block.instructions.append(block.sema.gpa, &inst.base);940 try block.instructions.append(block.sema.gpa, &inst.base);
921 return &inst.base;941 return &inst.base;
922 }942 }
943
944 pub fn addStructFieldPtr(
945 block: *Scope.Block,
946 src: LazySrcLoc,
947 ty: Type,
948 struct_ptr: *ir.Inst,
949 field_index: u32,
950 ) !*ir.Inst {
951 const inst = try block.sema.arena.create(ir.Inst.StructFieldPtr);
952 inst.* = .{
953 .base = .{
954 .tag = .struct_field_ptr,
955 .ty = ty,
956 .src = src,
957 },
958 .struct_ptr = struct_ptr,
959 .field_index = field_index,
960 };
961 try block.instructions.append(block.sema.gpa, &inst.base);
962 return &inst.base;
963 }
923 };964 };
924965
925 /// This is a temporary structure; references to it are valid only966 /// This is a temporary structure; references to it are valid only
src/Sema.zig+118-10
...@@ -261,7 +261,9 @@ pub fn analyzeBody(...@@ -261,7 +261,9 @@ pub fn analyzeBody(
261 .xor => try sema.zirBitwise(block, inst, .xor),261 .xor => try sema.zirBitwise(block, inst, .xor),
262 .struct_init_empty => try sema.zirStructInitEmpty(block, inst),262 .struct_init_empty => try sema.zirStructInitEmpty(block, inst),
263263
264 .struct_decl => try sema.zirStructDecl(block, inst),264 .struct_decl => try sema.zirStructDecl(block, inst, .Auto),
265 .struct_decl_packed => try sema.zirStructDecl(block, inst, .Packed),
266 .struct_decl_extern => try sema.zirStructDecl(block, inst, .Extern),
265 .enum_decl => try sema.zirEnumDecl(block, inst),267 .enum_decl => try sema.zirEnumDecl(block, inst),
266 .union_decl => try sema.zirUnionDecl(block, inst),268 .union_decl => try sema.zirUnionDecl(block, inst),
267 .opaque_decl => try sema.zirOpaqueDecl(block, inst),269 .opaque_decl => try sema.zirOpaqueDecl(block, inst),
...@@ -520,21 +522,98 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) In...@@ -520,21 +522,98 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) In
520 return sema.mod.fail(&block.base, sema.src, "TODO implement zirCoerceResultPtr", .{});522 return sema.mod.fail(&block.base, sema.src, "TODO implement zirCoerceResultPtr", .{});
521}523}
522524
523fn zirStructDecl(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {525fn zirStructDecl(
526 sema: *Sema,
527 block: *Scope.Block,
528 inst: zir.Inst.Index,
529 layout: std.builtin.TypeInfo.ContainerLayout,
530) InnerError!*Inst {
524 const tracy = trace(@src());531 const tracy = trace(@src());
525 defer tracy.end();532 defer tracy.end();
526533
534 const gpa = sema.gpa;
527 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;535 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
528 const src = inst_data.src();536 const src = inst_data.src();
529 const extra = sema.code.extraData(zir.Inst.Block, inst_data.payload_index);537 const extra = sema.code.extraData(zir.Inst.StructDecl, inst_data.payload_index);
538 const fields_len = extra.data.fields_len;
539 const bit_bags_count = std.math.divCeil(usize, fields_len, 16) catch unreachable;
540
541 var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa);
542 errdefer new_decl_arena.deinit();
543
544 var fields_map: std.StringArrayHashMapUnmanaged(Module.Struct.Field) = .{};
545 try fields_map.ensureCapacity(&new_decl_arena.allocator, fields_len);
530546
531 return sema.mod.fail(&block.base, sema.src, "TODO implement zirStructDecl", .{});547 {
548 var field_index: usize = extra.end + bit_bags_count;
549 var bit_bag_index: usize = extra.end;
550 var cur_bit_bag: u32 = undefined;
551 var field_i: u32 = 0;
552 while (field_i < fields_len) : (field_i += 1) {
553 if (field_i % 16 == 0) {
554 cur_bit_bag = sema.code.extra[bit_bag_index];
555 bit_bag_index += 1;
556 }
557 const has_align = @truncate(u1, cur_bit_bag) != 0;
558 cur_bit_bag >>= 1;
559 const has_default = @truncate(u1, cur_bit_bag) != 0;
560 cur_bit_bag >>= 1;
561
562 const field_name_zir = sema.code.nullTerminatedString(sema.code.extra[field_index]);
563 field_index += 1;
564 const field_type_ref = @intToEnum(zir.Inst.Ref, sema.code.extra[field_index]);
565 field_index += 1;
566
567 // This string needs to outlive the ZIR code.
568 const field_name = try new_decl_arena.allocator.dupe(u8, field_name_zir);
569 // TODO: if we need to report an error here, use a source location
570 // that points to this type expression rather than the struct.
571 // But only resolve the source location if we need to emit a compile error.
572 const field_ty = try sema.resolveType(block, src, field_type_ref);
573
574 const gop = fields_map.getOrPutAssumeCapacity(field_name);
575 assert(!gop.found_existing);
576 gop.entry.value = .{
577 .ty = field_ty,
578 .abi_align = Value.initTag(.abi_align_default),
579 .default_val = Value.initTag(.unreachable_value),
580 };
581
582 if (has_align) {
583 const align_ref = @intToEnum(zir.Inst.Ref, sema.code.extra[field_index]);
584 field_index += 1;
585 // TODO: if we need to report an error here, use a source location
586 // that points to this alignment expression rather than the struct.
587 // But only resolve the source location if we need to emit a compile error.
588 gop.entry.value.abi_align = (try sema.resolveInstConst(block, src, align_ref)).val;
589 }
590 if (has_default) {
591 const default_ref = @intToEnum(zir.Inst.Ref, sema.code.extra[field_index]);
592 field_index += 1;
593 // TODO: if we need to report an error here, use a source location
594 // that points to this default value expression rather than the struct.
595 // But only resolve the source location if we need to emit a compile error.
596 gop.entry.value.default_val = (try sema.resolveInstConst(block, src, default_ref)).val;
597 }
598 }
599 }
532600
533 //const new_decl = try sema.mod.createAnonymousDecl(&block.base, &new_decl_arena, .{601 const struct_obj = try new_decl_arena.allocator.create(Module.Struct);
534 // .ty = decl_ty,602 const struct_ty = try Type.Tag.@"struct".create(&new_decl_arena.allocator, struct_obj);
535 // .val = decl_val,603 struct_obj.* = .{
536 //});604 .owner_decl = sema.owner_decl,
537 //return sema.analyzeDeclVal(block, src, new_decl);605 .fields = fields_map,
606 .node_offset = inst_data.src_node,
607 .container = .{
608 .ty = struct_ty,
609 .file_scope = block.getFileScope(),
610 },
611 };
612 const new_decl = try sema.mod.createAnonymousDecl(&block.base, &new_decl_arena, .{
613 .ty = Type.initTag(.type),
614 .val = try Value.Tag.ty.create(gpa, struct_ty),
615 });
616 return sema.analyzeDeclVal(block, src, new_decl);
538}617}
539618
540fn zirEnumDecl(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {619fn zirEnumDecl(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
...@@ -763,7 +842,7 @@ fn zirValidateStructInitPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Ind...@@ -763,7 +842,7 @@ fn zirValidateStructInitPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Ind
763 const extra = sema.code.extraData(zir.Inst.Block, inst_data.payload_index);842 const extra = sema.code.extraData(zir.Inst.Block, inst_data.payload_index);
764 const instrs = sema.code.extra[extra.end..][0..extra.data.body_len];843 const instrs = sema.code.extra[extra.end..][0..extra.data.body_len];
765844
766 return sema.mod.fail(&block.base, src, "TODO implement zirValidateStructInitPtr", .{});845 log.warn("TODO implement zirValidateStructInitPtr (compile errors for missing/dupe fields)", .{});
767}846}
768847
769fn zirStoreToBlockPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!void {848fn zirStoreToBlockPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!void {
...@@ -4141,11 +4220,40 @@ fn namedFieldPtr(...@@ -4141,11 +4220,40 @@ fn namedFieldPtr(
4141 else => return sema.mod.fail(&block.base, src, "type '{}' does not support field access", .{child_type}),4220 else => return sema.mod.fail(&block.base, src, "type '{}' does not support field access", .{child_type}),
4142 }4221 }
4143 },4222 },
4223 .Struct => return sema.analyzeStructFieldPtr(block, src, object_ptr, field_name, field_name_src, elem_ty),
4144 else => {},4224 else => {},
4145 }4225 }
4146 return sema.mod.fail(&block.base, src, "type '{}' does not support field access", .{elem_ty});4226 return sema.mod.fail(&block.base, src, "type '{}' does not support field access", .{elem_ty});
4147}4227}
41484228
4229fn analyzeStructFieldPtr(
4230 sema: *Sema,
4231 block: *Scope.Block,
4232 src: LazySrcLoc,
4233 struct_ptr: *Inst,
4234 field_name: []const u8,
4235 field_name_src: LazySrcLoc,
4236 elem_ty: Type,
4237) InnerError!*Inst {
4238 const mod = sema.mod;
4239 const arena = sema.arena;
4240 assert(elem_ty.zigTypeTag() == .Struct);
4241
4242 const struct_obj = elem_ty.castTag(.@"struct").?.data;
4243
4244 const field_index = struct_obj.fields.getIndex(field_name) orelse {
4245 // TODO note: struct S declared here
4246 return mod.fail(&block.base, field_name_src, "no field named '{s}' in struct '{}'", .{
4247 field_name, elem_ty,
4248 });
4249 };
4250 const field = struct_obj.fields.entries.items[field_index].value;
4251 const ptr_field_ty = try mod.simplePtrType(arena, field.ty, true, .One);
4252 // TODO comptime field access
4253 try sema.requireRuntimeBlock(block, src);
4254 return block.addStructFieldPtr(src, ptr_field_ty, struct_ptr, @intCast(u32, field_index));
4255}
4256
4149fn elemPtr(4257fn elemPtr(
4150 sema: *Sema,4258 sema: *Sema,
4151 block: *Scope.Block,4259 block: *Scope.Block,
src/codegen.zig+5
...@@ -910,6 +910,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -910,6 +910,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
910 .ret => return self.genRet(inst.castTag(.ret).?),910 .ret => return self.genRet(inst.castTag(.ret).?),
911 .retvoid => return self.genRetVoid(inst.castTag(.retvoid).?),911 .retvoid => return self.genRetVoid(inst.castTag(.retvoid).?),
912 .store => return self.genStore(inst.castTag(.store).?),912 .store => return self.genStore(inst.castTag(.store).?),
913 .struct_field_ptr => return self.genStructFieldPtr(inst.castTag(.struct_field_ptr).?),
913 .sub => return self.genSub(inst.castTag(.sub).?),914 .sub => return self.genSub(inst.castTag(.sub).?),
914 .subwrap => return self.genSubWrap(inst.castTag(.subwrap).?),915 .subwrap => return self.genSubWrap(inst.castTag(.subwrap).?),
915 .switchbr => return self.genSwitch(inst.castTag(.switchbr).?),916 .switchbr => return self.genSwitch(inst.castTag(.switchbr).?),
...@@ -1403,6 +1404,10 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -1403,6 +1404,10 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
1403 return .none;1404 return .none;
1404 }1405 }
14051406
1407 fn genStructFieldPtr(self: *Self, inst: *ir.Inst.StructFieldPtr) !MCValue {
1408 return self.fail(inst.base.src, "TODO implement codegen struct_field_ptr", .{});
1409 }
1410
1406 fn genSub(self: *Self, inst: *ir.Inst.BinOp) !MCValue {1411 fn genSub(self: *Self, inst: *ir.Inst.BinOp) !MCValue {
1407 // No side effects, so if it's unreferenced, do nothing.1412 // No side effects, so if it's unreferenced, do nothing.
1408 if (inst.base.isUnused())1413 if (inst.base.isUnused())
src/ir.zig+40
...@@ -137,6 +137,8 @@ pub const Inst = struct {...@@ -137,6 +137,8 @@ pub const Inst = struct {
137 wrap_errunion_err,137 wrap_errunion_err,
138 xor,138 xor,
139 switchbr,139 switchbr,
140 /// Given a pointer to a struct and a field index, returns a pointer to the field.
141 struct_field_ptr,
140142
141 pub fn Type(tag: Tag) type {143 pub fn Type(tag: Tag) type {
142 return switch (tag) {144 return switch (tag) {
...@@ -204,6 +206,7 @@ pub const Inst = struct {...@@ -204,6 +206,7 @@ pub const Inst = struct {
204 .constant => Constant,206 .constant => Constant,
205 .loop => Loop,207 .loop => Loop,
206 .varptr => VarPtr,208 .varptr => VarPtr,
209 .struct_field_ptr => StructFieldPtr,
207 .switchbr => SwitchBr,210 .switchbr => SwitchBr,
208 .dbg_stmt => DbgStmt,211 .dbg_stmt => DbgStmt,
209 };212 };
...@@ -552,6 +555,27 @@ pub const Inst = struct {...@@ -552,6 +555,27 @@ pub const Inst = struct {
552 }555 }
553 };556 };
554557
558 pub const StructFieldPtr = struct {
559 pub const base_tag = Tag.struct_field_ptr;
560
561 base: Inst,
562 struct_ptr: *Inst,
563 field_index: usize,
564
565 pub fn operandCount(self: *const StructFieldPtr) usize {
566 return 1;
567 }
568 pub fn getOperand(self: *const StructFieldPtr, index: usize) ?*Inst {
569 var i = index;
570
571 if (i < 1)
572 return self.struct_ptr;
573 i -= 1;
574
575 return null;
576 }
577 };
578
555 pub const SwitchBr = struct {579 pub const SwitchBr = struct {
556 pub const base_tag = Tag.switchbr;580 pub const base_tag = Tag.switchbr;
557581
...@@ -794,6 +818,10 @@ const DumpTzir = struct {...@@ -794,6 +818,10 @@ const DumpTzir = struct {
794 try dtz.findConst(arg);818 try dtz.findConst(arg);
795 }819 }
796 },820 },
821 .struct_field_ptr => {
822 const struct_field_ptr = inst.castTag(.struct_field_ptr).?;
823 try dtz.findConst(struct_field_ptr.struct_ptr);
824 },
797825
798 // TODO fill out this debug printing826 // TODO fill out this debug printing
799 .assembly,827 .assembly,
...@@ -1067,6 +1095,18 @@ const DumpTzir = struct {...@@ -1067,6 +1095,18 @@ const DumpTzir = struct {
1067 }1095 }
1068 },1096 },
10691097
1098 .struct_field_ptr => {
1099 const struct_field_ptr = inst.castTag(.struct_field_ptr).?;
1100 const kinky = try dtz.writeInst(writer, struct_field_ptr.struct_ptr);
1101 if (kinky != null) {
1102 try writer.print("{d}) // Instruction does not dominate all uses!\n", .{
1103 struct_field_ptr.field_index,
1104 });
1105 } else {
1106 try writer.print("{d})\n", .{struct_field_ptr.field_index});
1107 }
1108 },
1109
1070 // TODO fill out this debug printing1110 // TODO fill out this debug printing
1071 .assembly,1111 .assembly,
1072 .constant,1112 .constant,
src/type.zig+63-2
...@@ -4,6 +4,7 @@ const assert = std.debug.assert;...@@ -4,6 +4,7 @@ const assert = std.debug.assert;
4const Allocator = std.mem.Allocator;4const Allocator = std.mem.Allocator;
5const Target = std.Target;5const Target = std.Target;
6const Module = @import("Module.zig");6const Module = @import("Module.zig");
7const log = std.log.scoped(.Type);
78
8/// This is the raw data, with no bookkeeping, no memory awareness, no de-duplication.9/// This is the raw data, with no bookkeeping, no memory awareness, no de-duplication.
9/// It's important for this type to be small.10/// It's important for this type to be small.
...@@ -94,6 +95,7 @@ pub const Type = extern union {...@@ -94,6 +95,7 @@ pub const Type = extern union {
9495
95 .empty_struct => return .Struct,96 .empty_struct => return .Struct,
96 .empty_struct_literal => return .Struct,97 .empty_struct_literal => return .Struct,
98 .@"struct" => return .Struct,
9799
98 .var_args_param => unreachable, // can be any type100 .var_args_param => unreachable, // can be any type
99 }101 }
...@@ -611,7 +613,7 @@ pub const Type = extern union {...@@ -611,7 +613,7 @@ pub const Type = extern union {
611 .error_set => return self.copyPayloadShallow(allocator, Payload.ErrorSet),613 .error_set => return self.copyPayloadShallow(allocator, Payload.ErrorSet),
612 .error_set_single => return self.copyPayloadShallow(allocator, Payload.Name),614 .error_set_single => return self.copyPayloadShallow(allocator, Payload.Name),
613 .empty_struct => return self.copyPayloadShallow(allocator, Payload.ContainerScope),615 .empty_struct => return self.copyPayloadShallow(allocator, Payload.ContainerScope),
614616 .@"struct" => return self.copyPayloadShallow(allocator, Payload.Struct),
615 .@"opaque" => return self.copyPayloadShallow(allocator, Payload.Opaque),617 .@"opaque" => return self.copyPayloadShallow(allocator, Payload.Opaque),
616 }618 }
617 }619 }
...@@ -675,6 +677,7 @@ pub const Type = extern union {...@@ -675,6 +677,7 @@ pub const Type = extern union {
675 .@"undefined" => return out_stream.writeAll("@Type(.Undefined)"),677 .@"undefined" => return out_stream.writeAll("@Type(.Undefined)"),
676678
677 .empty_struct, .empty_struct_literal => return out_stream.writeAll("struct {}"),679 .empty_struct, .empty_struct_literal => return out_stream.writeAll("struct {}"),
680 .@"struct" => return out_stream.writeAll("(struct)"),
678 .anyerror_void_error_union => return out_stream.writeAll("anyerror!void"),681 .anyerror_void_error_union => return out_stream.writeAll("anyerror!void"),
679 .const_slice_u8 => return out_stream.writeAll("[]const u8"),682 .const_slice_u8 => return out_stream.writeAll("[]const u8"),
680 .fn_noreturn_no_args => return out_stream.writeAll("fn() noreturn"),683 .fn_noreturn_no_args => return out_stream.writeAll("fn() noreturn"),
...@@ -940,6 +943,18 @@ pub const Type = extern union {...@@ -940,6 +943,18 @@ pub const Type = extern union {
940 .error_set,943 .error_set,
941 .error_set_single,944 .error_set_single,
942 => true,945 => true,
946
947 .@"struct" => {
948 // TODO introduce lazy value mechanism
949 const struct_obj = self.castTag(.@"struct").?.data;
950 for (struct_obj.fields.entries.items) |entry| {
951 if (entry.value.ty.hasCodeGenBits())
952 return true;
953 } else {
954 return false;
955 }
956 },
957
943 // TODO lazy types958 // TODO lazy types
944 .array => self.elemType().hasCodeGenBits() and self.arrayLen() != 0,959 .array => self.elemType().hasCodeGenBits() and self.arrayLen() != 0,
945 .array_u8 => self.arrayLen() != 0,960 .array_u8 => self.arrayLen() != 0,
...@@ -1100,6 +1115,10 @@ pub const Type = extern union {...@@ -1100,6 +1115,10 @@ pub const Type = extern union {
1100 @panic("TODO abiAlignment error union");1115 @panic("TODO abiAlignment error union");
1101 },1116 },
11021117
1118 .@"struct" => {
1119 @panic("TODO abiAlignment struct");
1120 },
1121
1103 .c_void,1122 .c_void,
1104 .void,1123 .void,
1105 .type,1124 .type,
...@@ -1144,6 +1163,10 @@ pub const Type = extern union {...@@ -1144,6 +1163,10 @@ pub const Type = extern union {
1144 .@"opaque" => unreachable,1163 .@"opaque" => unreachable,
1145 .var_args_param => unreachable,1164 .var_args_param => unreachable,
11461165
1166 .@"struct" => {
1167 @panic("TODO abiSize struct");
1168 },
1169
1147 .u8,1170 .u8,
1148 .i8,1171 .i8,
1149 .bool,1172 .bool,
...@@ -1316,6 +1339,7 @@ pub const Type = extern union {...@@ -1316,6 +1339,7 @@ pub const Type = extern union {
1316 .anyerror_void_error_union,1339 .anyerror_void_error_union,
1317 .error_set,1340 .error_set,
1318 .error_set_single,1341 .error_set_single,
1342 .@"struct",
1319 .empty_struct,1343 .empty_struct,
1320 .empty_struct_literal,1344 .empty_struct_literal,
1321 .@"opaque",1345 .@"opaque",
...@@ -1393,6 +1417,7 @@ pub const Type = extern union {...@@ -1393,6 +1417,7 @@ pub const Type = extern union {
1393 .empty_struct,1417 .empty_struct,
1394 .empty_struct_literal,1418 .empty_struct_literal,
1395 .@"opaque",1419 .@"opaque",
1420 .@"struct",
1396 .var_args_param,1421 .var_args_param,
1397 => unreachable,1422 => unreachable,
13981423
...@@ -1487,6 +1512,7 @@ pub const Type = extern union {...@@ -1487,6 +1512,7 @@ pub const Type = extern union {
1487 .empty_struct_literal,1512 .empty_struct_literal,
1488 .inferred_alloc_const,1513 .inferred_alloc_const,
1489 .inferred_alloc_mut,1514 .inferred_alloc_mut,
1515 .@"struct",
1490 .@"opaque",1516 .@"opaque",
1491 .var_args_param,1517 .var_args_param,
1492 => false,1518 => false,
...@@ -1564,6 +1590,7 @@ pub const Type = extern union {...@@ -1564,6 +1590,7 @@ pub const Type = extern union {
1564 .empty_struct_literal,1590 .empty_struct_literal,
1565 .inferred_alloc_const,1591 .inferred_alloc_const,
1566 .inferred_alloc_mut,1592 .inferred_alloc_mut,
1593 .@"struct",
1567 .@"opaque",1594 .@"opaque",
1568 .var_args_param,1595 .var_args_param,
1569 => false,1596 => false,
...@@ -1650,6 +1677,7 @@ pub const Type = extern union {...@@ -1650,6 +1677,7 @@ pub const Type = extern union {
1650 .empty_struct_literal,1677 .empty_struct_literal,
1651 .inferred_alloc_const,1678 .inferred_alloc_const,
1652 .inferred_alloc_mut,1679 .inferred_alloc_mut,
1680 .@"struct",
1653 .@"opaque",1681 .@"opaque",
1654 .var_args_param,1682 .var_args_param,
1655 => false,1683 => false,
...@@ -1731,6 +1759,7 @@ pub const Type = extern union {...@@ -1731,6 +1759,7 @@ pub const Type = extern union {
1731 .empty_struct_literal,1759 .empty_struct_literal,
1732 .inferred_alloc_const,1760 .inferred_alloc_const,
1733 .inferred_alloc_mut,1761 .inferred_alloc_mut,
1762 .@"struct",
1734 .@"opaque",1763 .@"opaque",
1735 .var_args_param,1764 .var_args_param,
1736 => false,1765 => false,
...@@ -1792,7 +1821,11 @@ pub const Type = extern union {...@@ -1792,7 +1821,11 @@ pub const Type = extern union {
1792 .ErrorUnion => ty = ty.errorUnionChild(),1821 .ErrorUnion => ty = ty.errorUnionChild(),
17931822
1794 .Fn => @panic("TODO fn isValidVarType"),1823 .Fn => @panic("TODO fn isValidVarType"),
1795 .Struct => @panic("TODO struct isValidVarType"),1824 .Struct => {
1825 // TODO this is not always correct; introduce lazy value mechanism
1826 // and here we need to force a resolve of "type requires comptime".
1827 return true;
1828 },
1796 .Union => @panic("TODO union isValidVarType"),1829 .Union => @panic("TODO union isValidVarType"),
1797 };1830 };
1798 }1831 }
...@@ -1850,6 +1883,7 @@ pub const Type = extern union {...@@ -1850,6 +1883,7 @@ pub const Type = extern union {
1850 .anyerror_void_error_union => unreachable,1883 .anyerror_void_error_union => unreachable,
1851 .error_set => unreachable,1884 .error_set => unreachable,
1852 .error_set_single => unreachable,1885 .error_set_single => unreachable,
1886 .@"struct" => unreachable,
1853 .empty_struct => unreachable,1887 .empty_struct => unreachable,
1854 .empty_struct_literal => unreachable,1888 .empty_struct_literal => unreachable,
1855 .inferred_alloc_const => unreachable,1889 .inferred_alloc_const => unreachable,
...@@ -1999,6 +2033,7 @@ pub const Type = extern union {...@@ -1999,6 +2033,7 @@ pub const Type = extern union {
1999 .anyerror_void_error_union,2033 .anyerror_void_error_union,
2000 .error_set,2034 .error_set,
2001 .error_set_single,2035 .error_set_single,
2036 .@"struct",
2002 .empty_struct,2037 .empty_struct,
2003 .empty_struct_literal,2038 .empty_struct_literal,
2004 .inferred_alloc_const,2039 .inferred_alloc_const,
...@@ -2070,6 +2105,7 @@ pub const Type = extern union {...@@ -2070,6 +2105,7 @@ pub const Type = extern union {
2070 .anyerror_void_error_union,2105 .anyerror_void_error_union,
2071 .error_set,2106 .error_set,
2072 .error_set_single,2107 .error_set_single,
2108 .@"struct",
2073 .empty_struct,2109 .empty_struct,
2074 .empty_struct_literal,2110 .empty_struct_literal,
2075 .inferred_alloc_const,2111 .inferred_alloc_const,
...@@ -2156,6 +2192,7 @@ pub const Type = extern union {...@@ -2156,6 +2192,7 @@ pub const Type = extern union {
2156 .anyerror_void_error_union,2192 .anyerror_void_error_union,
2157 .error_set,2193 .error_set,
2158 .error_set_single,2194 .error_set_single,
2195 .@"struct",
2159 .empty_struct,2196 .empty_struct,
2160 .empty_struct_literal,2197 .empty_struct_literal,
2161 .inferred_alloc_const,2198 .inferred_alloc_const,
...@@ -2238,6 +2275,7 @@ pub const Type = extern union {...@@ -2238,6 +2275,7 @@ pub const Type = extern union {
2238 .anyerror_void_error_union,2275 .anyerror_void_error_union,
2239 .error_set,2276 .error_set,
2240 .error_set_single,2277 .error_set_single,
2278 .@"struct",
2241 .empty_struct,2279 .empty_struct,
2242 .empty_struct_literal,2280 .empty_struct_literal,
2243 .inferred_alloc_const,2281 .inferred_alloc_const,
...@@ -2306,6 +2344,7 @@ pub const Type = extern union {...@@ -2306,6 +2344,7 @@ pub const Type = extern union {
2306 .anyerror_void_error_union,2344 .anyerror_void_error_union,
2307 .error_set,2345 .error_set,
2308 .error_set_single,2346 .error_set_single,
2347 .@"struct",
2309 .empty_struct,2348 .empty_struct,
2310 .empty_struct_literal,2349 .empty_struct_literal,
2311 .inferred_alloc_const,2350 .inferred_alloc_const,
...@@ -2402,6 +2441,7 @@ pub const Type = extern union {...@@ -2402,6 +2441,7 @@ pub const Type = extern union {
2402 .anyerror_void_error_union,2441 .anyerror_void_error_union,
2403 .error_set,2442 .error_set,
2404 .error_set_single,2443 .error_set_single,
2444 .@"struct",
2405 .empty_struct,2445 .empty_struct,
2406 .empty_struct_literal,2446 .empty_struct_literal,
2407 .inferred_alloc_const,2447 .inferred_alloc_const,
...@@ -2519,6 +2559,7 @@ pub const Type = extern union {...@@ -2519,6 +2559,7 @@ pub const Type = extern union {
2519 .anyerror_void_error_union,2559 .anyerror_void_error_union,
2520 .error_set,2560 .error_set,
2521 .error_set_single,2561 .error_set_single,
2562 .@"struct",
2522 .empty_struct,2563 .empty_struct,
2523 .empty_struct_literal,2564 .empty_struct_literal,
2524 .inferred_alloc_const,2565 .inferred_alloc_const,
...@@ -2602,6 +2643,7 @@ pub const Type = extern union {...@@ -2602,6 +2643,7 @@ pub const Type = extern union {
2602 .anyerror_void_error_union,2643 .anyerror_void_error_union,
2603 .error_set,2644 .error_set,
2604 .error_set_single,2645 .error_set_single,
2646 .@"struct",
2605 .empty_struct,2647 .empty_struct,
2606 .empty_struct_literal,2648 .empty_struct_literal,
2607 .inferred_alloc_const,2649 .inferred_alloc_const,
...@@ -2684,6 +2726,7 @@ pub const Type = extern union {...@@ -2684,6 +2726,7 @@ pub const Type = extern union {
2684 .anyerror_void_error_union,2726 .anyerror_void_error_union,
2685 .error_set,2727 .error_set,
2686 .error_set_single,2728 .error_set_single,
2729 .@"struct",
2687 .empty_struct,2730 .empty_struct,
2688 .empty_struct_literal,2731 .empty_struct_literal,
2689 .inferred_alloc_const,2732 .inferred_alloc_const,
...@@ -2766,6 +2809,7 @@ pub const Type = extern union {...@@ -2766,6 +2809,7 @@ pub const Type = extern union {
2766 .anyerror_void_error_union,2809 .anyerror_void_error_union,
2767 .error_set,2810 .error_set,
2768 .error_set_single,2811 .error_set_single,
2812 .@"struct",
2769 .empty_struct,2813 .empty_struct,
2770 .empty_struct_literal,2814 .empty_struct_literal,
2771 .inferred_alloc_const,2815 .inferred_alloc_const,
...@@ -2845,6 +2889,7 @@ pub const Type = extern union {...@@ -2845,6 +2889,7 @@ pub const Type = extern union {
2845 .anyerror_void_error_union,2889 .anyerror_void_error_union,
2846 .error_set,2890 .error_set,
2847 .error_set_single,2891 .error_set_single,
2892 .@"struct",
2848 .empty_struct,2893 .empty_struct,
2849 .empty_struct_literal,2894 .empty_struct_literal,
2850 .inferred_alloc_const,2895 .inferred_alloc_const,
...@@ -2924,6 +2969,7 @@ pub const Type = extern union {...@@ -2924,6 +2969,7 @@ pub const Type = extern union {
2924 .anyerror_void_error_union,2969 .anyerror_void_error_union,
2925 .error_set,2970 .error_set,
2926 .error_set_single,2971 .error_set_single,
2972 .@"struct",
2927 .empty_struct,2973 .empty_struct,
2928 .empty_struct_literal,2974 .empty_struct_literal,
2929 .inferred_alloc_const,2975 .inferred_alloc_const,
...@@ -3003,6 +3049,7 @@ pub const Type = extern union {...@@ -3003,6 +3049,7 @@ pub const Type = extern union {
3003 .anyerror_void_error_union,3049 .anyerror_void_error_union,
3004 .error_set,3050 .error_set,
3005 .error_set_single,3051 .error_set_single,
3052 .@"struct",
3006 .empty_struct,3053 .empty_struct,
3007 .empty_struct_literal,3054 .empty_struct_literal,
3008 .inferred_alloc_const,3055 .inferred_alloc_const,
...@@ -3070,6 +3117,11 @@ pub const Type = extern union {...@@ -3070,6 +3117,11 @@ pub const Type = extern union {
3070 .var_args_param,3117 .var_args_param,
3071 => return null,3118 => return null,
30723119
3120 .@"struct" => {
3121 log.warn("TODO implement Type.onePossibleValue for structs", .{});
3122 return null;
3123 },
3124
3073 .empty_struct, .empty_struct_literal => return Value.initTag(.empty_struct_value),3125 .empty_struct, .empty_struct_literal => return Value.initTag(.empty_struct_value),
3074 .void => return Value.initTag(.void_value),3126 .void => return Value.initTag(.void_value),
3075 .noreturn => return Value.initTag(.unreachable_value),3127 .noreturn => return Value.initTag(.unreachable_value),
...@@ -3172,6 +3224,7 @@ pub const Type = extern union {...@@ -3172,6 +3224,7 @@ pub const Type = extern union {
3172 .anyerror_void_error_union,3224 .anyerror_void_error_union,
3173 .error_set,3225 .error_set,
3174 .error_set_single,3226 .error_set_single,
3227 .@"struct",
3175 .empty_struct,3228 .empty_struct,
3176 .empty_struct_literal,3229 .empty_struct_literal,
3177 .inferred_alloc_const,3230 .inferred_alloc_const,
...@@ -3269,6 +3322,7 @@ pub const Type = extern union {...@@ -3269,6 +3322,7 @@ pub const Type = extern union {
3269 .empty_struct_literal,3322 .empty_struct_literal,
3270 => unreachable,3323 => unreachable,
32713324
3325 .@"struct" => &self.castTag(.@"struct").?.data.container,
3272 .empty_struct => self.castTag(.empty_struct).?.data,3326 .empty_struct => self.castTag(.empty_struct).?.data,
3273 .@"opaque" => &self.castTag(.@"opaque").?.data,3327 .@"opaque" => &self.castTag(.@"opaque").?.data,
3274 };3328 };
...@@ -3421,6 +3475,7 @@ pub const Type = extern union {...@@ -3421,6 +3475,7 @@ pub const Type = extern union {
3421 error_set_single,3475 error_set_single,
3422 empty_struct,3476 empty_struct,
3423 @"opaque",3477 @"opaque",
3478 @"struct",
34243479
3425 pub const last_no_payload_tag = Tag.inferred_alloc_const;3480 pub const last_no_payload_tag = Tag.inferred_alloc_const;
3426 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;3481 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
...@@ -3506,6 +3561,7 @@ pub const Type = extern union {...@@ -3506,6 +3561,7 @@ pub const Type = extern union {
3506 .error_union => Payload.ErrorUnion,3561 .error_union => Payload.ErrorUnion,
3507 .error_set_single => Payload.Name,3562 .error_set_single => Payload.Name,
3508 .@"opaque" => Payload.Opaque,3563 .@"opaque" => Payload.Opaque,
3564 .@"struct" => Payload.Struct,
3509 .empty_struct => Payload.ContainerScope,3565 .empty_struct => Payload.ContainerScope,
3510 };3566 };
3511 }3567 }
...@@ -3638,6 +3694,11 @@ pub const Type = extern union {...@@ -3638,6 +3694,11 @@ pub const Type = extern union {
3638 base: Payload = .{ .tag = .@"opaque" },3694 base: Payload = .{ .tag = .@"opaque" },
3639 data: Module.Scope.Container,3695 data: Module.Scope.Container,
3640 };3696 };
3697
3698 pub const Struct = struct {
3699 base: Payload = .{ .tag = .@"struct" },
3700 data: *Module.Struct,
3701 };
3641 };3702 };
3642};3703};
36433704
src/value.zig+18-1
...@@ -74,6 +74,7 @@ pub const Value = extern union {...@@ -74,6 +74,7 @@ pub const Value = extern union {
74 bool_true,74 bool_true,
75 bool_false,75 bool_false,
7676
77 abi_align_default,
77 empty_struct_value,78 empty_struct_value,
78 empty_array, // See last_no_payload_tag below.79 empty_array, // See last_no_payload_tag below.
79 // After this, the tag requires a payload.80 // After this, the tag requires a payload.
...@@ -165,6 +166,7 @@ pub const Value = extern union {...@@ -165,6 +166,7 @@ pub const Value = extern union {
165 .null_value,166 .null_value,
166 .bool_true,167 .bool_true,
167 .bool_false,168 .bool_false,
169 .abi_align_default,
168 => @compileError("Value Tag " ++ @tagName(t) ++ " has no payload"),170 => @compileError("Value Tag " ++ @tagName(t) ++ " has no payload"),
169171
170 .int_big_positive,172 .int_big_positive,
...@@ -320,6 +322,7 @@ pub const Value = extern union {...@@ -320,6 +322,7 @@ pub const Value = extern union {
320 .bool_true,322 .bool_true,
321 .bool_false,323 .bool_false,
322 .empty_struct_value,324 .empty_struct_value,
325 .abi_align_default,
323 => unreachable,326 => unreachable,
324327
325 .ty => {328 .ty => {
...@@ -464,8 +467,8 @@ pub const Value = extern union {...@@ -464,8 +467,8 @@ pub const Value = extern union {
464 .single_const_pointer_to_comptime_int_type => return out_stream.writeAll("*const comptime_int"),467 .single_const_pointer_to_comptime_int_type => return out_stream.writeAll("*const comptime_int"),
465 .const_slice_u8_type => return out_stream.writeAll("[]const u8"),468 .const_slice_u8_type => return out_stream.writeAll("[]const u8"),
466 .enum_literal_type => return out_stream.writeAll("@Type(.EnumLiteral)"),469 .enum_literal_type => return out_stream.writeAll("@Type(.EnumLiteral)"),
470 .abi_align_default => return out_stream.writeAll("(default ABI alignment)"),
467471
468 // TODO this should print `NAME{}`
469 .empty_struct_value => return out_stream.writeAll("struct {}{}"),472 .empty_struct_value => return out_stream.writeAll("struct {}{}"),
470 .null_value => return out_stream.writeAll("null"),473 .null_value => return out_stream.writeAll("null"),
471 .undef => return out_stream.writeAll("undefined"),474 .undef => return out_stream.writeAll("undefined"),
...@@ -627,6 +630,7 @@ pub const Value = extern union {...@@ -627,6 +630,7 @@ pub const Value = extern union {
627 .error_union,630 .error_union,
628 .empty_struct_value,631 .empty_struct_value,
629 .inferred_alloc,632 .inferred_alloc,
633 .abi_align_default,
630 => unreachable,634 => unreachable,
631 };635 };
632 }636 }
...@@ -699,6 +703,7 @@ pub const Value = extern union {...@@ -699,6 +703,7 @@ pub const Value = extern union {
699 .@"error",703 .@"error",
700 .empty_struct_value,704 .empty_struct_value,
701 .inferred_alloc,705 .inferred_alloc,
706 .abi_align_default,
702 => unreachable,707 => unreachable,
703708
704 .undef => unreachable,709 .undef => unreachable,
...@@ -786,6 +791,7 @@ pub const Value = extern union {...@@ -786,6 +791,7 @@ pub const Value = extern union {
786 .error_union,791 .error_union,
787 .empty_struct_value,792 .empty_struct_value,
788 .inferred_alloc,793 .inferred_alloc,
794 .abi_align_default,
789 => unreachable,795 => unreachable,
790796
791 .undef => unreachable,797 .undef => unreachable,
...@@ -873,6 +879,7 @@ pub const Value = extern union {...@@ -873,6 +879,7 @@ pub const Value = extern union {
873 .error_union,879 .error_union,
874 .empty_struct_value,880 .empty_struct_value,
875 .inferred_alloc,881 .inferred_alloc,
882 .abi_align_default,
876 => unreachable,883 => unreachable,
877884
878 .undef => unreachable,885 .undef => unreachable,
...@@ -988,6 +995,7 @@ pub const Value = extern union {...@@ -988,6 +995,7 @@ pub const Value = extern union {
988 .error_union,995 .error_union,
989 .empty_struct_value,996 .empty_struct_value,
990 .inferred_alloc,997 .inferred_alloc,
998 .abi_align_default,
991 => unreachable,999 => unreachable,
9921000
993 .zero,1001 .zero,
...@@ -1079,6 +1087,7 @@ pub const Value = extern union {...@@ -1079,6 +1087,7 @@ pub const Value = extern union {
1079 .error_union,1087 .error_union,
1080 .empty_struct_value,1088 .empty_struct_value,
1081 .inferred_alloc,1089 .inferred_alloc,
1090 .abi_align_default,
1082 => unreachable,1091 => unreachable,
10831092
1084 .zero,1093 .zero,
...@@ -1239,6 +1248,7 @@ pub const Value = extern union {...@@ -1239,6 +1248,7 @@ pub const Value = extern union {
1239 .error_union,1248 .error_union,
1240 .empty_struct_value,1249 .empty_struct_value,
1241 .inferred_alloc,1250 .inferred_alloc,
1251 .abi_align_default,
1242 => unreachable,1252 => unreachable,
12431253
1244 .zero,1254 .zero,
...@@ -1317,6 +1327,7 @@ pub const Value = extern union {...@@ -1317,6 +1327,7 @@ pub const Value = extern union {
1317 .error_union,1327 .error_union,
1318 .empty_struct_value,1328 .empty_struct_value,
1319 .inferred_alloc,1329 .inferred_alloc,
1330 .abi_align_default,
1320 => unreachable,1331 => unreachable,
13211332
1322 .zero,1333 .zero,
...@@ -1452,6 +1463,7 @@ pub const Value = extern union {...@@ -1452,6 +1463,7 @@ pub const Value = extern union {
1452 .const_slice_u8_type,1463 .const_slice_u8_type,
1453 .enum_literal_type,1464 .enum_literal_type,
1454 .ty,1465 .ty,
1466 .abi_align_default,
1455 => {1467 => {
1456 // Directly return Type.hash, toType can only fail for .int_type.1468 // Directly return Type.hash, toType can only fail for .int_type.
1457 var allocator = std.heap.FixedBufferAllocator.init(&[_]u8{});1469 var allocator = std.heap.FixedBufferAllocator.init(&[_]u8{});
...@@ -1632,6 +1644,7 @@ pub const Value = extern union {...@@ -1632,6 +1644,7 @@ pub const Value = extern union {
1632 .error_union,1644 .error_union,
1633 .empty_struct_value,1645 .empty_struct_value,
1634 .inferred_alloc,1646 .inferred_alloc,
1647 .abi_align_default,
1635 => unreachable,1648 => unreachable,
16361649
1637 .ref_val => self.castTag(.ref_val).?.data,1650 .ref_val => self.castTag(.ref_val).?.data,
...@@ -1719,6 +1732,7 @@ pub const Value = extern union {...@@ -1719,6 +1732,7 @@ pub const Value = extern union {
1719 .error_union,1732 .error_union,
1720 .empty_struct_value,1733 .empty_struct_value,
1721 .inferred_alloc,1734 .inferred_alloc,
1735 .abi_align_default,
1722 => unreachable,1736 => unreachable,
17231737
1724 .empty_array => unreachable, // out of bounds array index1738 .empty_array => unreachable, // out of bounds array index
...@@ -1822,6 +1836,7 @@ pub const Value = extern union {...@@ -1822,6 +1836,7 @@ pub const Value = extern union {
1822 .@"error",1836 .@"error",
1823 .error_union,1837 .error_union,
1824 .empty_struct_value,1838 .empty_struct_value,
1839 .abi_align_default,
1825 => false,1840 => false,
18261841
1827 .undef => unreachable,1842 .undef => unreachable,
...@@ -1903,6 +1918,7 @@ pub const Value = extern union {...@@ -1903,6 +1918,7 @@ pub const Value = extern union {
1903 .void_value,1918 .void_value,
1904 .enum_literal,1919 .enum_literal,
1905 .empty_struct_value,1920 .empty_struct_value,
1921 .abi_align_default,
1906 => null,1922 => null,
19071923
1908 .error_union => {1924 .error_union => {
...@@ -2009,6 +2025,7 @@ pub const Value = extern union {...@@ -2009,6 +2025,7 @@ pub const Value = extern union {
2009 .error_union,2025 .error_union,
2010 .empty_struct_value,2026 .empty_struct_value,
2011 .null_value,2027 .null_value,
2028 .abi_align_default,
2012 => false,2029 => false,
20132030
2014 .undef => unreachable,2031 .undef => unreachable,
src/zir.zig+10-1
...@@ -274,6 +274,10 @@ pub const Inst = struct {...@@ -274,6 +274,10 @@ pub const Inst = struct {
274 /// the field types, defaults, and alignments.274 /// the field types, defaults, and alignments.
275 /// Uses the `pl_node` union field. Payload is `StructDecl`.275 /// Uses the `pl_node` union field. Payload is `StructDecl`.
276 struct_decl,276 struct_decl,
277 /// Same as `struct_decl`, except has the `packed` layout.
278 struct_decl_packed,
279 /// Same as `struct_decl`, except has the `extern` layout.
280 struct_decl_extern,
277 /// A union type definition. Contains references to ZIR instructions for281 /// A union type definition. Contains references to ZIR instructions for
278 /// the field types and optional type tag expression.282 /// the field types and optional type tag expression.
279 /// Uses the `pl_node` union field. Payload is `UnionDecl`.283 /// Uses the `pl_node` union field. Payload is `UnionDecl`.
...@@ -707,6 +711,8 @@ pub const Inst = struct {...@@ -707,6 +711,8 @@ pub const Inst = struct {
707 .coerce_result_ptr,711 .coerce_result_ptr,
708 .@"const",712 .@"const",
709 .struct_decl,713 .struct_decl,
714 .struct_decl_packed,
715 .struct_decl_extern,
710 .union_decl,716 .union_decl,
711 .enum_decl,717 .enum_decl,
712 .opaque_decl,718 .opaque_decl,
...@@ -1655,7 +1661,10 @@ const Writer = struct {...@@ -1655,7 +1661,10 @@ const Writer = struct {
1655 .condbr_inline,1661 .condbr_inline,
1656 => try self.writePlNodeCondBr(stream, inst),1662 => try self.writePlNodeCondBr(stream, inst),
16571663
1658 .struct_decl => try self.writeStructDecl(stream, inst),1664 .struct_decl,
1665 .struct_decl_packed,
1666 .struct_decl_extern,
1667 => try self.writeStructDecl(stream, inst),
16591668
1660 .switch_block => try self.writePlNodeSwitchBr(stream, inst, .none),1669 .switch_block => try self.writePlNodeSwitchBr(stream, inst, .none),
1661 .switch_block_else => try self.writePlNodeSwitchBr(stream, inst, .@"else"),1670 .switch_block_else => try self.writePlNodeSwitchBr(stream, inst, .@"else"),