mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
stage2: outline container types
This commit is contained in:
parent
643f526cd1
commit
f173d078c7
@ -428,7 +428,7 @@ pub const Scope = struct {
|
||||
};
|
||||
}
|
||||
|
||||
/// Asserts the scope has a parent which is a ZIRModule, Contaienr or File and
|
||||
/// Asserts the scope has a parent which is a ZIRModule, Container or File and
|
||||
/// returns the sub_file_path field.
|
||||
pub fn subFilePath(base: *Scope) []const u8 {
|
||||
switch (base.tag) {
|
||||
@ -1515,6 +1515,7 @@ pub fn analyzeContainer(self: *Module, container_scope: *Scope.Container) !void
|
||||
// an incremental update. This code handles both cases.
|
||||
const tree = try self.getAstTree(container_scope);
|
||||
const decls = tree.root_node.decls();
|
||||
// const decls = container_scope.root_node.decls();
|
||||
|
||||
try self.comp.work_queue.ensureUnusedCapacity(decls.len);
|
||||
try container_scope.decls.ensureCapacity(self.gpa, decls.len);
|
||||
@ -2272,6 +2273,33 @@ pub fn createAnonymousDecl(
|
||||
return new_decl;
|
||||
}
|
||||
|
||||
fn createContainerDecl(self: *Module, scope: *Scope, container_node: *std.zig.ast.Node.ContainerDecl) !*Decl {
|
||||
const name = try self.getAnonTypeName(scope, container_node.kind_token);
|
||||
defer self.gpa.free(name);
|
||||
const name_hash = scope.namespace().fullyQualifiedNameHash(name);
|
||||
const src_hash: std.zig.SrcHash = undefined;
|
||||
const new_decl = try self.createNewDecl(scope, name, scope_decl.src_index, name_hash, src_hash);
|
||||
const decl_arena_state = try decl_arena.allocator.create(std.heap.ArenaAllocator.State);
|
||||
|
||||
decl_arena_state.* = decl_arena.state;
|
||||
new_decl.generation = self.generation;
|
||||
|
||||
return new_decl;
|
||||
}
|
||||
|
||||
fn getAnonTypeName(self: *Module, scope: *Scope, base_token: std.zig.ast.TokenIndex) ![]u8 {
|
||||
const container = scope.getContainer();
|
||||
const tree = self.getAstTree(container);
|
||||
const base_name = switch (tree.token_ids[base_token]) {
|
||||
.Keyword_struct => "struct",
|
||||
.Keyword_enum => "enum",
|
||||
.Keyword_union => "union",
|
||||
else => unreachable,
|
||||
};
|
||||
const loc = tree.tokenLocationLoc(0, tree.token_locs[base_token]);
|
||||
return std.fmt.allocPrint(self.gpa, "{}:{}:{}", .{ base_name, loc.line, loc.column });
|
||||
}
|
||||
|
||||
fn getNextAnonNameIndex(self: *Module) usize {
|
||||
return @atomicRmw(usize, &self.next_anon_name_index, .Add, 1, .Monotonic);
|
||||
}
|
||||
|
||||
99
src/type.zig
99
src/type.zig
@ -90,7 +90,9 @@ pub const Type = extern union {
|
||||
|
||||
.anyframe_T, .@"anyframe" => return .AnyFrame,
|
||||
|
||||
.empty_struct => return .Struct,
|
||||
.@"struct", .empty_struct => return .Struct,
|
||||
.@"enum" => return .Enum,
|
||||
.@"union" => return .Union,
|
||||
}
|
||||
}
|
||||
|
||||
@ -442,6 +444,11 @@ pub const Type = extern union {
|
||||
.error_set => return self.copyPayloadShallow(allocator, Payload.ErrorSet),
|
||||
.error_set_single => return self.copyPayloadShallow(allocator, Payload.ErrorSetSingle),
|
||||
.empty_struct => return self.copyPayloadShallow(allocator, Payload.EmptyStruct),
|
||||
|
||||
// memory managed by the decl
|
||||
.@"enum" => return self,
|
||||
.@"struct" => return self,
|
||||
.@"union" => return self,
|
||||
}
|
||||
}
|
||||
|
||||
@ -673,6 +680,10 @@ pub const Type = extern union {
|
||||
const payload = @fieldParentPtr(Payload.ErrorSetSingle, "base", ty.ptr_otherwise);
|
||||
return out_stream.print("error{{{}}}", .{payload.name});
|
||||
},
|
||||
// TODO improve
|
||||
.@"enum" => return out_stream.writeAll("enum {}"),
|
||||
.@"struct" => return out_stream.writeAll("struct {}"),
|
||||
.@"union" => return out_stream.writeAll("union {}"),
|
||||
}
|
||||
unreachable;
|
||||
}
|
||||
@ -784,6 +795,10 @@ pub const Type = extern union {
|
||||
return payload.error_set.hasCodeGenBits() or payload.payload.hasCodeGenBits();
|
||||
},
|
||||
|
||||
.@"enum" => @panic("TODO"),
|
||||
.@"struct" => @panic("TODO"),
|
||||
.@"union" => @panic("TODO"),
|
||||
|
||||
.c_void,
|
||||
.void,
|
||||
.type,
|
||||
@ -908,6 +923,10 @@ pub const Type = extern union {
|
||||
@panic("TODO abiAlignment error union");
|
||||
},
|
||||
|
||||
.@"enum" => self.cast(Payload.Enum).?.abiAlignment(),
|
||||
.@"struct" => @panic("TODO"),
|
||||
.@"union" => @panic("TODO"),
|
||||
|
||||
.c_void,
|
||||
.void,
|
||||
.type,
|
||||
@ -1050,6 +1069,10 @@ pub const Type = extern union {
|
||||
}
|
||||
@panic("TODO abiSize error union");
|
||||
},
|
||||
|
||||
.@"enum" => @panic("TODO"),
|
||||
.@"struct" => @panic("TODO"),
|
||||
.@"union" => @panic("TODO"),
|
||||
};
|
||||
}
|
||||
|
||||
@ -1117,6 +1140,9 @@ pub const Type = extern union {
|
||||
.error_set,
|
||||
.error_set_single,
|
||||
.empty_struct,
|
||||
.@"enum",
|
||||
.@"struct",
|
||||
.@"union",
|
||||
=> false,
|
||||
|
||||
.single_const_pointer,
|
||||
@ -1192,6 +1218,9 @@ pub const Type = extern union {
|
||||
.error_set,
|
||||
.error_set_single,
|
||||
.empty_struct,
|
||||
.@"enum",
|
||||
.@"struct",
|
||||
.@"union",
|
||||
=> false,
|
||||
|
||||
.const_slice,
|
||||
@ -1264,6 +1293,9 @@ pub const Type = extern union {
|
||||
.error_set,
|
||||
.error_set_single,
|
||||
.empty_struct,
|
||||
.@"enum",
|
||||
.@"struct",
|
||||
.@"union",
|
||||
=> false,
|
||||
|
||||
.single_const_pointer,
|
||||
@ -1345,6 +1377,9 @@ pub const Type = extern union {
|
||||
.error_set,
|
||||
.error_set_single,
|
||||
.empty_struct,
|
||||
.@"enum",
|
||||
.@"struct",
|
||||
.@"union",
|
||||
=> false,
|
||||
|
||||
.pointer => {
|
||||
@ -1421,6 +1456,9 @@ pub const Type = extern union {
|
||||
.error_set,
|
||||
.error_set_single,
|
||||
.empty_struct,
|
||||
.@"enum",
|
||||
.@"struct",
|
||||
.@"union",
|
||||
=> false,
|
||||
|
||||
.pointer => {
|
||||
@ -1539,6 +1577,9 @@ pub const Type = extern union {
|
||||
.error_set,
|
||||
.error_set_single,
|
||||
.empty_struct,
|
||||
.@"enum",
|
||||
.@"struct",
|
||||
.@"union",
|
||||
=> unreachable,
|
||||
|
||||
.array => self.cast(Payload.Array).?.elem_type,
|
||||
@ -1667,6 +1708,9 @@ pub const Type = extern union {
|
||||
.error_set,
|
||||
.error_set_single,
|
||||
.empty_struct,
|
||||
.@"enum",
|
||||
.@"struct",
|
||||
.@"union",
|
||||
=> unreachable,
|
||||
|
||||
.array => self.cast(Payload.Array).?.len,
|
||||
@ -1733,6 +1777,9 @@ pub const Type = extern union {
|
||||
.error_set,
|
||||
.error_set_single,
|
||||
.empty_struct,
|
||||
.@"enum",
|
||||
.@"struct",
|
||||
.@"union",
|
||||
=> unreachable,
|
||||
|
||||
.single_const_pointer,
|
||||
@ -1816,6 +1863,9 @@ pub const Type = extern union {
|
||||
.error_set,
|
||||
.error_set_single,
|
||||
.empty_struct,
|
||||
.@"enum",
|
||||
.@"struct",
|
||||
.@"union",
|
||||
=> false,
|
||||
|
||||
.int_signed,
|
||||
@ -1891,6 +1941,9 @@ pub const Type = extern union {
|
||||
.error_set,
|
||||
.error_set_single,
|
||||
.empty_struct,
|
||||
.@"enum",
|
||||
.@"struct",
|
||||
.@"union",
|
||||
=> false,
|
||||
|
||||
.int_unsigned,
|
||||
@ -1956,6 +2009,9 @@ pub const Type = extern union {
|
||||
.error_set,
|
||||
.error_set_single,
|
||||
.empty_struct,
|
||||
.@"enum",
|
||||
.@"struct",
|
||||
.@"union",
|
||||
=> unreachable,
|
||||
|
||||
.int_unsigned => .{ .signed = false, .bits = self.cast(Payload.IntUnsigned).?.bits },
|
||||
@ -2039,6 +2095,9 @@ pub const Type = extern union {
|
||||
.error_set,
|
||||
.error_set_single,
|
||||
.empty_struct,
|
||||
.@"enum",
|
||||
.@"struct",
|
||||
.@"union",
|
||||
=> false,
|
||||
|
||||
.usize,
|
||||
@ -2151,6 +2210,9 @@ pub const Type = extern union {
|
||||
.error_set,
|
||||
.error_set_single,
|
||||
.empty_struct,
|
||||
.@"enum",
|
||||
.@"struct",
|
||||
.@"union",
|
||||
=> unreachable,
|
||||
};
|
||||
}
|
||||
@ -2229,6 +2291,9 @@ pub const Type = extern union {
|
||||
.error_set,
|
||||
.error_set_single,
|
||||
.empty_struct,
|
||||
.@"enum",
|
||||
.@"struct",
|
||||
.@"union",
|
||||
=> unreachable,
|
||||
}
|
||||
}
|
||||
@ -2306,6 +2371,9 @@ pub const Type = extern union {
|
||||
.error_set,
|
||||
.error_set_single,
|
||||
.empty_struct,
|
||||
.@"enum",
|
||||
.@"struct",
|
||||
.@"union",
|
||||
=> unreachable,
|
||||
}
|
||||
}
|
||||
@ -2383,6 +2451,9 @@ pub const Type = extern union {
|
||||
.error_set,
|
||||
.error_set_single,
|
||||
.empty_struct,
|
||||
.@"enum",
|
||||
.@"struct",
|
||||
.@"union",
|
||||
=> unreachable,
|
||||
};
|
||||
}
|
||||
@ -2457,6 +2528,9 @@ pub const Type = extern union {
|
||||
.error_set,
|
||||
.error_set_single,
|
||||
.empty_struct,
|
||||
.@"enum",
|
||||
.@"struct",
|
||||
.@"union",
|
||||
=> unreachable,
|
||||
};
|
||||
}
|
||||
@ -2531,6 +2605,9 @@ pub const Type = extern union {
|
||||
.error_set,
|
||||
.error_set_single,
|
||||
.empty_struct,
|
||||
.@"enum",
|
||||
.@"struct",
|
||||
.@"union",
|
||||
=> unreachable,
|
||||
};
|
||||
}
|
||||
@ -2605,6 +2682,9 @@ pub const Type = extern union {
|
||||
.error_set,
|
||||
.error_set_single,
|
||||
.empty_struct,
|
||||
.@"enum",
|
||||
.@"struct",
|
||||
.@"union",
|
||||
=> false,
|
||||
};
|
||||
}
|
||||
@ -2664,6 +2744,10 @@ pub const Type = extern union {
|
||||
.error_set_single,
|
||||
=> return null,
|
||||
|
||||
.@"enum" => @panic("TODO onePossibleValue enum"),
|
||||
.@"struct" => @panic("TODO onePossibleValue struct"),
|
||||
.@"union" => @panic("TODO onePossibleValue union"),
|
||||
|
||||
.empty_struct => return Value.initTag(.empty_struct_value),
|
||||
.void => return Value.initTag(.void_value),
|
||||
.noreturn => return Value.initTag(.unreachable_value),
|
||||
@ -2773,6 +2857,9 @@ pub const Type = extern union {
|
||||
.error_set,
|
||||
.error_set_single,
|
||||
.empty_struct,
|
||||
.@"enum",
|
||||
.@"struct",
|
||||
.@"union",
|
||||
=> return false,
|
||||
|
||||
.c_const_pointer,
|
||||
@ -2861,6 +2948,9 @@ pub const Type = extern union {
|
||||
=> unreachable,
|
||||
|
||||
.empty_struct => self.cast(Type.Payload.EmptyStruct).?.scope,
|
||||
.@"enum" => &self.cast(Type.Payload.Enum).?.scope,
|
||||
.@"struct" => &self.cast(Type.Payload.Struct).?.scope,
|
||||
.@"union" => &self.cast(Type.Payload.Union).?.scope,
|
||||
};
|
||||
}
|
||||
|
||||
@ -3012,6 +3102,9 @@ pub const Type = extern union {
|
||||
error_set,
|
||||
error_set_single,
|
||||
empty_struct,
|
||||
@"enum",
|
||||
@"struct",
|
||||
@"union",
|
||||
|
||||
pub const last_no_payload_tag = Tag.const_slice_u8;
|
||||
pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
|
||||
@ -3127,6 +3220,10 @@ pub const Type = extern union {
|
||||
|
||||
scope: *Module.Scope.Container,
|
||||
};
|
||||
|
||||
pub const Enum = @import("value/Enum.zig");
|
||||
pub const Struct = @import("value/Struct.zig");
|
||||
pub const Union = @import("value/Union.zig");
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
55
src/type/Enum.zig
Normal file
55
src/type/Enum.zig
Normal file
@ -0,0 +1,55 @@
|
||||
const std = @import("std");
|
||||
const Value = @import("../value.zig").Value;
|
||||
const Type = @import("../type.zig").Type;
|
||||
const Module = @import("../Module.zig");
|
||||
const Scope = Module.Scope;
|
||||
|
||||
base: Type.Payload = .{ .tag = .@"enum" },
|
||||
|
||||
analysis: union(enum) {
|
||||
queued: Zir,
|
||||
in_progress,
|
||||
resolved: Size,
|
||||
failed,
|
||||
},
|
||||
|
||||
pub const Field = struct {
|
||||
value: Value,
|
||||
};
|
||||
|
||||
pub const Zir = struct {
|
||||
body: zir.Module.Body,
|
||||
inst: *zir.Inst,
|
||||
arena: std.heap.ArenaAllocator.State,
|
||||
};
|
||||
|
||||
pub const Size = struct {
|
||||
is_zero_bits: bool,
|
||||
alignment: u32,
|
||||
size: u32,
|
||||
fields: std.AutoArrayHashMap([]const u8, Field),
|
||||
};
|
||||
|
||||
pub fn resolve(self: *Enum, mod: *Module, scope: *Scope) !void {
|
||||
const zir = switch (self.analysis) {
|
||||
.failed => return error.AnalysisFail,
|
||||
.resolved => return,
|
||||
.in_progress => {
|
||||
return mod.fail(scope, src, "enum '{}' depends on itself", .{enum_name});
|
||||
},
|
||||
.queued => |zir| zir,
|
||||
};
|
||||
self.analysis = .in_progress;
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
// TODO should this resolve the type or assert that it has already been resolved?
|
||||
pub fn abiAlignment(self: *Enum) u32 {
|
||||
switch (self.analysis) {
|
||||
.queued => unreachable, // alignment has not been resolved
|
||||
.in_progress => unreachable, // alignment has not been resolved
|
||||
.failed => unreachable, // type resolution failed
|
||||
.resolved => |r| return r.tag_type.abiAlignment(),
|
||||
}
|
||||
}
|
||||
57
src/type/Struct.zig
Normal file
57
src/type/Struct.zig
Normal file
@ -0,0 +1,57 @@
|
||||
const std = @import("std");
|
||||
const Value = @import("../value.zig").Value;
|
||||
const Type = @import("../type.zig").Type;
|
||||
const Module = @import("../Module.zig");
|
||||
const Scope = Module.Scope;
|
||||
|
||||
base: Type.Payload = .{ .tag = .@"struct" },
|
||||
|
||||
analysis: union(enum) {
|
||||
queued: Zir,
|
||||
zero_bits_in_progress,
|
||||
zero_bits: Zero,
|
||||
in_progress,
|
||||
alignment: Align,
|
||||
resolved: Size,
|
||||
failed,
|
||||
},
|
||||
scope: Scope.Container,
|
||||
|
||||
pub const Field = struct {
|
||||
value: Value,
|
||||
};
|
||||
|
||||
pub const Zir = struct {
|
||||
body: zir.Module.Body,
|
||||
inst: *zir.Inst,
|
||||
arena: std.heap.ArenaAllocator.State,
|
||||
};
|
||||
|
||||
pub const Zero = struct {
|
||||
is_zero_bits: bool,
|
||||
fields: std.AutoArrayHashMap([]const u8, Field),
|
||||
};
|
||||
|
||||
pub const Size = struct {
|
||||
is_zero_bits: bool,
|
||||
alignment: u32,
|
||||
size: u32,
|
||||
fields: std.AutoArrayHashMap([]const u8, Field),
|
||||
};
|
||||
|
||||
pub fn resolveZeroBits(self: *Enum, mod: *Module, scope: *Scope) !void {
|
||||
const zir = switch (self.analysis) {
|
||||
.failed => return error.AnalysisFail,
|
||||
.zero_bits_in_progress => {
|
||||
return mod.fail(scope, src, "union '{}' depends on itself", .{});
|
||||
},
|
||||
.queued => |zir| zir,
|
||||
else => return,
|
||||
};
|
||||
|
||||
self.analysis = .zero_bits_in_progress;
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
pub fn resolveSize(self: *Enum,)
|
||||
57
src/type/Union.zig
Normal file
57
src/type/Union.zig
Normal file
@ -0,0 +1,57 @@
|
||||
const std = @import("std");
|
||||
const Value = @import("../value.zig").Value;
|
||||
const Type = @import("../type.zig").Type;
|
||||
const Module = @import("../Module.zig");
|
||||
const Scope = Module.Scope;
|
||||
|
||||
base: Type.Payload = .{ .tag = .@"struct" },
|
||||
|
||||
analysis: union(enum) {
|
||||
queued: Zir,
|
||||
zero_bits_in_progress,
|
||||
zero_bits: Zero,
|
||||
in_progress,
|
||||
alignment: Align,
|
||||
resolved: Size,
|
||||
failed,
|
||||
},
|
||||
scope: Scope.Container,
|
||||
|
||||
pub const Field = struct {
|
||||
value: Value,
|
||||
};
|
||||
|
||||
pub const Zir = struct {
|
||||
body: zir.Module.Body,
|
||||
inst: *zir.Inst,
|
||||
arena: std.heap.ArenaAllocator.State,
|
||||
};
|
||||
|
||||
pub const Zero = struct {
|
||||
is_zero_bits: bool,
|
||||
fields: std.AutoArrayHashMap([]const u8, Field),
|
||||
};
|
||||
|
||||
pub const Size = struct {
|
||||
is_zero_bits: bool,
|
||||
alignment: u32,
|
||||
size: u32,
|
||||
fields: std.AutoArrayHashMap([]const u8, Field),
|
||||
};
|
||||
|
||||
pub fn resolveZeroBits(self: *Enum, mod: *Module, scope: *Scope) !void {
|
||||
const zir = switch (self.analysis) {
|
||||
.failed => return error.AnalysisFail,
|
||||
.zero_bits_in_progress => {
|
||||
return mod.fail(scope, src, "union '{}' depends on itself", .{});
|
||||
},
|
||||
.queued => |zir| zir,
|
||||
else => return,
|
||||
};
|
||||
|
||||
self.analysis = .zero_bits_in_progress;
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
pub fn resolveSize(self: *Enum,)
|
||||
@ -252,7 +252,7 @@ pub const Value = extern union {
|
||||
.@"error" => return self.copyPayloadShallow(allocator, Payload.Error),
|
||||
|
||||
// memory is managed by the declaration
|
||||
.error_set => return self.copyPayloadShallow(allocator, Payload.ErrorSet),
|
||||
.error_set => return self,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1865,6 +1865,7 @@ pub const Value = extern union {
|
||||
val: f128,
|
||||
};
|
||||
|
||||
// TODO move to type.zig
|
||||
pub const ErrorSet = struct {
|
||||
base: Payload = .{ .tag = .error_set },
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user