authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-11-15 13:03:48+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-11-15 13:03:48+02:00
logf173d078c780c9946742c4ce686ccd0dccdb7e98
tree47cf88dce1e9f9d4db80290aec4ff5234845defb
parent643f526cd121173b4102ce3a07ee9bb4a1582cc2
signature Commit is signed but in an unrecognized format.

stage2: outline container types


6 files changed, 298 insertions(+), 3 deletions(-)

src/Module.zig+29-1
......@@ -428,7 +428,7 @@ pub const Scope = struct {
428428 };
429429 }
430430
431 /// Asserts the scope has a parent which is a ZIRModule, Contaienr or File and
431 /// Asserts the scope has a parent which is a ZIRModule, Container or File and
432432 /// returns the sub_file_path field.
433433 pub fn subFilePath(base: *Scope) []const u8 {
434434 switch (base.tag) {
......@@ -1515,6 +1515,7 @@ pub fn analyzeContainer(self: *Module, container_scope: *Scope.Container) !void
15151515 // an incremental update. This code handles both cases.
15161516 const tree = try self.getAstTree(container_scope);
15171517 const decls = tree.root_node.decls();
1518 // const decls = container_scope.root_node.decls();
15181519
15191520 try self.comp.work_queue.ensureUnusedCapacity(decls.len);
15201521 try container_scope.decls.ensureCapacity(self.gpa, decls.len);
......@@ -2272,6 +2273,33 @@ pub fn createAnonymousDecl(
22722273 return new_decl;
22732274}
22742275
2276fn createContainerDecl(self: *Module, scope: *Scope, container_node: *std.zig.ast.Node.ContainerDecl) !*Decl {
2277 const name = try self.getAnonTypeName(scope, container_node.kind_token);
2278 defer self.gpa.free(name);
2279 const name_hash = scope.namespace().fullyQualifiedNameHash(name);
2280 const src_hash: std.zig.SrcHash = undefined;
2281 const new_decl = try self.createNewDecl(scope, name, scope_decl.src_index, name_hash, src_hash);
2282 const decl_arena_state = try decl_arena.allocator.create(std.heap.ArenaAllocator.State);
2283
2284 decl_arena_state.* = decl_arena.state;
2285 new_decl.generation = self.generation;
2286
2287 return new_decl;
2288}
2289
2290fn getAnonTypeName(self: *Module, scope: *Scope, base_token: std.zig.ast.TokenIndex) ![]u8 {
2291 const container = scope.getContainer();
2292 const tree = self.getAstTree(container);
2293 const base_name = switch (tree.token_ids[base_token]) {
2294 .Keyword_struct => "struct",
2295 .Keyword_enum => "enum",
2296 .Keyword_union => "union",
2297 else => unreachable,
2298 };
2299 const loc = tree.tokenLocationLoc(0, tree.token_locs[base_token]);
2300 return std.fmt.allocPrint(self.gpa, "{}:{}:{}", .{ base_name, loc.line, loc.column });
2301}
2302
22752303fn getNextAnonNameIndex(self: *Module) usize {
22762304 return @atomicRmw(usize, &self.next_anon_name_index, .Add, 1, .Monotonic);
22772305}
src/type.zig+98-1
......@@ -90,7 +90,9 @@ pub const Type = extern union {
9090
9191 .anyframe_T, .@"anyframe" => return .AnyFrame,
9292
93 .empty_struct => return .Struct,
93 .@"struct", .empty_struct => return .Struct,
94 .@"enum" => return .Enum,
95 .@"union" => return .Union,
9496 }
9597 }
9698
......@@ -442,6 +444,11 @@ pub const Type = extern union {
442444 .error_set => return self.copyPayloadShallow(allocator, Payload.ErrorSet),
443445 .error_set_single => return self.copyPayloadShallow(allocator, Payload.ErrorSetSingle),
444446 .empty_struct => return self.copyPayloadShallow(allocator, Payload.EmptyStruct),
447
448 // memory managed by the decl
449 .@"enum" => return self,
450 .@"struct" => return self,
451 .@"union" => return self,
445452 }
446453 }
447454
......@@ -673,6 +680,10 @@ pub const Type = extern union {
673680 const payload = @fieldParentPtr(Payload.ErrorSetSingle, "base", ty.ptr_otherwise);
674681 return out_stream.print("error{{{}}}", .{payload.name});
675682 },
683 // TODO improve
684 .@"enum" => return out_stream.writeAll("enum {}"),
685 .@"struct" => return out_stream.writeAll("struct {}"),
686 .@"union" => return out_stream.writeAll("union {}"),
676687 }
677688 unreachable;
678689 }
......@@ -784,6 +795,10 @@ pub const Type = extern union {
784795 return payload.error_set.hasCodeGenBits() or payload.payload.hasCodeGenBits();
785796 },
786797
798 .@"enum" => @panic("TODO"),
799 .@"struct" => @panic("TODO"),
800 .@"union" => @panic("TODO"),
801
787802 .c_void,
788803 .void,
789804 .type,
......@@ -908,6 +923,10 @@ pub const Type = extern union {
908923 @panic("TODO abiAlignment error union");
909924 },
910925
926 .@"enum" => self.cast(Payload.Enum).?.abiAlignment(),
927 .@"struct" => @panic("TODO"),
928 .@"union" => @panic("TODO"),
929
911930 .c_void,
912931 .void,
913932 .type,
......@@ -1050,6 +1069,10 @@ pub const Type = extern union {
10501069 }
10511070 @panic("TODO abiSize error union");
10521071 },
1072
1073 .@"enum" => @panic("TODO"),
1074 .@"struct" => @panic("TODO"),
1075 .@"union" => @panic("TODO"),
10531076 };
10541077 }
10551078
......@@ -1117,6 +1140,9 @@ pub const Type = extern union {
11171140 .error_set,
11181141 .error_set_single,
11191142 .empty_struct,
1143 .@"enum",
1144 .@"struct",
1145 .@"union",
11201146 => false,
11211147
11221148 .single_const_pointer,
......@@ -1192,6 +1218,9 @@ pub const Type = extern union {
11921218 .error_set,
11931219 .error_set_single,
11941220 .empty_struct,
1221 .@"enum",
1222 .@"struct",
1223 .@"union",
11951224 => false,
11961225
11971226 .const_slice,
......@@ -1264,6 +1293,9 @@ pub const Type = extern union {
12641293 .error_set,
12651294 .error_set_single,
12661295 .empty_struct,
1296 .@"enum",
1297 .@"struct",
1298 .@"union",
12671299 => false,
12681300
12691301 .single_const_pointer,
......@@ -1345,6 +1377,9 @@ pub const Type = extern union {
13451377 .error_set,
13461378 .error_set_single,
13471379 .empty_struct,
1380 .@"enum",
1381 .@"struct",
1382 .@"union",
13481383 => false,
13491384
13501385 .pointer => {
......@@ -1421,6 +1456,9 @@ pub const Type = extern union {
14211456 .error_set,
14221457 .error_set_single,
14231458 .empty_struct,
1459 .@"enum",
1460 .@"struct",
1461 .@"union",
14241462 => false,
14251463
14261464 .pointer => {
......@@ -1539,6 +1577,9 @@ pub const Type = extern union {
15391577 .error_set,
15401578 .error_set_single,
15411579 .empty_struct,
1580 .@"enum",
1581 .@"struct",
1582 .@"union",
15421583 => unreachable,
15431584
15441585 .array => self.cast(Payload.Array).?.elem_type,
......@@ -1667,6 +1708,9 @@ pub const Type = extern union {
16671708 .error_set,
16681709 .error_set_single,
16691710 .empty_struct,
1711 .@"enum",
1712 .@"struct",
1713 .@"union",
16701714 => unreachable,
16711715
16721716 .array => self.cast(Payload.Array).?.len,
......@@ -1733,6 +1777,9 @@ pub const Type = extern union {
17331777 .error_set,
17341778 .error_set_single,
17351779 .empty_struct,
1780 .@"enum",
1781 .@"struct",
1782 .@"union",
17361783 => unreachable,
17371784
17381785 .single_const_pointer,
......@@ -1816,6 +1863,9 @@ pub const Type = extern union {
18161863 .error_set,
18171864 .error_set_single,
18181865 .empty_struct,
1866 .@"enum",
1867 .@"struct",
1868 .@"union",
18191869 => false,
18201870
18211871 .int_signed,
......@@ -1891,6 +1941,9 @@ pub const Type = extern union {
18911941 .error_set,
18921942 .error_set_single,
18931943 .empty_struct,
1944 .@"enum",
1945 .@"struct",
1946 .@"union",
18941947 => false,
18951948
18961949 .int_unsigned,
......@@ -1956,6 +2009,9 @@ pub const Type = extern union {
19562009 .error_set,
19572010 .error_set_single,
19582011 .empty_struct,
2012 .@"enum",
2013 .@"struct",
2014 .@"union",
19592015 => unreachable,
19602016
19612017 .int_unsigned => .{ .signed = false, .bits = self.cast(Payload.IntUnsigned).?.bits },
......@@ -2039,6 +2095,9 @@ pub const Type = extern union {
20392095 .error_set,
20402096 .error_set_single,
20412097 .empty_struct,
2098 .@"enum",
2099 .@"struct",
2100 .@"union",
20422101 => false,
20432102
20442103 .usize,
......@@ -2151,6 +2210,9 @@ pub const Type = extern union {
21512210 .error_set,
21522211 .error_set_single,
21532212 .empty_struct,
2213 .@"enum",
2214 .@"struct",
2215 .@"union",
21542216 => unreachable,
21552217 };
21562218 }
......@@ -2229,6 +2291,9 @@ pub const Type = extern union {
22292291 .error_set,
22302292 .error_set_single,
22312293 .empty_struct,
2294 .@"enum",
2295 .@"struct",
2296 .@"union",
22322297 => unreachable,
22332298 }
22342299 }
......@@ -2306,6 +2371,9 @@ pub const Type = extern union {
23062371 .error_set,
23072372 .error_set_single,
23082373 .empty_struct,
2374 .@"enum",
2375 .@"struct",
2376 .@"union",
23092377 => unreachable,
23102378 }
23112379 }
......@@ -2383,6 +2451,9 @@ pub const Type = extern union {
23832451 .error_set,
23842452 .error_set_single,
23852453 .empty_struct,
2454 .@"enum",
2455 .@"struct",
2456 .@"union",
23862457 => unreachable,
23872458 };
23882459 }
......@@ -2457,6 +2528,9 @@ pub const Type = extern union {
24572528 .error_set,
24582529 .error_set_single,
24592530 .empty_struct,
2531 .@"enum",
2532 .@"struct",
2533 .@"union",
24602534 => unreachable,
24612535 };
24622536 }
......@@ -2531,6 +2605,9 @@ pub const Type = extern union {
25312605 .error_set,
25322606 .error_set_single,
25332607 .empty_struct,
2608 .@"enum",
2609 .@"struct",
2610 .@"union",
25342611 => unreachable,
25352612 };
25362613 }
......@@ -2605,6 +2682,9 @@ pub const Type = extern union {
26052682 .error_set,
26062683 .error_set_single,
26072684 .empty_struct,
2685 .@"enum",
2686 .@"struct",
2687 .@"union",
26082688 => false,
26092689 };
26102690 }
......@@ -2664,6 +2744,10 @@ pub const Type = extern union {
26642744 .error_set_single,
26652745 => return null,
26662746
2747 .@"enum" => @panic("TODO onePossibleValue enum"),
2748 .@"struct" => @panic("TODO onePossibleValue struct"),
2749 .@"union" => @panic("TODO onePossibleValue union"),
2750
26672751 .empty_struct => return Value.initTag(.empty_struct_value),
26682752 .void => return Value.initTag(.void_value),
26692753 .noreturn => return Value.initTag(.unreachable_value),
......@@ -2773,6 +2857,9 @@ pub const Type = extern union {
27732857 .error_set,
27742858 .error_set_single,
27752859 .empty_struct,
2860 .@"enum",
2861 .@"struct",
2862 .@"union",
27762863 => return false,
27772864
27782865 .c_const_pointer,
......@@ -2861,6 +2948,9 @@ pub const Type = extern union {
28612948 => unreachable,
28622949
28632950 .empty_struct => self.cast(Type.Payload.EmptyStruct).?.scope,
2951 .@"enum" => &self.cast(Type.Payload.Enum).?.scope,
2952 .@"struct" => &self.cast(Type.Payload.Struct).?.scope,
2953 .@"union" => &self.cast(Type.Payload.Union).?.scope,
28642954 };
28652955 }
28662956
......@@ -3012,6 +3102,9 @@ pub const Type = extern union {
30123102 error_set,
30133103 error_set_single,
30143104 empty_struct,
3105 @"enum",
3106 @"struct",
3107 @"union",
30153108
30163109 pub const last_no_payload_tag = Tag.const_slice_u8;
30173110 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
......@@ -3127,6 +3220,10 @@ pub const Type = extern union {
31273220
31283221 scope: *Module.Scope.Container,
31293222 };
3223
3224 pub const Enum = @import("value/Enum.zig");
3225 pub const Struct = @import("value/Struct.zig");
3226 pub const Union = @import("value/Union.zig");
31303227 };
31313228};
31323229
src/type/Enum.zig created+55
......@@ -0,0 +1,55 @@
1const std = @import("std");
2const Value = @import("../value.zig").Value;
3const Type = @import("../type.zig").Type;
4const Module = @import("../Module.zig");
5const Scope = Module.Scope;
6
7base: Type.Payload = .{ .tag = .@"enum" },
8
9analysis: union(enum) {
10 queued: Zir,
11 in_progress,
12 resolved: Size,
13 failed,
14},
15
16pub const Field = struct {
17 value: Value,
18};
19
20pub const Zir = struct {
21 body: zir.Module.Body,
22 inst: *zir.Inst,
23 arena: std.heap.ArenaAllocator.State,
24};
25
26pub const Size = struct {
27 is_zero_bits: bool,
28 alignment: u32,
29 size: u32,
30 fields: std.AutoArrayHashMap([]const u8, Field),
31};
32
33pub fn resolve(self: *Enum, mod: *Module, scope: *Scope) !void {
34 const zir = switch (self.analysis) {
35 .failed => return error.AnalysisFail,
36 .resolved => return,
37 .in_progress => {
38 return mod.fail(scope, src, "enum '{}' depends on itself", .{enum_name});
39 },
40 .queued => |zir| zir,
41 };
42 self.analysis = .in_progress;
43
44 // TODO
45}
46
47// TODO should this resolve the type or assert that it has already been resolved?
48pub fn abiAlignment(self: *Enum) u32 {
49 switch (self.analysis) {
50 .queued => unreachable, // alignment has not been resolved
51 .in_progress => unreachable, // alignment has not been resolved
52 .failed => unreachable, // type resolution failed
53 .resolved => |r| return r.tag_type.abiAlignment(),
54 }
55}
src/type/Struct.zig created+57
......@@ -0,0 +1,57 @@
1const std = @import("std");
2const Value = @import("../value.zig").Value;
3const Type = @import("../type.zig").Type;
4const Module = @import("../Module.zig");
5const Scope = Module.Scope;
6
7base: Type.Payload = .{ .tag = .@"struct" },
8
9analysis: union(enum) {
10 queued: Zir,
11 zero_bits_in_progress,
12 zero_bits: Zero,
13 in_progress,
14 alignment: Align,
15 resolved: Size,
16 failed,
17},
18scope: Scope.Container,
19
20pub const Field = struct {
21 value: Value,
22};
23
24pub const Zir = struct {
25 body: zir.Module.Body,
26 inst: *zir.Inst,
27 arena: std.heap.ArenaAllocator.State,
28};
29
30pub const Zero = struct {
31 is_zero_bits: bool,
32 fields: std.AutoArrayHashMap([]const u8, Field),
33};
34
35pub const Size = struct {
36 is_zero_bits: bool,
37 alignment: u32,
38 size: u32,
39 fields: std.AutoArrayHashMap([]const u8, Field),
40};
41
42pub fn resolveZeroBits(self: *Enum, mod: *Module, scope: *Scope) !void {
43 const zir = switch (self.analysis) {
44 .failed => return error.AnalysisFail,
45 .zero_bits_in_progress => {
46 return mod.fail(scope, src, "union '{}' depends on itself", .{});
47 },
48 .queued => |zir| zir,
49 else => return,
50 };
51
52 self.analysis = .zero_bits_in_progress;
53
54 // TODO
55}
56
57pub fn resolveSize(self: *Enum,)
\ No newline at end of file
src/type/Union.zig created+57
......@@ -0,0 +1,57 @@
1const std = @import("std");
2const Value = @import("../value.zig").Value;
3const Type = @import("../type.zig").Type;
4const Module = @import("../Module.zig");
5const Scope = Module.Scope;
6
7base: Type.Payload = .{ .tag = .@"struct" },
8
9analysis: union(enum) {
10 queued: Zir,
11 zero_bits_in_progress,
12 zero_bits: Zero,
13 in_progress,
14 alignment: Align,
15 resolved: Size,
16 failed,
17},
18scope: Scope.Container,
19
20pub const Field = struct {
21 value: Value,
22};
23
24pub const Zir = struct {
25 body: zir.Module.Body,
26 inst: *zir.Inst,
27 arena: std.heap.ArenaAllocator.State,
28};
29
30pub const Zero = struct {
31 is_zero_bits: bool,
32 fields: std.AutoArrayHashMap([]const u8, Field),
33};
34
35pub const Size = struct {
36 is_zero_bits: bool,
37 alignment: u32,
38 size: u32,
39 fields: std.AutoArrayHashMap([]const u8, Field),
40};
41
42pub fn resolveZeroBits(self: *Enum, mod: *Module, scope: *Scope) !void {
43 const zir = switch (self.analysis) {
44 .failed => return error.AnalysisFail,
45 .zero_bits_in_progress => {
46 return mod.fail(scope, src, "union '{}' depends on itself", .{});
47 },
48 .queued => |zir| zir,
49 else => return,
50 };
51
52 self.analysis = .zero_bits_in_progress;
53
54 // TODO
55}
56
57pub fn resolveSize(self: *Enum,)
\ No newline at end of file
src/value.zig+2-1
......@@ -252,7 +252,7 @@ pub const Value = extern union {
252252 .@"error" => return self.copyPayloadShallow(allocator, Payload.Error),
253253
254254 // memory is managed by the declaration
255 .error_set => return self.copyPayloadShallow(allocator, Payload.ErrorSet),
255 .error_set => return self,
256256 }
257257 }
258258
......@@ -1865,6 +1865,7 @@ pub const Value = extern union {
18651865 val: f128,
18661866 };
18671867
1868 // TODO move to type.zig
18681869 pub const ErrorSet = struct {
18691870 base: Payload = .{ .tag = .error_set },
18701871