authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-06-03 21:53:13-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-06-08 15:16:40-04:00
logcf654b52d68f20a403965e70371a9ad193370d8c
treeead20daa8c4bcf8d4f269707fa24448df0cd1e1a
parentd4d954abd20d57ff62940993f5b95700ebfbbda7

stage2: -femit-zir respects decl names and supports cycles


5 files changed, 330 insertions(+), 153 deletions(-)

src-self-hosted/Module.zig+23-1
...@@ -1097,6 +1097,9 @@ fn resolveDecl(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*De...@@ -1097,6 +1097,9 @@ fn resolveDecl(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*De
1097 const decl = kv.value;1097 const decl = kv.value;
1098 try self.reAnalyzeDecl(decl, old_inst);1098 try self.reAnalyzeDecl(decl, old_inst);
1099 return decl;1099 return decl;
1100 } else if (old_inst.cast(zir.Inst.DeclVal)) |decl_val| {
1101 // This is just a named reference to another decl.
1102 return self.analyzeDeclVal(scope, decl_val);
1100 } else {1103 } else {
1101 const new_decl = blk: {1104 const new_decl = blk: {
1102 try self.decl_table.ensureCapacity(self.decl_table.size + 1);1105 try self.decl_table.ensureCapacity(self.decl_table.size + 1);
...@@ -1443,6 +1446,7 @@ fn analyzeInst(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*In...@@ -1443,6 +1446,7 @@ fn analyzeInst(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*In
1443 .breakpoint => return self.analyzeInstBreakpoint(scope, old_inst.cast(zir.Inst.Breakpoint).?),1446 .breakpoint => return self.analyzeInstBreakpoint(scope, old_inst.cast(zir.Inst.Breakpoint).?),
1444 .call => return self.analyzeInstCall(scope, old_inst.cast(zir.Inst.Call).?),1447 .call => return self.analyzeInstCall(scope, old_inst.cast(zir.Inst.Call).?),
1445 .declref => return self.analyzeInstDeclRef(scope, old_inst.cast(zir.Inst.DeclRef).?),1448 .declref => return self.analyzeInstDeclRef(scope, old_inst.cast(zir.Inst.DeclRef).?),
1449 .declval => return self.analyzeInstDeclVal(scope, old_inst.cast(zir.Inst.DeclVal).?),
1446 .str => {1450 .str => {
1447 const bytes = old_inst.cast(zir.Inst.Str).?.positionals.bytes;1451 const bytes = old_inst.cast(zir.Inst.Str).?.positionals.bytes;
1448 // The bytes references memory inside the ZIR module, which can get deallocated1452 // The bytes references memory inside the ZIR module, which can get deallocated
...@@ -1501,6 +1505,24 @@ fn analyzeInstDeclRef(self: *Module, scope: *Scope, inst: *zir.Inst.DeclRef) Inn...@@ -1501,6 +1505,24 @@ fn analyzeInstDeclRef(self: *Module, scope: *Scope, inst: *zir.Inst.DeclRef) Inn
1501 return self.analyzeDeclRef(scope, inst.base.src, decl);1505 return self.analyzeDeclRef(scope, inst.base.src, decl);
1502}1506}
15031507
1508fn analyzeDeclVal(self: *Module, scope: *Scope, inst: *zir.Inst.DeclVal) InnerError!*Decl {
1509 const decl_name = inst.positionals.name;
1510 // This will need to get more fleshed out when there are proper structs & namespaces.
1511 const zir_module = scope.namespace();
1512 const src_decl = zir_module.contents.module.findDecl(decl_name) orelse
1513 return self.fail(scope, inst.base.src, "use of undeclared identifier '{}'", .{decl_name});
1514
1515 const decl = try self.resolveCompleteDecl(scope, src_decl);
1516
1517 return decl;
1518}
1519
1520fn analyzeInstDeclVal(self: *Module, scope: *Scope, inst: *zir.Inst.DeclVal) InnerError!*Inst {
1521 const decl = try self.analyzeDeclVal(scope, inst);
1522 const ptr = try self.analyzeDeclRef(scope, inst.base.src, decl);
1523 return self.analyzeDeref(scope, inst.base.src, ptr, inst.base.src);
1524}
1525
1504fn analyzeDeclRef(self: *Module, scope: *Scope, src: usize, decl: *Decl) InnerError!*Inst {1526fn analyzeDeclRef(self: *Module, scope: *Scope, src: usize, decl: *Decl) InnerError!*Inst {
1505 const decl_tv = try decl.typedValue();1527 const decl_tv = try decl.typedValue();
1506 const ty_payload = try scope.arena().create(Type.Payload.SingleConstPointer);1528 const ty_payload = try scope.arena().create(Type.Payload.SingleConstPointer);
...@@ -1621,7 +1643,7 @@ fn analyzeInstFnType(self: *Module, scope: *Scope, fntype: *zir.Inst.FnType) Inn...@@ -1621,7 +1643,7 @@ fn analyzeInstFnType(self: *Module, scope: *Scope, fntype: *zir.Inst.FnType) Inn
1621}1643}
16221644
1623fn analyzeInstPrimitive(self: *Module, scope: *Scope, primitive: *zir.Inst.Primitive) InnerError!*Inst {1645fn analyzeInstPrimitive(self: *Module, scope: *Scope, primitive: *zir.Inst.Primitive) InnerError!*Inst {
1624 return self.constType(scope, primitive.base.src, primitive.positionals.tag.toType());1646 return self.constInst(scope, primitive.base.src, primitive.positionals.tag.toTypedValue());
1625}1647}
16261648
1627fn analyzeInstAs(self: *Module, scope: *Scope, as: *zir.Inst.As) InnerError!*Inst {1649fn analyzeInstAs(self: *Module, scope: *Scope, as: *zir.Inst.As) InnerError!*Inst {
src-self-hosted/type.zig+22
...@@ -51,6 +51,7 @@ pub const Type = extern union {...@@ -51,6 +51,7 @@ pub const Type = extern union {
51 .comptime_float => return .ComptimeFloat,51 .comptime_float => return .ComptimeFloat,
52 .noreturn => return .NoReturn,52 .noreturn => return .NoReturn,
53 .@"null" => return .Null,53 .@"null" => return .Null,
54 .@"undefined" => return .Undefined,
5455
55 .fn_noreturn_no_args => return .Fn,56 .fn_noreturn_no_args => return .Fn,
56 .fn_naked_noreturn_no_args => return .Fn,57 .fn_naked_noreturn_no_args => return .Fn,
...@@ -201,6 +202,7 @@ pub const Type = extern union {...@@ -201,6 +202,7 @@ pub const Type = extern union {
201 => return out_stream.writeAll(@tagName(t)),202 => return out_stream.writeAll(@tagName(t)),
202203
203 .@"null" => return out_stream.writeAll("@TypeOf(null)"),204 .@"null" => return out_stream.writeAll("@TypeOf(null)"),
205 .@"undefined" => return out_stream.writeAll("@TypeOf(undefined)"),
204206
205 .const_slice_u8 => return out_stream.writeAll("[]const u8"),207 .const_slice_u8 => return out_stream.writeAll("[]const u8"),
206 .fn_noreturn_no_args => return out_stream.writeAll("fn() noreturn"),208 .fn_noreturn_no_args => return out_stream.writeAll("fn() noreturn"),
...@@ -265,6 +267,7 @@ pub const Type = extern union {...@@ -265,6 +267,7 @@ pub const Type = extern union {
265 .comptime_float => return Value.initTag(.comptime_float_type),267 .comptime_float => return Value.initTag(.comptime_float_type),
266 .noreturn => return Value.initTag(.noreturn_type),268 .noreturn => return Value.initTag(.noreturn_type),
267 .@"null" => return Value.initTag(.null_type),269 .@"null" => return Value.initTag(.null_type),
270 .@"undefined" => return Value.initTag(.undefined_type),
268 .fn_noreturn_no_args => return Value.initTag(.fn_noreturn_no_args_type),271 .fn_noreturn_no_args => return Value.initTag(.fn_noreturn_no_args_type),
269 .fn_naked_noreturn_no_args => return Value.initTag(.fn_naked_noreturn_no_args_type),272 .fn_naked_noreturn_no_args => return Value.initTag(.fn_naked_noreturn_no_args_type),
270 .fn_ccc_void_no_args => return Value.initTag(.fn_ccc_void_no_args_type),273 .fn_ccc_void_no_args => return Value.initTag(.fn_ccc_void_no_args_type),
...@@ -318,6 +321,7 @@ pub const Type = extern union {...@@ -318,6 +321,7 @@ pub const Type = extern union {
318 .comptime_float,321 .comptime_float,
319 .noreturn,322 .noreturn,
320 .@"null",323 .@"null",
324 .@"undefined",
321 => false,325 => false,
322 };326 };
323 }327 }
...@@ -378,6 +382,7 @@ pub const Type = extern union {...@@ -378,6 +382,7 @@ pub const Type = extern union {
378 .comptime_float,382 .comptime_float,
379 .noreturn,383 .noreturn,
380 .@"null",384 .@"null",
385 .@"undefined",
381 => unreachable,386 => unreachable,
382 };387 };
383 }388 }
...@@ -410,6 +415,7 @@ pub const Type = extern union {...@@ -410,6 +415,7 @@ pub const Type = extern union {
410 .comptime_float,415 .comptime_float,
411 .noreturn,416 .noreturn,
412 .@"null",417 .@"null",
418 .@"undefined",
413 .array,419 .array,
414 .array_u8_sentinel_0,420 .array_u8_sentinel_0,
415 .const_slice_u8,421 .const_slice_u8,
...@@ -454,6 +460,7 @@ pub const Type = extern union {...@@ -454,6 +460,7 @@ pub const Type = extern union {
454 .comptime_float,460 .comptime_float,
455 .noreturn,461 .noreturn,
456 .@"null",462 .@"null",
463 .@"undefined",
457 .array,464 .array,
458 .array_u8_sentinel_0,465 .array_u8_sentinel_0,
459 .single_const_pointer,466 .single_const_pointer,
...@@ -498,6 +505,7 @@ pub const Type = extern union {...@@ -498,6 +505,7 @@ pub const Type = extern union {
498 .comptime_float,505 .comptime_float,
499 .noreturn,506 .noreturn,
500 .@"null",507 .@"null",
508 .@"undefined",
501 .array,509 .array,
502 .array_u8_sentinel_0,510 .array_u8_sentinel_0,
503 .fn_noreturn_no_args,511 .fn_noreturn_no_args,
...@@ -543,6 +551,7 @@ pub const Type = extern union {...@@ -543,6 +551,7 @@ pub const Type = extern union {
543 .comptime_float,551 .comptime_float,
544 .noreturn,552 .noreturn,
545 .@"null",553 .@"null",
554 .@"undefined",
546 .fn_noreturn_no_args,555 .fn_noreturn_no_args,
547 .fn_naked_noreturn_no_args,556 .fn_naked_noreturn_no_args,
548 .fn_ccc_void_no_args,557 .fn_ccc_void_no_args,
...@@ -586,6 +595,7 @@ pub const Type = extern union {...@@ -586,6 +595,7 @@ pub const Type = extern union {
586 .comptime_float,595 .comptime_float,
587 .noreturn,596 .noreturn,
588 .@"null",597 .@"null",
598 .@"undefined",
589 .fn_noreturn_no_args,599 .fn_noreturn_no_args,
590 .fn_naked_noreturn_no_args,600 .fn_naked_noreturn_no_args,
591 .fn_ccc_void_no_args,601 .fn_ccc_void_no_args,
...@@ -630,6 +640,7 @@ pub const Type = extern union {...@@ -630,6 +640,7 @@ pub const Type = extern union {
630 .comptime_float,640 .comptime_float,
631 .noreturn,641 .noreturn,
632 .@"null",642 .@"null",
643 .@"undefined",
633 .fn_noreturn_no_args,644 .fn_noreturn_no_args,
634 .fn_naked_noreturn_no_args,645 .fn_naked_noreturn_no_args,
635 .fn_ccc_void_no_args,646 .fn_ccc_void_no_args,
...@@ -662,6 +673,7 @@ pub const Type = extern union {...@@ -662,6 +673,7 @@ pub const Type = extern union {
662 .comptime_float,673 .comptime_float,
663 .noreturn,674 .noreturn,
664 .@"null",675 .@"null",
676 .@"undefined",
665 .fn_noreturn_no_args,677 .fn_noreturn_no_args,
666 .fn_naked_noreturn_no_args,678 .fn_naked_noreturn_no_args,
667 .fn_ccc_void_no_args,679 .fn_ccc_void_no_args,
...@@ -707,6 +719,7 @@ pub const Type = extern union {...@@ -707,6 +719,7 @@ pub const Type = extern union {
707 .comptime_float,719 .comptime_float,
708 .noreturn,720 .noreturn,
709 .@"null",721 .@"null",
722 .@"undefined",
710 .fn_noreturn_no_args,723 .fn_noreturn_no_args,
711 .fn_naked_noreturn_no_args,724 .fn_naked_noreturn_no_args,
712 .fn_ccc_void_no_args,725 .fn_ccc_void_no_args,
...@@ -781,6 +794,7 @@ pub const Type = extern union {...@@ -781,6 +794,7 @@ pub const Type = extern union {
781 .comptime_float,794 .comptime_float,
782 .noreturn,795 .noreturn,
783 .@"null",796 .@"null",
797 .@"undefined",
784 .array,798 .array,
785 .single_const_pointer,799 .single_const_pointer,
786 .single_const_pointer_to_comptime_int,800 .single_const_pointer_to_comptime_int,
...@@ -826,6 +840,7 @@ pub const Type = extern union {...@@ -826,6 +840,7 @@ pub const Type = extern union {
826 .comptime_float,840 .comptime_float,
827 .noreturn,841 .noreturn,
828 .@"null",842 .@"null",
843 .@"undefined",
829 .array,844 .array,
830 .single_const_pointer,845 .single_const_pointer,
831 .single_const_pointer_to_comptime_int,846 .single_const_pointer_to_comptime_int,
...@@ -870,6 +885,7 @@ pub const Type = extern union {...@@ -870,6 +885,7 @@ pub const Type = extern union {
870 .comptime_float,885 .comptime_float,
871 .noreturn,886 .noreturn,
872 .@"null",887 .@"null",
888 .@"undefined",
873 .array,889 .array,
874 .single_const_pointer,890 .single_const_pointer,
875 .single_const_pointer_to_comptime_int,891 .single_const_pointer_to_comptime_int,
...@@ -914,6 +930,7 @@ pub const Type = extern union {...@@ -914,6 +930,7 @@ pub const Type = extern union {
914 .comptime_float,930 .comptime_float,
915 .noreturn,931 .noreturn,
916 .@"null",932 .@"null",
933 .@"undefined",
917 .array,934 .array,
918 .single_const_pointer,935 .single_const_pointer,
919 .single_const_pointer_to_comptime_int,936 .single_const_pointer_to_comptime_int,
...@@ -958,6 +975,7 @@ pub const Type = extern union {...@@ -958,6 +975,7 @@ pub const Type = extern union {
958 .comptime_float,975 .comptime_float,
959 .noreturn,976 .noreturn,
960 .@"null",977 .@"null",
978 .@"undefined",
961 .array,979 .array,
962 .single_const_pointer,980 .single_const_pointer,
963 .single_const_pointer_to_comptime_int,981 .single_const_pointer_to_comptime_int,
...@@ -1013,6 +1031,7 @@ pub const Type = extern union {...@@ -1013,6 +1031,7 @@ pub const Type = extern union {
1013 .anyerror,1031 .anyerror,
1014 .noreturn,1032 .noreturn,
1015 .@"null",1033 .@"null",
1034 .@"undefined",
1016 .fn_noreturn_no_args,1035 .fn_noreturn_no_args,
1017 .fn_naked_noreturn_no_args,1036 .fn_naked_noreturn_no_args,
1018 .fn_ccc_void_no_args,1037 .fn_ccc_void_no_args,
...@@ -1062,6 +1081,7 @@ pub const Type = extern union {...@@ -1062,6 +1081,7 @@ pub const Type = extern union {
1062 .void,1081 .void,
1063 .noreturn,1082 .noreturn,
1064 .@"null",1083 .@"null",
1084 .@"undefined",
1065 => return true,1085 => return true,
10661086
1067 .int_unsigned => return ty.cast(Payload.IntUnsigned).?.bits == 0,1087 .int_unsigned => return ty.cast(Payload.IntUnsigned).?.bits == 0,
...@@ -1115,6 +1135,7 @@ pub const Type = extern union {...@@ -1115,6 +1135,7 @@ pub const Type = extern union {
1115 .void,1135 .void,
1116 .noreturn,1136 .noreturn,
1117 .@"null",1137 .@"null",
1138 .@"undefined",
1118 .int_unsigned,1139 .int_unsigned,
1119 .int_signed,1140 .int_signed,
1120 .array,1141 .array,
...@@ -1157,6 +1178,7 @@ pub const Type = extern union {...@@ -1157,6 +1178,7 @@ pub const Type = extern union {
1157 comptime_float,1178 comptime_float,
1158 noreturn,1179 noreturn,
1159 @"null",1180 @"null",
1181 @"undefined",
1160 fn_noreturn_no_args,1182 fn_noreturn_no_args,
1161 fn_naked_noreturn_no_args,1183 fn_naked_noreturn_no_args,
1162 fn_ccc_void_no_args,1184 fn_ccc_void_no_args,
src-self-hosted/value.zig+12
...@@ -47,6 +47,7 @@ pub const Value = extern union {...@@ -47,6 +47,7 @@ pub const Value = extern union {
47 comptime_float_type,47 comptime_float_type,
48 noreturn_type,48 noreturn_type,
49 null_type,49 null_type,
50 undefined_type,
50 fn_noreturn_no_args_type,51 fn_noreturn_no_args_type,
51 fn_naked_noreturn_no_args_type,52 fn_naked_noreturn_no_args_type,
52 fn_ccc_void_no_args_type,53 fn_ccc_void_no_args_type,
...@@ -141,6 +142,7 @@ pub const Value = extern union {...@@ -141,6 +142,7 @@ pub const Value = extern union {
141 .comptime_float_type => return out_stream.writeAll("comptime_float"),142 .comptime_float_type => return out_stream.writeAll("comptime_float"),
142 .noreturn_type => return out_stream.writeAll("noreturn"),143 .noreturn_type => return out_stream.writeAll("noreturn"),
143 .null_type => return out_stream.writeAll("@TypeOf(null)"),144 .null_type => return out_stream.writeAll("@TypeOf(null)"),
145 .undefined_type => return out_stream.writeAll("@TypeOf(undefined)"),
144 .fn_noreturn_no_args_type => return out_stream.writeAll("fn() noreturn"),146 .fn_noreturn_no_args_type => return out_stream.writeAll("fn() noreturn"),
145 .fn_naked_noreturn_no_args_type => return out_stream.writeAll("fn() callconv(.Naked) noreturn"),147 .fn_naked_noreturn_no_args_type => return out_stream.writeAll("fn() callconv(.Naked) noreturn"),
146 .fn_ccc_void_no_args_type => return out_stream.writeAll("fn() callconv(.C) void"),148 .fn_ccc_void_no_args_type => return out_stream.writeAll("fn() callconv(.C) void"),
...@@ -225,6 +227,7 @@ pub const Value = extern union {...@@ -225,6 +227,7 @@ pub const Value = extern union {
225 .comptime_float_type => Type.initTag(.comptime_float),227 .comptime_float_type => Type.initTag(.comptime_float),
226 .noreturn_type => Type.initTag(.noreturn),228 .noreturn_type => Type.initTag(.noreturn),
227 .null_type => Type.initTag(.@"null"),229 .null_type => Type.initTag(.@"null"),
230 .undefined_type => Type.initTag(.@"undefined"),
228 .fn_noreturn_no_args_type => Type.initTag(.fn_noreturn_no_args),231 .fn_noreturn_no_args_type => Type.initTag(.fn_noreturn_no_args),
229 .fn_naked_noreturn_no_args_type => Type.initTag(.fn_naked_noreturn_no_args),232 .fn_naked_noreturn_no_args_type => Type.initTag(.fn_naked_noreturn_no_args),
230 .fn_ccc_void_no_args_type => Type.initTag(.fn_ccc_void_no_args),233 .fn_ccc_void_no_args_type => Type.initTag(.fn_ccc_void_no_args),
...@@ -281,6 +284,7 @@ pub const Value = extern union {...@@ -281,6 +284,7 @@ pub const Value = extern union {
281 .comptime_float_type,284 .comptime_float_type,
282 .noreturn_type,285 .noreturn_type,
283 .null_type,286 .null_type,
287 .undefined_type,
284 .fn_noreturn_no_args_type,288 .fn_noreturn_no_args_type,
285 .fn_naked_noreturn_no_args_type,289 .fn_naked_noreturn_no_args_type,
286 .fn_ccc_void_no_args_type,290 .fn_ccc_void_no_args_type,
...@@ -339,6 +343,7 @@ pub const Value = extern union {...@@ -339,6 +343,7 @@ pub const Value = extern union {
339 .comptime_float_type,343 .comptime_float_type,
340 .noreturn_type,344 .noreturn_type,
341 .null_type,345 .null_type,
346 .undefined_type,
342 .fn_noreturn_no_args_type,347 .fn_noreturn_no_args_type,
343 .fn_naked_noreturn_no_args_type,348 .fn_naked_noreturn_no_args_type,
344 .fn_ccc_void_no_args_type,349 .fn_ccc_void_no_args_type,
...@@ -398,6 +403,7 @@ pub const Value = extern union {...@@ -398,6 +403,7 @@ pub const Value = extern union {
398 .comptime_float_type,403 .comptime_float_type,
399 .noreturn_type,404 .noreturn_type,
400 .null_type,405 .null_type,
406 .undefined_type,
401 .fn_noreturn_no_args_type,407 .fn_noreturn_no_args_type,
402 .fn_naked_noreturn_no_args_type,408 .fn_naked_noreturn_no_args_type,
403 .fn_ccc_void_no_args_type,409 .fn_ccc_void_no_args_type,
...@@ -462,6 +468,7 @@ pub const Value = extern union {...@@ -462,6 +468,7 @@ pub const Value = extern union {
462 .comptime_float_type,468 .comptime_float_type,
463 .noreturn_type,469 .noreturn_type,
464 .null_type,470 .null_type,
471 .undefined_type,
465 .fn_noreturn_no_args_type,472 .fn_noreturn_no_args_type,
466 .fn_naked_noreturn_no_args_type,473 .fn_naked_noreturn_no_args_type,
467 .fn_ccc_void_no_args_type,474 .fn_ccc_void_no_args_type,
...@@ -555,6 +562,7 @@ pub const Value = extern union {...@@ -555,6 +562,7 @@ pub const Value = extern union {
555 .comptime_float_type,562 .comptime_float_type,
556 .noreturn_type,563 .noreturn_type,
557 .null_type,564 .null_type,
565 .undefined_type,
558 .fn_noreturn_no_args_type,566 .fn_noreturn_no_args_type,
559 .fn_naked_noreturn_no_args_type,567 .fn_naked_noreturn_no_args_type,
560 .fn_ccc_void_no_args_type,568 .fn_ccc_void_no_args_type,
...@@ -610,6 +618,7 @@ pub const Value = extern union {...@@ -610,6 +618,7 @@ pub const Value = extern union {
610 .comptime_float_type,618 .comptime_float_type,
611 .noreturn_type,619 .noreturn_type,
612 .null_type,620 .null_type,
621 .undefined_type,
613 .fn_noreturn_no_args_type,622 .fn_noreturn_no_args_type,
614 .fn_naked_noreturn_no_args_type,623 .fn_naked_noreturn_no_args_type,
615 .fn_ccc_void_no_args_type,624 .fn_ccc_void_no_args_type,
...@@ -710,6 +719,7 @@ pub const Value = extern union {...@@ -710,6 +719,7 @@ pub const Value = extern union {
710 .comptime_float_type,719 .comptime_float_type,
711 .noreturn_type,720 .noreturn_type,
712 .null_type,721 .null_type,
722 .undefined_type,
713 .fn_noreturn_no_args_type,723 .fn_noreturn_no_args_type,
714 .fn_naked_noreturn_no_args_type,724 .fn_naked_noreturn_no_args_type,
715 .fn_ccc_void_no_args_type,725 .fn_ccc_void_no_args_type,
...@@ -771,6 +781,7 @@ pub const Value = extern union {...@@ -771,6 +781,7 @@ pub const Value = extern union {
771 .comptime_float_type,781 .comptime_float_type,
772 .noreturn_type,782 .noreturn_type,
773 .null_type,783 .null_type,
784 .undefined_type,
774 .fn_noreturn_no_args_type,785 .fn_noreturn_no_args_type,
775 .fn_naked_noreturn_no_args_type,786 .fn_naked_noreturn_no_args_type,
776 .fn_ccc_void_no_args_type,787 .fn_ccc_void_no_args_type,
...@@ -849,6 +860,7 @@ pub const Value = extern union {...@@ -849,6 +860,7 @@ pub const Value = extern union {
849 .comptime_float_type,860 .comptime_float_type,
850 .noreturn_type,861 .noreturn_type,
851 .null_type,862 .null_type,
863 .undefined_type,
852 .fn_noreturn_no_args_type,864 .fn_noreturn_no_args_type,
853 .fn_naked_noreturn_no_args_type,865 .fn_naked_noreturn_no_args_type,
854 .fn_ccc_void_no_args_type,866 .fn_ccc_void_no_args_type,
src-self-hosted/zir.zig+250-140
...@@ -27,9 +27,11 @@ pub const Inst = struct {...@@ -27,9 +27,11 @@ pub const Inst = struct {
27 pub const Tag = enum {27 pub const Tag = enum {
28 breakpoint,28 breakpoint,
29 call,29 call,
30 /// Represents a reference to a global decl by name.30 /// Represents a pointer to a global decl by name.
31 /// The syntax `@foo` is equivalent to `declref("foo")`.
32 declref,31 declref,
32 /// The syntax `@foo` is equivalent to `declval("foo")`.
33 /// declval is equivalent to declref followed by deref.
34 declval,
33 str,35 str,
34 int,36 int,
35 ptrtoint,37 ptrtoint,
...@@ -59,6 +61,7 @@ pub const Inst = struct {...@@ -59,6 +61,7 @@ pub const Inst = struct {
59 .breakpoint => Breakpoint,61 .breakpoint => Breakpoint,
60 .call => Call,62 .call => Call,
61 .declref => DeclRef,63 .declref => DeclRef,
64 .declval => DeclVal,
62 .str => Str,65 .str => Str,
63 .int => Int,66 .int => Int,
64 .ptrtoint => PtrToInt,67 .ptrtoint => PtrToInt,
...@@ -122,6 +125,16 @@ pub const Inst = struct {...@@ -122,6 +125,16 @@ pub const Inst = struct {
122 kw_args: struct {},125 kw_args: struct {},
123 };126 };
124127
128 pub const DeclVal = struct {
129 pub const base_tag = Tag.declval;
130 base: Inst,
131
132 positionals: struct {
133 name: []const u8,
134 },
135 kw_args: struct {},
136 };
137
125 pub const Str = struct {138 pub const Str = struct {
126 pub const base_tag = Tag.str;139 pub const base_tag = Tag.str;
127 base: Inst,140 base: Inst,
...@@ -254,11 +267,11 @@ pub const Inst = struct {...@@ -254,11 +267,11 @@ pub const Inst = struct {
254 base: Inst,267 base: Inst,
255268
256 positionals: struct {269 positionals: struct {
257 tag: BuiltinType,270 tag: Builtin,
258 },271 },
259 kw_args: struct {},272 kw_args: struct {},
260273
261 pub const BuiltinType = enum {274 pub const Builtin = enum {
262 isize,275 isize,
263 usize,276 usize,
264 c_short,277 c_short,
...@@ -282,32 +295,42 @@ pub const Inst = struct {...@@ -282,32 +295,42 @@ pub const Inst = struct {
282 anyerror,295 anyerror,
283 comptime_int,296 comptime_int,
284 comptime_float,297 comptime_float,
298 @"true",
299 @"false",
300 @"null",
301 @"undefined",
302 void_value,
285303
286 pub fn toType(self: BuiltinType) Type {304 pub fn toTypedValue(self: Builtin) TypedValue {
287 return switch (self) {305 return switch (self) {
288 .isize => Type.initTag(.isize),306 .isize => .{ .ty = Type.initTag(.type), .val = Value.initTag(.isize_type) },
289 .usize => Type.initTag(.usize),307 .usize => .{ .ty = Type.initTag(.type), .val = Value.initTag(.usize_type) },
290 .c_short => Type.initTag(.c_short),308 .c_short => .{ .ty = Type.initTag(.type), .val = Value.initTag(.c_short_type) },
291 .c_ushort => Type.initTag(.c_ushort),309 .c_ushort => .{ .ty = Type.initTag(.type), .val = Value.initTag(.c_ushort_type) },
292 .c_int => Type.initTag(.c_int),310 .c_int => .{ .ty = Type.initTag(.type), .val = Value.initTag(.c_int_type) },
293 .c_uint => Type.initTag(.c_uint),311 .c_uint => .{ .ty = Type.initTag(.type), .val = Value.initTag(.c_uint_type) },
294 .c_long => Type.initTag(.c_long),312 .c_long => .{ .ty = Type.initTag(.type), .val = Value.initTag(.c_long_type) },
295 .c_ulong => Type.initTag(.c_ulong),313 .c_ulong => .{ .ty = Type.initTag(.type), .val = Value.initTag(.c_ulong_type) },
296 .c_longlong => Type.initTag(.c_longlong),314 .c_longlong => .{ .ty = Type.initTag(.type), .val = Value.initTag(.c_longlong_type) },
297 .c_ulonglong => Type.initTag(.c_ulonglong),315 .c_ulonglong => .{ .ty = Type.initTag(.type), .val = Value.initTag(.c_ulonglong_type) },
298 .c_longdouble => Type.initTag(.c_longdouble),316 .c_longdouble => .{ .ty = Type.initTag(.type), .val = Value.initTag(.c_longdouble_type) },
299 .c_void => Type.initTag(.c_void),317 .c_void => .{ .ty = Type.initTag(.type), .val = Value.initTag(.c_void_type) },
300 .f16 => Type.initTag(.f16),318 .f16 => .{ .ty = Type.initTag(.type), .val = Value.initTag(.f16_type) },
301 .f32 => Type.initTag(.f32),319 .f32 => .{ .ty = Type.initTag(.type), .val = Value.initTag(.f32_type) },
302 .f64 => Type.initTag(.f64),320 .f64 => .{ .ty = Type.initTag(.type), .val = Value.initTag(.f64_type) },
303 .f128 => Type.initTag(.f128),321 .f128 => .{ .ty = Type.initTag(.type), .val = Value.initTag(.f128_type) },
304 .bool => Type.initTag(.bool),322 .bool => .{ .ty = Type.initTag(.type), .val = Value.initTag(.bool_type) },
305 .void => Type.initTag(.void),323 .void => .{ .ty = Type.initTag(.type), .val = Value.initTag(.void_type) },
306 .noreturn => Type.initTag(.noreturn),324 .noreturn => .{ .ty = Type.initTag(.type), .val = Value.initTag(.noreturn_type) },
307 .type => Type.initTag(.type),325 .type => .{ .ty = Type.initTag(.type), .val = Value.initTag(.type_type) },
308 .anyerror => Type.initTag(.anyerror),326 .anyerror => .{ .ty = Type.initTag(.type), .val = Value.initTag(.anyerror_type) },
309 .comptime_int => Type.initTag(.comptime_int),327 .comptime_int => .{ .ty = Type.initTag(.type), .val = Value.initTag(.comptime_int_type) },
310 .comptime_float => Type.initTag(.comptime_float),328 .comptime_float => .{ .ty = Type.initTag(.type), .val = Value.initTag(.comptime_float_type) },
329 .@"true" => .{ .ty = Type.initTag(.bool), .val = Value.initTag(.bool_true) },
330 .@"false" => .{ .ty = Type.initTag(.bool), .val = Value.initTag(.bool_false) },
331 .@"null" => .{ .ty = Type.initTag(.@"null"), .val = Value.initTag(.null_value) },
332 .@"undefined" => .{ .ty = Type.initTag(.@"undefined"), .val = Value.initTag(.undef) },
333 .void_value => .{ .ty = Type.initTag(.void), .val = Value.initTag(.the_one_possible_value) },
311 };334 };
312 }335 }
313 };336 };
...@@ -440,7 +463,7 @@ pub const Module = struct {...@@ -440,7 +463,7 @@ pub const Module = struct {
440 self.writeToStream(std.heap.page_allocator, std.io.getStdErr().outStream()) catch {};463 self.writeToStream(std.heap.page_allocator, std.io.getStdErr().outStream()) catch {};
441 }464 }
442465
443 const InstPtrTable = std.AutoHashMap(*Inst, struct { index: usize, fn_body: ?*Module.Body });466 const InstPtrTable = std.AutoHashMap(*Inst, struct { inst: *Inst, index: ?usize });
444467
445 /// TODO Look into making a table to speed this up.468 /// TODO Look into making a table to speed this up.
446 pub fn findDecl(self: Module, name: []const u8) ?*Inst {469 pub fn findDecl(self: Module, name: []const u8) ?*Inst {
...@@ -462,17 +485,17 @@ pub const Module = struct {...@@ -462,17 +485,17 @@ pub const Module = struct {
462 try inst_table.ensureCapacity(self.decls.len);485 try inst_table.ensureCapacity(self.decls.len);
463486
464 for (self.decls) |decl, decl_i| {487 for (self.decls) |decl, decl_i| {
465 try inst_table.putNoClobber(decl, .{ .index = decl_i, .fn_body = null });488 try inst_table.putNoClobber(decl, .{ .inst = decl, .index = null });
466489
467 if (decl.cast(Inst.Fn)) |fn_inst| {490 if (decl.cast(Inst.Fn)) |fn_inst| {
468 for (fn_inst.positionals.body.instructions) |inst, inst_i| {491 for (fn_inst.positionals.body.instructions) |inst, inst_i| {
469 try inst_table.putNoClobber(inst, .{ .index = inst_i, .fn_body = &fn_inst.positionals.body });492 try inst_table.putNoClobber(inst, .{ .inst = inst, .index = inst_i });
470 }493 }
471 }494 }
472 }495 }
473496
474 for (self.decls) |decl, i| {497 for (self.decls) |decl, i| {
475 try stream.print("@{} ", .{i});498 try stream.print("@{} ", .{decl.name});
476 try self.writeInstToStream(stream, decl, &inst_table);499 try self.writeInstToStream(stream, decl, &inst_table);
477 try stream.writeByte('\n');500 try stream.writeByte('\n');
478 }501 }
...@@ -489,6 +512,7 @@ pub const Module = struct {...@@ -489,6 +512,7 @@ pub const Module = struct {
489 .breakpoint => return self.writeInstToStreamGeneric(stream, .breakpoint, decl, inst_table),512 .breakpoint => return self.writeInstToStreamGeneric(stream, .breakpoint, decl, inst_table),
490 .call => return self.writeInstToStreamGeneric(stream, .call, decl, inst_table),513 .call => return self.writeInstToStreamGeneric(stream, .call, decl, inst_table),
491 .declref => return self.writeInstToStreamGeneric(stream, .declref, decl, inst_table),514 .declref => return self.writeInstToStreamGeneric(stream, .declref, decl, inst_table),
515 .declval => return self.writeInstToStreamGeneric(stream, .declval, decl, inst_table),
492 .str => return self.writeInstToStreamGeneric(stream, .str, decl, inst_table),516 .str => return self.writeInstToStreamGeneric(stream, .str, decl, inst_table),
493 .int => return self.writeInstToStreamGeneric(stream, .int, decl, inst_table),517 .int => return self.writeInstToStreamGeneric(stream, .int, decl, inst_table),
494 .ptrtoint => return self.writeInstToStreamGeneric(stream, .ptrtoint, decl, inst_table),518 .ptrtoint => return self.writeInstToStreamGeneric(stream, .ptrtoint, decl, inst_table),
...@@ -587,9 +611,18 @@ pub const Module = struct {...@@ -587,9 +611,18 @@ pub const Module = struct {
587 }611 }
588612
589 fn writeInstParamToStream(self: Module, stream: var, inst: *Inst, inst_table: *const InstPtrTable) !void {613 fn writeInstParamToStream(self: Module, stream: var, inst: *Inst, inst_table: *const InstPtrTable) !void {
590 const info = inst_table.getValue(inst).?;614 if (inst_table.getValue(inst)) |info| {
591 const prefix = if (info.fn_body == null) "@" else "%";615 if (info.index) |i| {
592 try stream.print("{}{}", .{ prefix, info.index });616 try stream.print("%{}", .{info.index});
617 } else {
618 try stream.print("@{}", .{info.inst.name});
619 }
620 } else if (inst.cast(Inst.DeclVal)) |decl_val| {
621 try stream.print("@{}", .{decl_val.positionals.name});
622 } else {
623 //try stream.print("?", .{});
624 unreachable;
625 }
593 }626 }
594};627};
595628
...@@ -964,47 +997,17 @@ const Parser = struct {...@@ -964,47 +997,17 @@ const Parser = struct {
964 self.i = src;997 self.i = src;
965 return self.fail("unrecognized identifier: {}", .{bad_name});998 return self.fail("unrecognized identifier: {}", .{bad_name});
966 } else {999 } else {
967 const name_array = try self.arena.allocator.create(Inst.Str);1000 const declval = try self.arena.allocator.create(Inst.DeclVal);
968 name_array.* = .{1001 declval.* = .{
969 .base = .{
970 .name = try self.generateName(),
971 .src = src,
972 .tag = Inst.Str.base_tag,
973 },
974 .positionals = .{ .bytes = ident },
975 .kw_args = .{},
976 };
977 const name = try self.arena.allocator.create(Inst.Ref);
978 name.* = .{
979 .base = .{
980 .name = try self.generateName(),
981 .src = src,
982 .tag = Inst.Ref.base_tag,
983 },
984 .positionals = .{ .operand = &name_array.base },
985 .kw_args = .{},
986 };
987 const declref = try self.arena.allocator.create(Inst.DeclRef);
988 declref.* = .{
989 .base = .{
990 .name = try self.generateName(),
991 .src = src,
992 .tag = Inst.DeclRef.base_tag,
993 },
994 .positionals = .{ .name = &name.base },
995 .kw_args = .{},
996 };
997 const deref = try self.arena.allocator.create(Inst.Deref);
998 deref.* = .{
999 .base = .{1002 .base = .{
1000 .name = try self.generateName(),1003 .name = try self.generateName(),
1001 .src = src,1004 .src = src,
1002 .tag = Inst.Deref.base_tag,1005 .tag = Inst.DeclVal.base_tag,
1003 },1006 },
1004 .positionals = .{ .ptr = &declref.base },1007 .positionals = .{ .name = ident },
1005 .kw_args = .{},1008 .kw_args = .{},
1006 };1009 };
1007 return &deref.base;1010 return &declval.base;
1008 }1011 }
1009 };1012 };
1010 if (local_ref) {1013 if (local_ref) {
...@@ -1025,12 +1028,15 @@ pub fn emit(allocator: *Allocator, old_module: IrModule) !Module {...@@ -1025,12 +1028,15 @@ pub fn emit(allocator: *Allocator, old_module: IrModule) !Module {
1025 var ctx: EmitZIR = .{1028 var ctx: EmitZIR = .{
1026 .allocator = allocator,1029 .allocator = allocator,
1027 .decls = .{},1030 .decls = .{},
1028 .decl_table = std.AutoHashMap(*ir.Inst, *Inst).init(allocator),
1029 .arena = std.heap.ArenaAllocator.init(allocator),1031 .arena = std.heap.ArenaAllocator.init(allocator),
1030 .old_module = &old_module,1032 .old_module = &old_module,
1033 .next_auto_name = 0,
1034 .names = std.StringHashMap(void).init(allocator),
1035 .primitive_table = std.AutoHashMap(Inst.Primitive.Builtin, *Inst).init(allocator),
1031 };1036 };
1032 defer ctx.decls.deinit(allocator);1037 defer ctx.decls.deinit(allocator);
1033 defer ctx.decl_table.deinit();1038 defer ctx.names.deinit();
1039 defer ctx.primitive_table.deinit();
1034 errdefer ctx.arena.deinit();1040 errdefer ctx.arena.deinit();
10351041
1036 try ctx.emit();1042 try ctx.emit();
...@@ -1046,47 +1052,90 @@ const EmitZIR = struct {...@@ -1046,47 +1052,90 @@ const EmitZIR = struct {
1046 arena: std.heap.ArenaAllocator,1052 arena: std.heap.ArenaAllocator,
1047 old_module: *const IrModule,1053 old_module: *const IrModule,
1048 decls: std.ArrayListUnmanaged(*Inst),1054 decls: std.ArrayListUnmanaged(*Inst),
1049 decl_table: std.AutoHashMap(*ir.Inst, *Inst),1055 names: std.StringHashMap(void),
1056 next_auto_name: usize,
1057 primitive_table: std.AutoHashMap(Inst.Primitive.Builtin, *Inst),
10501058
1051 fn emit(self: *EmitZIR) !void {1059 fn emit(self: *EmitZIR) !void {
1052 var it = self.old_module.decl_exports.iterator();1060 // Put all the Decls in a list and sort them by name to avoid nondeterminism introduced
1053 while (it.next()) |kv| {1061 // by the hash table.
1054 const decl = kv.key;1062 var src_decls = std.ArrayList(*IrModule.Decl).init(self.allocator);
1055 const exports = kv.value;1063 defer src_decls.deinit();
1056 const export_value = try self.emitTypedValue(decl.src, decl.typed_value.most_recent.typed_value);1064 try src_decls.ensureCapacity(self.old_module.decl_table.size);
1057 for (exports) |module_export| {1065 try self.decls.ensureCapacity(self.allocator, self.old_module.decl_table.size);
1058 const symbol_name = try self.emitStringLiteral(module_export.src, module_export.options.name);1066 try self.names.ensureCapacity(self.old_module.decl_table.size);
1059 const export_inst = try self.arena.allocator.create(Inst.Export);1067
1060 export_inst.* = .{1068 var decl_it = self.old_module.decl_table.iterator();
1061 .base = .{1069 while (decl_it.next()) |kv| {
1062 .name = try self.autoName(),1070 const decl = kv.value;
1063 .src = module_export.src,1071 src_decls.appendAssumeCapacity(decl);
1064 .tag = Inst.Export.base_tag,1072 self.names.putAssumeCapacityNoClobber(mem.spanZ(decl.name), {});
1065 },1073 }
1066 .positionals = .{1074 std.sort.sort(*IrModule.Decl, src_decls.items, {}, (struct {
1067 .symbol_name = symbol_name,1075 fn lessThan(context: void, a: *IrModule.Decl, b: *IrModule.Decl) bool {
1068 .value = export_value,1076 return a.src < b.src;
1069 },1077 }
1070 .kw_args = .{},1078 }).lessThan);
1071 };1079
1072 try self.decls.append(self.allocator, &export_inst.base);1080 // Emit all the decls.
1081 for (src_decls.items) |ir_decl| {
1082 if (self.old_module.export_owners.getValue(ir_decl)) |exports| {
1083 for (exports) |module_export| {
1084 const declval = try self.emitDeclVal(ir_decl.src, mem.spanZ(module_export.exported_decl.name));
1085 const symbol_name = try self.emitStringLiteral(module_export.src, module_export.options.name);
1086 const export_inst = try self.arena.allocator.create(Inst.Export);
1087 export_inst.* = .{
1088 .base = .{
1089 .name = try self.autoName(),
1090 .src = module_export.src,
1091 .tag = Inst.Export.base_tag,
1092 },
1093 .positionals = .{
1094 .symbol_name = symbol_name,
1095 .value = declval,
1096 },
1097 .kw_args = .{},
1098 };
1099 try self.decls.append(self.allocator, &export_inst.base);
1100 }
1101 } else {
1102 const new_decl = try self.emitTypedValue(ir_decl.src, ir_decl.typed_value.most_recent.typed_value);
1103 new_decl.name = try self.arena.allocator.dupe(u8, mem.spanZ(ir_decl.name));
1073 }1104 }
1074 }1105 }
1075 }1106 }
10761107
1077 fn resolveInst(self: *EmitZIR, inst_table: *const std.AutoHashMap(*ir.Inst, *Inst), inst: *ir.Inst) !*Inst {1108 fn resolveInst(self: *EmitZIR, inst_table: *std.AutoHashMap(*ir.Inst, *Inst), inst: *ir.Inst) !*Inst {
1078 if (inst.cast(ir.Inst.Constant)) |const_inst| {1109 if (inst.cast(ir.Inst.Constant)) |const_inst| {
1079 if (self.decl_table.getValue(inst)) |decl| {1110 const new_decl = if (const_inst.val.cast(Value.Payload.Function)) |func_pl| blk: {
1080 return decl;1111 const owner_decl = func_pl.func.owner_decl;
1081 }1112 break :blk try self.emitDeclVal(inst.src, mem.spanZ(owner_decl.name));
1082 const new_decl = try self.emitTypedValue(inst.src, .{ .ty = inst.ty, .val = const_inst.val });1113 } else if (const_inst.val.cast(Value.Payload.DeclRef)) |declref| blk: {
1083 try self.decl_table.putNoClobber(inst, new_decl);1114 break :blk try self.emitDeclRef(inst.src, declref.decl);
1115 } else blk: {
1116 break :blk try self.emitTypedValue(inst.src, .{ .ty = inst.ty, .val = const_inst.val });
1117 };
1118 try inst_table.putNoClobber(inst, new_decl);
1084 return new_decl;1119 return new_decl;
1085 } else {1120 } else {
1086 return inst_table.getValue(inst).?;1121 return inst_table.getValue(inst).?;
1087 }1122 }
1088 }1123 }
10891124
1125 fn emitDeclVal(self: *EmitZIR, src: usize, decl_name: []const u8) !*Inst {
1126 const declval = try self.arena.allocator.create(Inst.DeclVal);
1127 declval.* = .{
1128 .base = .{
1129 .name = try self.autoName(),
1130 .src = src,
1131 .tag = Inst.DeclVal.base_tag,
1132 },
1133 .positionals = .{ .name = try self.arena.allocator.dupe(u8, decl_name) },
1134 .kw_args = .{},
1135 };
1136 return &declval.base;
1137 }
1138
1090 fn emitComptimeIntVal(self: *EmitZIR, src: usize, val: Value) !*Inst {1139 fn emitComptimeIntVal(self: *EmitZIR, src: usize, val: Value) !*Inst {
1091 const big_int_space = try self.arena.allocator.create(Value.BigIntSpace);1140 const big_int_space = try self.arena.allocator.create(Value.BigIntSpace);
1092 const int_inst = try self.arena.allocator.create(Inst.Int);1141 const int_inst = try self.arena.allocator.create(Inst.Int);
...@@ -1105,8 +1154,31 @@ const EmitZIR = struct {...@@ -1105,8 +1154,31 @@ const EmitZIR = struct {
1105 return &int_inst.base;1154 return &int_inst.base;
1106 }1155 }
11071156
1157 fn emitDeclRef(self: *EmitZIR, src: usize, decl: *IrModule.Decl) !*Inst {
1158 const declval = try self.emitDeclVal(src, mem.spanZ(decl.name));
1159 const ref_inst = try self.arena.allocator.create(Inst.Ref);
1160 ref_inst.* = .{
1161 .base = .{
1162 .name = try self.autoName(),
1163 .src = src,
1164 .tag = Inst.Ref.base_tag,
1165 },
1166 .positionals = .{
1167 .operand = declval,
1168 },
1169 .kw_args = .{},
1170 };
1171 try self.decls.append(self.allocator, &ref_inst.base);
1172
1173 return &ref_inst.base;
1174 }
1175
1108 fn emitTypedValue(self: *EmitZIR, src: usize, typed_value: TypedValue) Allocator.Error!*Inst {1176 fn emitTypedValue(self: *EmitZIR, src: usize, typed_value: TypedValue) Allocator.Error!*Inst {
1109 const allocator = &self.arena.allocator;1177 const allocator = &self.arena.allocator;
1178 if (typed_value.val.cast(Value.Payload.DeclRef)) |decl_ref| {
1179 const decl = decl_ref.decl;
1180 return self.emitDeclRef(src, decl);
1181 }
1110 switch (typed_value.ty.zigTypeTag()) {1182 switch (typed_value.ty.zigTypeTag()) {
1111 .Pointer => {1183 .Pointer => {
1112 const ptr_elem_type = typed_value.ty.elemType();1184 const ptr_elem_type = typed_value.ty.elemType();
...@@ -1142,7 +1214,6 @@ const EmitZIR = struct {...@@ -1142,7 +1214,6 @@ const EmitZIR = struct {
1142 },1214 },
1143 .kw_args = .{},1215 .kw_args = .{},
1144 };1216 };
1145 try self.decls.append(self.allocator, &as_inst.base);
11461217
1147 return &as_inst.base;1218 return &as_inst.base;
1148 },1219 },
...@@ -1182,6 +1253,33 @@ const EmitZIR = struct {...@@ -1182,6 +1253,33 @@ const EmitZIR = struct {
1182 try self.decls.append(self.allocator, &fn_inst.base);1253 try self.decls.append(self.allocator, &fn_inst.base);
1183 return &fn_inst.base;1254 return &fn_inst.base;
1184 },1255 },
1256 .Array => {
1257 // TODO more checks to make sure this can be emitted as a string literal
1258 //const array_elem_type = ptr_elem_type.elemType();
1259 //if (array_elem_type.eql(Type.initTag(.u8)) and
1260 // ptr_elem_type.hasSentinel(Value.initTag(.zero)))
1261 //{
1262 //}
1263 const bytes = typed_value.val.toAllocatedBytes(allocator) catch |err| switch (err) {
1264 error.AnalysisFail => unreachable,
1265 else => |e| return e,
1266 };
1267 const str_inst = try self.arena.allocator.create(Inst.Str);
1268 str_inst.* = .{
1269 .base = .{
1270 .name = try self.autoName(),
1271 .src = src,
1272 .tag = Inst.Str.base_tag,
1273 },
1274 .positionals = .{
1275 .bytes = bytes,
1276 },
1277 .kw_args = .{},
1278 };
1279 try self.decls.append(self.allocator, &str_inst.base);
1280 return &str_inst.base;
1281 },
1282 .Void => return self.emitPrimitive(src, .void_value),
1185 else => |t| std.debug.panic("TODO implement emitTypedValue for {}", .{@tagName(t)}),1283 else => |t| std.debug.panic("TODO implement emitTypedValue for {}", .{@tagName(t)}),
1186 }1284 }
1187 }1285 }
...@@ -1395,30 +1493,30 @@ const EmitZIR = struct {...@@ -1395,30 +1493,30 @@ const EmitZIR = struct {
13951493
1396 fn emitType(self: *EmitZIR, src: usize, ty: Type) Allocator.Error!*Inst {1494 fn emitType(self: *EmitZIR, src: usize, ty: Type) Allocator.Error!*Inst {
1397 switch (ty.tag()) {1495 switch (ty.tag()) {
1398 .isize => return self.emitPrimitiveType(src, .isize),1496 .isize => return self.emitPrimitive(src, .isize),
1399 .usize => return self.emitPrimitiveType(src, .usize),1497 .usize => return self.emitPrimitive(src, .usize),
1400 .c_short => return self.emitPrimitiveType(src, .c_short),1498 .c_short => return self.emitPrimitive(src, .c_short),
1401 .c_ushort => return self.emitPrimitiveType(src, .c_ushort),1499 .c_ushort => return self.emitPrimitive(src, .c_ushort),
1402 .c_int => return self.emitPrimitiveType(src, .c_int),1500 .c_int => return self.emitPrimitive(src, .c_int),
1403 .c_uint => return self.emitPrimitiveType(src, .c_uint),1501 .c_uint => return self.emitPrimitive(src, .c_uint),
1404 .c_long => return self.emitPrimitiveType(src, .c_long),1502 .c_long => return self.emitPrimitive(src, .c_long),
1405 .c_ulong => return self.emitPrimitiveType(src, .c_ulong),1503 .c_ulong => return self.emitPrimitive(src, .c_ulong),
1406 .c_longlong => return self.emitPrimitiveType(src, .c_longlong),1504 .c_longlong => return self.emitPrimitive(src, .c_longlong),
1407 .c_ulonglong => return self.emitPrimitiveType(src, .c_ulonglong),1505 .c_ulonglong => return self.emitPrimitive(src, .c_ulonglong),
1408 .c_longdouble => return self.emitPrimitiveType(src, .c_longdouble),1506 .c_longdouble => return self.emitPrimitive(src, .c_longdouble),
1409 .c_void => return self.emitPrimitiveType(src, .c_void),1507 .c_void => return self.emitPrimitive(src, .c_void),
1410 .f16 => return self.emitPrimitiveType(src, .f16),1508 .f16 => return self.emitPrimitive(src, .f16),
1411 .f32 => return self.emitPrimitiveType(src, .f32),1509 .f32 => return self.emitPrimitive(src, .f32),
1412 .f64 => return self.emitPrimitiveType(src, .f64),1510 .f64 => return self.emitPrimitive(src, .f64),
1413 .f128 => return self.emitPrimitiveType(src, .f128),1511 .f128 => return self.emitPrimitive(src, .f128),
1414 .anyerror => return self.emitPrimitiveType(src, .anyerror),1512 .anyerror => return self.emitPrimitive(src, .anyerror),
1415 else => switch (ty.zigTypeTag()) {1513 else => switch (ty.zigTypeTag()) {
1416 .Bool => return self.emitPrimitiveType(src, .bool),1514 .Bool => return self.emitPrimitive(src, .bool),
1417 .Void => return self.emitPrimitiveType(src, .void),1515 .Void => return self.emitPrimitive(src, .void),
1418 .NoReturn => return self.emitPrimitiveType(src, .noreturn),1516 .NoReturn => return self.emitPrimitive(src, .noreturn),
1419 .Type => return self.emitPrimitiveType(src, .type),1517 .Type => return self.emitPrimitive(src, .type),
1420 .ComptimeInt => return self.emitPrimitiveType(src, .comptime_int),1518 .ComptimeInt => return self.emitPrimitive(src, .comptime_int),
1421 .ComptimeFloat => return self.emitPrimitiveType(src, .comptime_float),1519 .ComptimeFloat => return self.emitPrimitive(src, .comptime_float),
1422 .Fn => {1520 .Fn => {
1423 const param_types = try self.allocator.alloc(Type, ty.fnParamLen());1521 const param_types = try self.allocator.alloc(Type, ty.fnParamLen());
1424 defer self.allocator.free(param_types);1522 defer self.allocator.free(param_types);
...@@ -1453,24 +1551,36 @@ const EmitZIR = struct {...@@ -1453,24 +1551,36 @@ const EmitZIR = struct {
1453 }1551 }
14541552
1455 fn autoName(self: *EmitZIR) ![]u8 {1553 fn autoName(self: *EmitZIR) ![]u8 {
1456 return std.fmt.allocPrint(&self.arena.allocator, "{}", .{self.decls.items.len});1554 while (true) {
1555 const proposed_name = try std.fmt.allocPrint(&self.arena.allocator, "unnamed${}", .{self.next_auto_name});
1556 self.next_auto_name += 1;
1557 const gop = try self.names.getOrPut(proposed_name);
1558 if (!gop.found_existing) {
1559 gop.kv.value = {};
1560 return proposed_name;
1561 }
1562 }
1457 }1563 }
14581564
1459 fn emitPrimitiveType(self: *EmitZIR, src: usize, tag: Inst.Primitive.BuiltinType) !*Inst {1565 fn emitPrimitive(self: *EmitZIR, src: usize, tag: Inst.Primitive.Builtin) !*Inst {
1460 const primitive_inst = try self.arena.allocator.create(Inst.Primitive);1566 const gop = try self.primitive_table.getOrPut(tag);
1461 primitive_inst.* = .{1567 if (!gop.found_existing) {
1462 .base = .{1568 const primitive_inst = try self.arena.allocator.create(Inst.Primitive);
1463 .name = try self.autoName(),1569 primitive_inst.* = .{
1464 .src = src,1570 .base = .{
1465 .tag = Inst.Primitive.base_tag,1571 .name = try self.autoName(),
1466 },1572 .src = src,
1467 .positionals = .{1573 .tag = Inst.Primitive.base_tag,
1468 .tag = tag,1574 },
1469 },1575 .positionals = .{
1470 .kw_args = .{},1576 .tag = tag,
1471 };1577 },
1472 try self.decls.append(self.allocator, &primitive_inst.base);1578 .kw_args = .{},
1473 return &primitive_inst.base;1579 };
1580 try self.decls.append(self.allocator, &primitive_inst.base);
1581 gop.kv.value = &primitive_inst.base;
1582 }
1583 return gop.kv.value;
1474 }1584 }
14751585
1476 fn emitStringLiteral(self: *EmitZIR, src: usize, str: []const u8) !*Inst {1586 fn emitStringLiteral(self: *EmitZIR, src: usize, str: []const u8) !*Inst {
test/stage2/zir.zig+23-12
...@@ -21,14 +21,17 @@ pub fn addCases(ctx: *TestContext) void {...@@ -21,14 +21,17 @@ pub fn addCases(ctx: *TestContext) void {
21 \\ %11 = return()21 \\ %11 = return()
22 \\})22 \\})
23 ,23 ,
24 \\@0 = primitive(void)24 \\@void = primitive(void)
25 \\@1 = fntype([], @0, cc=C)25 \\@fnty = fntype([], @void, cc=C)
26 \\@2 = fn(@1, {26 \\@9 = str("entry")
27 \\@10 = ref(@9)
28 \\@unnamed$6 = str("entry")
29 \\@unnamed$7 = ref(@unnamed$6)
30 \\@unnamed$8 = export(@unnamed$7, @entry)
31 \\@unnamed$10 = fntype([], @void, cc=C)
32 \\@entry = fn(@unnamed$10, {
27 \\ %0 = return()33 \\ %0 = return()
28 \\})34 \\})
29 \\@3 = str("entry")
30 \\@4 = ref(@3)
31 \\@5 = export(@4, @2)
32 \\35 \\
33 );36 );
34 ctx.addZIRTransform("elemptr, add, cmp, condbr, return, breakpoint", linux_x64,37 ctx.addZIRTransform("elemptr, add, cmp, condbr, return, breakpoint", linux_x64,
...@@ -68,14 +71,22 @@ pub fn addCases(ctx: *TestContext) void {...@@ -68,14 +71,22 @@ pub fn addCases(ctx: *TestContext) void {
68 \\@10 = ref(@9)71 \\@10 = ref(@9)
69 \\@11 = export(@10, @entry)72 \\@11 = export(@10, @entry)
70 ,73 ,
71 \\@0 = primitive(void)74 \\@void = primitive(void)
72 \\@1 = fntype([], @0, cc=C)75 \\@fnty = fntype([], @void, cc=C)
73 \\@2 = fn(@1, {76 \\@0 = int(0)
77 \\@1 = int(1)
78 \\@2 = int(2)
79 \\@3 = int(3)
80 \\@unnamed$7 = fntype([], @void, cc=C)
81 \\@entry = fn(@unnamed$7, {
74 \\ %0 = return()82 \\ %0 = return()
75 \\})83 \\})
76 \\@3 = str("entry")84 \\@a = str("2\x08\x01\n")
77 \\@4 = ref(@3)85 \\@9 = str("entry")
78 \\@5 = export(@4, @2)86 \\@10 = ref(@9)
87 \\@unnamed$14 = str("entry")
88 \\@unnamed$15 = ref(@unnamed$14)
89 \\@unnamed$16 = export(@unnamed$15, @entry)
79 \\90 \\
80 );91 );
8192